Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: add find-dom-node-polyfill and update integration documentation
- Added `find-dom-node-polyfill` to enhance compatibility with React's `findDOMNode`.
- Updated integration documentation to include Python examples and improved clarity on API key usage.
- Adjusted various code snippets for consistency and readability across multiple programming languages.
  • Loading branch information
jimmyn committed Apr 16, 2025
commit e1bc426f6deb20d9bd0e93683a1a0f64eaefa5ef
200 changes: 150 additions & 50 deletions docs/subscriptions/integration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ values={[
{label: 'cURL', value: 'curl'},
{label: 'Node.js', value: 'node'},
{label: 'PHP', value: 'php'},
{label: 'Python', value: 'python'}
]}>
<TabItem value="curl">

```shell script title="POST https://api.monei.com/v1/subscriptions"
curl --request POST 'https://api.monei.com/v1/subscriptions' \
--header 'Authorization: pk_test_3c140607778e1217f56ccb8b50540e00' \
--header 'Content-Type: application/json' \
curl --request POST 'https://api.monei.com/v1/subscriptions' \\
--header 'Authorization: YOUR_API_KEY' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"customer": {
"name": "John Doe",
Expand All @@ -43,46 +44,97 @@ curl --request POST 'https://api.monei.com/v1/subscriptions' \
}'
```

(Replace `YOUR_API_KEY` with your actual MONEI API key)

</TabItem>

<TabItem value="node">

```js title="server.js"
const {Monei} = require('@monei-js/node-sdk');
const monei = new Monei('pk_test_36cf3e8a15eff3f5be983562ea6b13ec');
monei.subscriptions.create({
// Replace YOUR_API_KEY with your actual MONEI API key
const monei = new Monei('YOUR_API_KEY');
const subscription = await monei.subscriptions.create({
customer: {
name: "John Doe"
email: "[email protected]"
name: 'John Doe',
email: '[email protected]'
},
amount: 110,
currency: "EUR",
interval: "month",
currency: 'EUR',
interval: 'month',
intervalCount: 1,
description: "MoonMail Lite Monthly",
callbackUrl: "https://example.com/subscription/callback",
paymentCallbackUrl: "https://example.com/payment/callback"
description: 'MoonMail Lite Monthly',
callbackUrl: 'https://example.com/subscription/callback',
paymentCallbackUrl: 'https://example.com/payment/callback'
});

// You will need the subscription id from the response in the next step
const subscriptionId = subscription.id;
```

</TabItem>
<TabItem value="php">

```php title="server.php"
$monei = new Monei\MoneiClient('pk_test_36cf3e8a15eff3f5be983562ea6b13ec');
$monei->subscriptions->create([
'customer'=> [
'name'=> 'John Doe',
'email'=> '[email protected]'
],
'amount'=> 110,
'currency'=> 'EUR',
'interval_count'=> 'month',
'interval_count'=> 1,
'description'=> 'MoonMail Lite Monthly',
'callback_url'=> 'https://example.com/subscription/callback',
'payment_callback_url'=> 'https://example.com/payment/callback'
]);
<?php
require_once 'vendor/autoload.php';

use Monei\\MoneiClient;
use Monei\\Model\\CreateSubscriptionRequest;
use Monei\\Model\\PaymentCustomer;

// Replace YOUR_API_KEY with your actual MONEI API key
$monei = new MoneiClient('YOUR_API_KEY');
$subscription = $monei->subscriptions->create(
new CreateSubscriptionRequest([
'customer' => new PaymentCustomer([
'name' => 'John Doe',
'email' => '[email protected]'
]),
'amount' => 110,
'currency' => 'EUR',
'interval' => 'month',
'interval_count' => 1,
'description' => 'MoonMail Lite Monthly',
'callback_url' => 'https://example.com/subscription/callback',
'payment_callback_url' => 'https://example.com/payment/callback'
])
);

// You will need the subscription id from the response in the next step
$subscriptionId = $subscription->getId();
?>
```

