Payment links

Create a custom payment link to share with your customers and receive online payment.

Overview

The payment process can also be started through a payment link sent to the customer. This link can be customized and shared as many times as you want on any channel you prefer.

Requirements

Partner requirements

Before integrating payment links, Monite partners must provide their logo to be displayed in the “Powered by” badge at the bottom of the payment page. Partners must also specify their website that the logo will link to.

Roles and permissions

If you create payment links with an entity user token, this user must have a role with the following permissions:

  • To create payment links for receivable invoices: read permission for entity_bank_account and receivable.
  • To create payment links for payables: read permission for counterpart and payable.

When using a partner-level token, no extra permissions are required.

Payment link lifecycle

The possible status of a payment link during its lifecycle are as follows:

StatusDescriptionNext statusWebhook triggered
created

This is the initial status of a recently created payment link.

⚠️ Every time a payment link is created, an associated payment intent is also automatically created.

succeeded,
expired
payment_link.created
succeededThis status means the payment provider has accepted the payment method.

⚠️ A succeeded payment link does not mean the payment itself was succeeded.
payment_link.status_updated
expiredExpired payment links cannot be reactivated. Check payment link expiration for further information.payment_link.status_updated

The payment intent is the object that represents the payment itself and the one that must be used to track the payment.

The steps below describe how to receive a payment through a payment link:

  1. Get the available payment methods. (Recommended)
  2. Create a payment link.
  3. Share the payment link with the payer.
  4. Track the payment.

This step is not mandatory but highly recommended.

Some payment methods may be rejected by the payment provider, even if you assign all payment methods to the entity and the entity completes onboarding. In these cases, if you request a payment link with rejected or inactive payment methods, an error message will be returned.

The payment link object contains the payment methods to be displayed to the payer on the payment page so they can select their preferred one during the payment act.

Learn how to get all available payment methods for a specific entity and check the full list of payment methods Monite supports.

If you know in advance which payment methods to display to the payer, you can directly request the payment link without having to retrieve the whole list of available payment methods first.

2. Create a payment link

The payer must access a specific link to initialize the payment. To generate this payment link, call POST /payment_links, which will return you a payment_page_url that can be used to make the payment. The payment link can be up to 400 characters long.

The request body varies depending on whether the payment link is created for an invoice stored in Monite platform (as a payable or receivable), or for an arbitrary external invoice.

The common fields for all payment links are:

  • return_url - The URL where the user will be redirected after the payment is complete. It is required for payment links that are created for payables (object.type="payable") and optional for other types of payment links.

  • expires_at - Optional. The date and time when the payment link will expire. For more information, see Payment link expiration.

  • payment_methods - Required. A list of payment methods to show on the payment page. These payment methods must be enabled for the entity that will make or accept the payment.

    • Payables can currently be paid using:

      • SEPA Credit (sepa_credit) - in case of European entities and counterparts in the SEPA zone.
      • ACH Direct Debit (ach) - in case of US-based entities and counterparts. Note: ACH payment option is not available on Monite payment page. Instead, these payments can be initiated by calling POST /batch_payments. Refer to our ACH guide to learn how to integrate ACH payments into your application.
    • Receivables can be paid using any payment method with direction=receive.

    • External invoices can be paid using the same payment methods as payables (in case an entity pays to its counterpart) or receivables (in case an entity accepts a payment from its counterpart).

Other required fields and values depend on the use case and are explained below:

The successful response contains the URL to the payment page (payment_page_url). This URL can be up to 400 characters long.

Example: payment link response for a receivable invoice
1{
2 "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
3 "amount": 1000,
4 "currency": "EUR",
5 "expires_at": "2024-09-30T13:53:49.198Z",
6 "invoice": {
7 "issue_date": "2024-09-19",
8 "due_date": "2024-09-30",
9 "file": {
10 "name": "invoice.pdf",
11 "mimetype": "application/pdf",
12 "url": "https://bucketname.s3.com/12345/invoice.pdf"
13 }
14 },
15 "payer": null,
16 "payment_intent": {
17 "id": "9400893a-1ad7-4154-9bc5-7bd4744902ee",
18 "updated_at": "2024-09-19T10:40:59.052011+00:00",
19 "application_fee_amount": null,
20 "object": null,
21 "provider": null,
22 "selected_payment_method": null,
23 "status": "created"
24 },
25 "payment_intent_id": "9400893a-1ad7-4154-9bc5-7bd4744902ee",
26 "payment_methods": [
27 "card",
28 "eps",
29 "ideal",
30 "sepa_debit",
31 "sepa_credit"
32 ],
33 "payment_page_url": "https://pay.sandbox.monite.com?data=eyJpZ...",
34 "payment_reference": "INV-00042",
35 "recipient": {
36 "id": "cff85bcf-bd28-472a-93a7-317f9cbbc96f",
37 "type": "entity",
38 "name": "Acme Inc.",
39 "bank_accounts": [
40 {
41 "id": "24049bec-bcd6-4590-9750-974fb75233d6",
42 "account_holder_name": "Acme Inc.",
43 "account_number": null,
44 "bic": "DEUTDEFFXXX",
45 "country": "DE",
46 "currency": "EUR",
47 "display_name": "Primary account",
48 "iban": "DE25648730420109480400",
49 "is_default": true,
50 "name": "Primary account",
51 "routing_number": null,
52 "sort_code": null,
53 "was_created_by_user_id": null
54 }
55 ]
56 },
57 "return_url": "https://example.com/where-to-redirect-after-payment",
58 "status": "created"
59}