</TabItem>
<TabItem value="python">

```python title="server.py"
import Monei
from Monei import CreateSubscriptionRequest, PaymentCustomer

# Replace YOUR_API_KEY with your actual MONEI API key
monei = Monei.MoneiClient(api_key="YOUR_API_KEY")

subscription = monei.subscriptions.create(
CreateSubscriptionRequest(
customer=PaymentCustomer(
name="John Doe",
email="[email protected]"
),
amount=110,
currency="EUR",
interval="month",
interval_count=1,
description="MoonMail Lite Monthly",
callback_url="https://example.com/subscription/callback",
payment_callback_url="https://example.com/payment/callback"
)
)

# You will need the subscription id from the response in the next step
subscription_id = subscription.id

```

</TabItem>
Expand All @@ -92,10 +144,10 @@ The following parameters are required:

- **amount** `positive integer` - Amount intended to be collected by this payment. A positive integer representing how much to charge in the smallest currency unit (e.g., 100 cents to charge 1.00 USD)
- **currency** `string` - Three-letter [ISO currency code](https://en.wikipedia.org/wiki/ISO_4217), in uppercase. Must be a supported currency.
- **callbackUrl** `string` - The URL will be called each time subscription status changes.
- **paymentCallbackUrl** `string` - The URL will be called each time subscription creates a new subscriptions.
- **interval** `string` - Subscription interval, one of `day`, `week`, `month`, `year`
- **intervalCount** `number` - Number of intervals between subscription subscriptions.
- **callbackUrl** `string` - The URL will be called each time subscription status changes.
- **paymentCallbackUrl** `string` - The URL will be called each time subscription creates a new payment.
- **intervalCount** `number` - Number of intervals between subscription payments.

Check all available [request parameters](/apis/rest/subscriptions-create/).

Expand All @@ -107,43 +159,89 @@ Check all available [request parameters](/apis/rest/subscriptions-create/).
values={[
{label: 'cURL', value: 'curl'},
{label: 'Node.js', value: 'node'},
{label: 'PHP', value: 'php'}
{label: 'PHP', value: 'php'},
{label: 'Python', value: 'python'}
]}>
<TabItem value="curl">

```shell script title="POST https://api.monei.com/v1/subscriptions/575bcd84-09fc-4a6e-8c4c-f88b8eb90bfa/activate"
curl --request POST 'https://api.monei.com/v1/subscriptions/575bcd84-09fc-4a6e-8c4c-f88b8eb90bfa/activate' \
--header 'Authorization: pk_test_3c140607778e1217f56ccb8b50540e00' \
--header 'Content-Type: application/json' \
```shell script title="POST https://api.monei.com/v1/subscriptions/{subscription_id}/activate"
curl --request POST 'https://api.monei.com/v1/subscriptions/YOUR_SUBSCRIPTION_ID/activate' \\
--header 'Authorization: YOUR_API_KEY' \\
--header 'Content-Type: application/json' \\
--data-raw '{
"completeUrl": "https://example.com/checkout/complete",
"cancelUrl": "https://example.com/checkout/cancel"
}'
```

(Replace `YOUR_SUBSCRIPTION_ID` and `YOUR_API_KEY`)

</TabItem>

<TabItem value="node">

```js title="server.js"
const {Monei} = require('@monei-js/node-sdk');
const monei = new Monei('pk_test_36cf3e8a15eff3f5be983562ea6b13ec');
monei.subscriptions.activate('575bcd84-09fc-4a6e-8c4c-f88b8eb90bfa', {
// Replace YOUR_API_KEY with your actual MONEI API key
const monei = new Monei('YOUR_API_KEY');
// Replace YOUR_SUBSCRIPTION_ID with the ID from the previous step
const activation = await monei.subscriptions.activate('YOUR_SUBSCRIPTION_ID', {
completeUrl: 'https://example.com/checkout/complete',
cancelUrl: 'https://example.com/checkout/cancel'
});

// You will need the redirectUrl from the response in the next step
const redirectUrl = activation.nextAction.redirectUrl;
```

</TabItem>
<TabItem value="php">

```php title="server.php"
$monei = new Monei\MoneiClient('pk_test_36cf3e8a15eff3f5be983562ea6b13ec');
$monei->subscriptions->activate(
'575bcd84-09fc-4a6e-8c4c-f88b8eb90bfa', [
'complete_url' => 'https://example.com/checkout/complete',
'cancel_url' => 'https://example.com/checkout/cancel'
]);
<?php
require_once 'vendor/autoload.php';

use Monei\\MoneiClient;
use Monei\\Model\\ActivateSubscriptionRequest;

// Replace YOUR_API_KEY with your actual MONEI API key
$monei = new MoneiClient('YOUR_API_KEY');
// Replace YOUR_SUBSCRIPTION_ID with the ID from the previous step
$activation = $monei->subscriptions->activate(
'YOUR_SUBSCRIPTION_ID',
new ActivateSubscriptionRequest([
'complete_url' => 'https://example.com/checkout/complete',
'cancel_url' => 'https://example.com/checkout/cancel'
])
);

// You will need the redirectUrl from the response in the next step
$redirectUrl = $activation->getNextAction()->getRedirectUrl();
?>
```

</TabItem>
<TabItem value="python">

```python title="server.py"
import Monei
from Monei import ActivateSubscriptionRequest

# Replace YOUR_API_KEY with your actual MONEI API key
monei = Monei.MoneiClient(api_key="YOUR_API_KEY")

# Replace YOUR_SUBSCRIPTION_ID with the ID from the previous step
activation = monei.subscriptions.activate(
subscription_id="YOUR_SUBSCRIPTION_ID",
request=ActivateSubscriptionRequest(
complete_url="https://example.com/checkout/complete",
cancel_url="https://example.com/checkout/cancel"
)
)

# You will need the redirectUrl from the response in the next step
redirect_url = activation.next_action.redirect_url

```

</TabItem>
Expand All @@ -157,7 +255,7 @@ In the response from the [activate subscription](/apis/rest/subscriptions-activa

```json
{
"id": "af6029f80f5fc73a8ad2753eea0b1be0",
"id": "af6029f80f5fc73a8ad2753eea0b1be0", // Payment ID
"amount": 110,
"currency": "EUR",
"orderId": "84370745531439",
Expand All @@ -172,14 +270,14 @@ In the response from the [activate subscription](/apis/rest/subscriptions-activa
},
"nextAction": {
"type": "CONFIRM",
"mustRedirect": false,
"redirectUrl": "https://secure.monei.com/payments/af6029f80f5fc73a8ad2753eea0b1be0"
"mustRedirect": true, // Indicates redirection is needed
"redirectUrl": "https://secure.monei.com/payments/af6029f80f5fc73a8ad2753eea0b1be0" // <-- REDIRECT CUSTOMER HERE
},
"createdAt": 1594215339
}
```

Redirect the customer to the `nextAction.redirectUrl` to show him the MONEI Hosted payment page.
Redirect the customer to the `nextAction.redirectUrl` to show him the MONEI Hosted payment page. The response object here is actually a [Payment object](/apis/rest/schemas/payment/) associated with the _initial activation_ of the subscription.

:::note
As an alternative process you can confirm the payment by using monei.js on the client-side. Check our [build a custom checkout guide](/integrations/build-custom-checkout.mdx).
Expand All @@ -192,15 +290,17 @@ Customer enters the Card information and goes through the 3D secure verification
### 5. Customer is redirected back to your server

- if customer clicks **"Back to \{\{shop.name}}"** link (you can provide `shop.name` in the [public business details settings](https://dashboard.monei.com/settings)), s/he is redirected to `cancelUrl`. (Usually this url is the checkout page on your website, where the user had started a checkout process)
- in any other case the customer is redirected to the `completeUrl` with **payment_id** and **subscription_id** query parameters. Use [get subscription](/apis/rest/subscriptions-get/) endpoint to get the subscription status.
- in any other case the customer is redirected to the `completeUrl` with **payment_id** and **subscription_id** query parameters. Use [get payment](/apis/rest/payments-get/) endpoint to check the initial payment status, and [get subscription](/apis/rest/subscriptions-get/) endpoint to get the subscription status (it should move to `ACTIVE` or `TRIALING` if successful).

### 6. An asynchronous request is sent to your server

MONEI will notify you about the payment status by sending an HTTP POST request to the `callbackUrl`. The request body will contain the full [subscription object](/apis/rest/schemas/subscription/) in JSON format.
MONEI will notify you about the _initial payment_ status by sending an HTTP POST request to the `callbackUrl` defined in the **create payment** step (this is the `paymentCallbackUrl` from the _create subscription_ request). The request body will contain the full [Payment object](/apis/rest/schemas/payment/).

Additionally, MONEI will notify you about the _subscription status changes_ (e.g., from `PENDING` to `ACTIVE`) by sending an HTTP POST request to the `callbackUrl` defined in the **create subscription** request. The request body will contain the full [Subscription object](/apis/rest/schemas/subscription/).

This ensures that you get the payment status even when the customer closed the browser window or lost Internet connection.
This ensures that you get the status updates even when the customer closes the browser window or loses Internet connection.

The request also contains a `MONEI-Signature` header. [Verify this signature](guides/verify-signature.mdx) to confirm that the received request is sent from MONEI.
The request also contains a `MONEI-Signature` header. [Verify this signature](/guides/verify-signature.mdx) to confirm that the received request is sent from MONEI.

To acknowledge the receipt of the request, your endpoint must return a `200` HTTP status code to MONEI. All other response codes, including `3xx` codes, indicate to MONEI that you did not receive the event.

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"clsx": "^2.1.1",
"docusaurus-plugin-openapi-docs": "4.3.7",
"docusaurus-theme-openapi-docs": "4.3.7",
"find-dom-node-polyfill": "^1.0.3",
"graphql": "^16.10.0",
"marked": "^15.0.8",
"prism-react-renderer": "^2.4.1",
Expand Down
8 changes: 7 additions & 1 deletion src/components/Bizum.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import {Bizum as MoneiBizum} from '@monei-js/components';
import React from 'react';
import ReactDOM from 'react-dom';
import {Bizum as MoneiBizum} from '@monei-js/components';

// Import findDOMNode from external library
import {findDOMNode} from 'find-dom-node-polyfill';

// Set Find DOM Node before driver
ReactDOM.findDOMNode = findDOMNode;

const BizumComponent = MoneiBizum.driver('react', {
React: React,
Expand Down
Binary file modified static/img/click-to-pay-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7865,6 +7865,16 @@ __metadata:
languageName: node
linkType: hard

"find-dom-node-polyfill@npm:^1.0.3":
version: 1.0.3
resolution: "find-dom-node-polyfill@npm:1.0.3"
peerDependencies:
react: "*"
react-dom: "*"
checksum: 10c0/38d19d01a68c7a4c79f0fe93a7ac21abf5258304f20407ab4c127b6e56424fc94d52263c649c917b087c0b669e19dee01cea3c4efbf9704a0f3185e89ff24d9a
languageName: node
linkType: hard

"find-up@npm:^3.0.0":
version: 3.0.0
resolution: "find-up@npm:3.0.0"
Expand Down Expand Up @@ -11727,6 +11737,7 @@ __metadata:
clsx: "npm:^2.1.1"
docusaurus-plugin-openapi-docs: "npm:4.3.7"
docusaurus-theme-openapi-docs: "npm:4.3.7"
find-dom-node-polyfill: "npm:^1.0.3"
graphql: "npm:^16.10.0"
husky: "npm:^9.1.7"
lint-staged: "npm:^15.5.1"
Expand Down