Once the payment link is created, an associated payment intent is also automatically created. The payment intent ID returned will be used to track the actual payment.

2.1. Payment link for a payable

Payment links can be created only for payables in the waiting_to_be_paid status. To create a payment link, specify the following data in the request body for POST /payment_links:

  • object.type - Must be "payable".
  • object.id - Required. Payable ID.
  • recipient.type - Must be "counterpart".
  • recipient.id - Required. ID of the counterpart that issued the payable. The value must be the same as the counterpart ID in the payable data.
  • payment_methods - This list must contain a single item, "sepa_credit".
  • return_url - Required. The URL where the entity user who will make the payment will be redirected after the payment is successfully initiated.
  • Other fields as necessary.
1curl -X POST 'https://api.sandbox.monite.com/v1/payment_links' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'X-Monite-Entity-Id: ENTITY_ID' \
4 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN' \
5 -H 'Content-Type: application/json' \
6 -d '{
7 "object": {
8 "type": "payable",
9 "id": "PAYABLE_ID"
10 }
11 "recipient": {
12 "type": "counterpart",
13 "id": "COUNTERPART_ID"
14 },
15 "payment_methods": [
16 "sepa_credit"
17 ],
18 "return_url": "https://return.url.com",
19 "expires_at": "2023-12-03T13:53:49.198Z",
20 }'

2.2. Payment link for a receivable

Payment links can be created only for receivable invoices in the issued and partially_paid statuses. To create a payment link, specify the following data in the request body for POST /payment_links:

  • object.type - Must be "receivable".
  • object.id - Required. ID of the receivable invoice.
  • recipient.type - Must be "entity".
  • recipient.id - Required. ID of the entity that issued the receivable. The value must be the same as specified in X-Monite-Entity-Id request header.
  • Other fields as necessary.
1curl -X POST 'https://api.sandbox.monite.com/v1/payment_links' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'X-Monite-Entity-Id: ENTITY_ID' \
4 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN' \
5 -H 'Content-Type: application/json' \
6 -d '{
7 "object": {
8 "type": "receivable",
9 "id": "RECEIVABLE_INVOICE_ID"
10 }
11 "recipient": {
12 "type": "entity",
13 "id": "ENTITY_ID"
14 },
15 "payment_methods": [
16 "card",
17 "eps",
18 "ideal",
19 "sepa_credit",
20 "sepa_debit"
21 ],
22 "return_url": "https://return.url.com",
23 "expires_at": "2023-12-03T13:53:49.198Z",
24 }'

2.3. Payment link for an external invoice

This example shows how to create a payment link for an arbitrary invoice (stored outside of Monite platform) or arbitrary payment amount. You need to call POST /payment_links and provide the following data in the request body:

  • currency - Required. The payment currency. See the list of currencies supported by Monite.
  • amount - Required. The amount to be paid, in minor units.
  • payment_reference - Required. Invoice number or payment reference number.
  • invoice - Optional. An object containing information about the invoice, such as the issue date, due date, URL of the invoice file. If provided, this information will be displayed on the payment page. If invoice file URL is provided, the payment page will also display the invoice file. For a list of invoice object fields, see the description of the POST /payment_links endpoint.
  • Other fields as necessary.
Payment link for an external invoice
1curl -X POST 'https://api.sandbox.monite.com/v1/payment_links' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'X-Monite-Entity-Id: ENTITY_ID' \
4 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN' \
5 -H 'Content-Type: application/json' \
6 -d '{
7 "payment_methods": [
8 "card",
9 "eps",
10 "ideal",
11 "sepa_credit",
12 "sepa_debit"
13 ],
14 "recipient": {
15 "id": "<Recipient ID>",
16 "type": "entity|counterpart"
17 },
18 "return_url": "https://return.url.com",
19 "expires_at": "2023-12-03T13:53:49.198Z",
20 "amount": 1000,
21 "currency": "EUR",
22 "payment_reference": "Inv 102",
23 "invoice": {
24 "issue_date": "2022-10-17",
25 "due_date": "2022-10-17",
26 "file": {
27 "name": "invoice.pdf",
28 "mimetype": "application/pdf",
29 "url": "https://bucketname.s3.com/12345/invoice.pdf"
30 }
31 }
32 }'

After a payment link is created, you can share its URL (payment_page_url) with the payer. When a payer navigates to this URL, they will see the payment page displaying information about the invoice and payment amount. The payer can select their preferred payment method and enter their payment information to initialize the payment.

4. Track the payment

Use the payment intent ID obtained in step 2 to watch the payment transition from status to status and get information about the actual payment.

Given an invoice ID, you can find an existing payment link that was previously created for that invoice. This is supported for both accounts payable invoices (payables and accounts receivable invoices.

To do this, first call GET /payment_intents?object_id=INVOICE_ID. This gives you a list of payment intents associated with the specified invoice:

1{
2 "data": [
3 {
4 "id": "6f1a0e95-059b-4095-9264-b8a600e79a61",
5 ...
6 "payment_link_id": "0b971087-a15e-4946-a6c8-be230e297004",
7 "status": "processing"
8 }
9 ]
10}

Each payment intent has the payment_link_id field containing the ID of the associated payment link. You can pass this ID to GET /payment_links/{payment_link_id} to get the payment link details, such as the URL and expiration date.

1{
2 "id": "0b971087-a15e-4946-a6c8-be230e297004",
3 ...
4 "expires_at": "2024-08-30T10:52:45.785Z",
5 "payment_page_url": "https://pay.sandbox.monite.pay/?data=..."
6}

You can track the payment link transition from status to status in two different ways:

1. Webhooks

You can be notified of every change in the status of the payment by subscribing to the payment_link.status_updated webhook. Call POST /webhook_subscriptions with the following request body, replacing the url with the URL of your webhook listener endpoint:

1curl -X POST 'https://api.sandbox.monite.com/v1/webhook_subscriptions' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN' \
4 -H 'Content-Type: application/json' \
5 -d '{
6 "object_type": "payment_link",
7 "url": "https://example.com/your-webhook-listener"
8 }'

The event sent by Monite contains entity_id, object_type, and object_id, which can be used to identify the affected payment intent:

1{
2 "id": "06c003f1-6b05-415f-be6d-39ecacdddbd3",
3 "created_at": "2024-03-04T20:06:48.593225+00:00",
4 "action": "payment_link.status_updated",
5 "api_version": "2024-01-31",
6 "entity_id": "ce0e9fc7-b3e7-4f12-ad86-bfb0725a99f0",
7 "description": "payment_link_status_updated",
8 "object": {
9 "id": "f7dcd6bc-2cc9-4cb9-be9c-d7bf2404acd7"
10 },
11 "object_type": "payment_link",
12 "webhook_subscription_id": "c7f37127-44e5-494a-833a-21e60585f187"
13}

The payment link ID received from the webhook can be used to check the status of the payment link, by calling GET /payment_links/{payment_link_id}:

1curl -X GET 'https://api.sandbox.monite.com/v1/payment_links/3fa85f6...f66afa6' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN'

The successful response contains information about the payment link:

1{
2 "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
3 "amount": 11781,
4 "currency": "EUR",
5 "expires_at": "2023-03-01T10:52:45.785Z",
6 ...
7 "payment_intent_id": "9400893a-1ad7-4154-9bc5-7bd4744902ee",
8 "payment_page_url": "https://pay.sandbox.monite.com?data=eyJpZ...",
9 ...
10 "return_url": "https://example.com/where-to-redirect-after-payment",
11 "status": "created"
12}

By default, payment pages are served from pay.monite.com, but partners can use their own domain instead (for example, pay.mycompany.com). To do this, follow these steps:

  1. Register the desired domain name with your DNS provider. We recommend that you register two different domains - one for the Production environment, and another one for the Sandbox environment. For example, pay.mycompany.com and pay.sandbox.mycompany.com.

  2. Create CNAME records to point your production domain to pay.monite.com, and the sandbox domain to pay.sandbox.monite.com.

  3. Specify your custom domain name in the partner setting payments.payment_page_domain. Set the corresponding value for the Sandbox and Production environments.

    Sandbox example
    1curl -X PATCH 'https://api.sandbox.monite.com/v1/settings' \
    2 -H 'X-Monite-Version: 2024-01-31' \
    3 -H 'Authorization: Bearer YOUR_PARTNER_TOKEN' \
    4 -H 'Content-Type: application/json' \
    5 -d '{
    6 "payments": {
    7 "payment_page_domain": "pay.sandbox.mycompany.com"
    8 }
    9 }'
  4. Contact us to complete the setup.

From now on, payment links generated by Monite will use your custom domain in their URLs.

Payment link expiration

By default, payment links expire within 24 hours from when they are created. You can specify a custom expires_at timestamp (up to 70 days) when creating a payment link. Once set, the expiration time cannot be changed.

After a payment link expires, visiting its payment_page_url in a browser will show an expiration message instead of a payment page. Expired payment links cannot be reactivated, but you can create a new payment link if needed.

You can also force the expiration of a payment link by calling POST /payment_links/{payment_link_id}/expire. This may be needed, for example, if the related invoice was updated or canceled, making the original payment link outdated.

1curl -X POST 'https://api.sandbox.monite.com/v1/payment_links/{payment_link_id}/expire' \
2 -H 'X-Monite-Version: 2024-01-31' \
3 -H 'X-Monite-Entity-Id: ENTITY_ID' \
4 -H 'Authorization: YOUR_PARTNER_TOKEN'

This changes the payment link’s status to "expired". The response returns the payment link details with the updated status:

1{
2 "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
3 "amount": 1000,
4 "currency": "EUR",
5 ...
6 "status": "expired"
7}

When a payment link expires (whether automatically or upon request), a payment_link.status_updated webhook is triggered.