SEPA Direct Debit server-to-server integration

Collect payments directly from your customers' EUR bank accounts using server-to-server API calls — no hosted checkout widget required.

The Single Euro Payments Area (SEPA) is a European Union initiative that standardises payments within and across member countries. SEPA Direct Debit (SDD) lets merchants collect payments directly from customers' EUR-denominated bank accounts — making it a popular choice for subscriptions, recurring billing, and any flow where your platform manages payment mandates directly. Revolut supports the SEPA Direct Debit Core scheme, which covers both personal and business bank accounts across the SEPA region.

This guide will help you integrate with the Revolut Merchant API to accept SEPA Direct Debit payments through direct server-to-server API calls, without relying on a checkout widget. To debit an account, you collect the customer's name and IBAN, obtain a signed mandate authorising the debit, then submit the payment from your backend.

How it works

From an implementation perspective, integrating SEPA Direct Debit with Revolut involves the following components:

  1. Server-side: You set up endpoints on your server that create orders and submit payments using the Revolut Merchant API.
  2. Mandate management: You collect SEPA Direct Debit mandates from your customers and store them securely. Revolut does not manage mandates on your behalf.
  3. Webhooks: You set up an endpoint to receive webhook events from the Merchant API. Unlike card payments, SEPA Direct Debit is fully asynchronous — payment outcomes can arrive up to 5 business days after submission. Webhooks are mandatory, not optional.

The order and payment flow is as follows:

  1. Order creation: Your backend creates an order via the Revolut Merchant API and obtains the order ID.
  2. Mandate collection: Your platform collects the customer's IBAN and mandate consent. You are responsible for compliance with SEPA mandate requirements.
  3. Payment submission: Your backend submits the payment request with the debtor's IBAN and name (or a saved payment method ID).
  4. Asynchronous processing: Revolut submits the debit instruction to the SEPA scheme. No polling is required.
  5. Webhook notification: Your server receives a webhook when the payment is completed or declined — this can take from a few hours to up to 5 business days.
Info

For more information about the order and payment lifecycle, see: Order and payment lifecycle.

Implementation overview

Check the following high-level overview on how to implement SEPA Direct Debit integration:

  1. Create an order
  2. Collect a SEPA mandate
  3. Handle SEPA mandate and notification rules
  4. Create a payment request
  5. Handle payment outcomes via webhooks

Before you begin

Before you start this guide, ensure you have completed the following steps:

  • Get started: 1. Apply for a Merchant account
  • Get started: 2. Generate the API keys
  • Obtained a valid SEPA Creditor ID
  • Contacted your account executive to have SEPA Direct Debits enabled on your merchant account
  • Shared your Creditor ID with Revolut
  • Confirmed you can collect, store, and manage SEPA Direct Debit mandates in compliance with SEPA guidelines
  • Set up a process to send pre-debit notifications to customers as required by SEPA rules

Implement SEPA Direct Debit integration

1. Create an order

Create an order from your backend forwarding the data collected during checkout, and including your Secret API key in the authorisation header. We recommend creating the order when the customer is at your checkout and you are ready to initiate the payment.

Send a POST request to the Create an order endpoint with the order details:

Request example
{
"amount": 100,
"currency": "EUR",
"customer": {
"email": "customer@example.com"
}
}
Caution

SEPA Direct Debit payments are denominated in EUR only.

ParameterDescriptionRequired
amountThe order amount in the smallest currency unit (cents). For €1.00, use 100.Yes
currencyMust be EUR for SEPA Direct Debit payments.Yes
customerCustomer details. Pass email for new customers or id for existing customers. Required if you want to save the payment method for future use.No
Info

For complete details on all available parameters, see: Merchant API: Create an order.

Once the order is created, extract the id from the response — you will use it as order_id in Step 4:

Response example
{
"id": "64d38f09-d04e-a9b5-b394-991f8a527eb3",
"token": "1112e405-c0b1-4a3f-a50d-e8acd66c7a8e",
"type": "payment",
"state": "pending",
"created_at": "2023-08-09T13:05:13.697830Z",
"updated_at": "2023-08-09T13:05:13.697830Z",
"capture_mode": "automatic",
"amount": 100,
"currency": "EUR",
"outstanding_amount": 100,
"checkout_url": "https://checkout.revolut.com/payment-link/999515ab-be9e-4477-b879-85b85c1576c1"
}

2. Collect a SEPA mandate

Before initiating any SEPA Direct Debit payment, you must collect a valid mandate from your customer. A mandate is your customer's explicit authorisation for you to debit their bank account.

Collect the following information and store it securely in your system:

Mandate fieldDescription
Customer nameThe account holder's name as it appears on their bank account
IBANThe customer's International Bank Account Number
Mandate consentThe customer must explicitly agree to the SEPA Direct Debit terms before any debit is initiated
Warning

Never send IBAN or mandate data directly from your frontend to Revolut.

Always route it through your backend server.

You are responsible for ensuring that each mandate contains all mandatory SEPA fields and is accepted by the customer before any payment is submitted. For full details on mandate storage and compliance requirements, see Step 3.

3. Handle SEPA mandate and notification rules

SEPA rules impose obligations on you as a merchant before and after initiating any direct debit. You are fully responsible for compliance — Revolut does not manage mandates or send pre-notifications on your behalf.

Mandate management

RequirementDetails
Mandatory fieldsDebtor name, IBAN, creditor identifier, mandate reference, customer consent
StorageStore mandates securely for as long as they remain valid and for at least 14 months after the last collection
Mandate referenceRevolut generates a unique mandate reference number and returns it in the payment response. Use this reference in pre-debit notifications sent to your customers.
RevocationProvide customers with a clear process to cancel or revoke their mandate
Signed mandate deliveryShare a copy of the signed mandate with the customer as required by SEPA guidelines. In the event of a dispute, you may be asked to submit the mandate and evidence of its delivery.
Audit readinessBe prepared to provide proof of mandate authorisation if challenged by the debtor's bank

Pre-notification requirements

You must notify the customer before each debit. Send the pre-notification at least 14 calendar days before the debit date, unless you have contractually agreed to a shorter period with the customer.

Each notification must include:

Required contentDetails
Last 4 digits of IBANThe last 4 digits of the debtor's bank account number
Mandate referenceThe unique reference number of the mandate
Debit amountThe amount to be debited
Creditor identifierYour SEPA creditor identifier
Contact informationYour business contact details
Tip

For subscriptions with fixed amounts and regular dates, a single pre-notification can cover multiple future collections if the schedule is clearly communicated.

Caution

If anything in the mandate changes — amount, date, or any other terms — you must collect a new mandate from the customer. Revolut does not support mandate updates.

Submission deadlines

Payment typeSubmit instructions to Revolut by
First or single SDDAt least 5 business days before the requested payment date
Recurring SDDAt least 2 business days before the requested payment date
Caution

If instructions are submitted after the deadlines above, the payment may be processed later than your intended date.

4. Create a payment request

Once the order is created and the mandate has been collected, submit a payment request from your backend.

Send a POST request to the Pay for an order endpoint, passing id returned from Step 1: Create an order as {order_id}.

There are two ways to submit a SEPA Direct Debit payment request, depending on whether you are charging a customer for the first time or using a payment method they have previously authorised:

For the first payment from a customer, pass the debtor's IBAN and name directly. Pass save_for: merchant to save this payment method for future recurring charges without requiring the customer to re-enter their details.

Request example
{
"payment_method": {
"type": "sepa_direct_debit",
"debtor_iban": "DE12345678901234567890",
"debtor_name": "John Doe",
"billing_address": {
"street_line_1": "Example Street 123",
"street_line_2": "II/123",
"region": "London",
"city": "London",
"country_code": "GB",
"postcode": "123456"
},
"save_for": "merchant"
}
}

Payment request object:

ParameterDescriptionFormatRequired
payment_methodPayment method details for initiating a payment request.ObjectYes

payment_method object:

ParameterDescriptionFormatRequired
typeThe type of payment method. Must be sepa_direct_debit.StringYes
debtor_ibanThe customer's IBAN.StringYes
debtor_nameThe account holder's name.StringYes
billing_addressThe customer's billing address.ObjectNo
save_forPass merchant to save the payment method for future merchant-initiated charges.StringNo

billing_address object:

ParameterDescriptionRequired
street_line_1Street line 1 information.No
street_line_2Street line 2 information.No
regionThe region associated with the address.No
cityThe city associated with the address.No
country_codeThe country associated with the address (ISO 3166-1 alpha-2).Yes
postcodeThe postcode associated with the address.Yes

After submitting, the payment response will return with state: pending. This is expected — the payment is now queued for submission to the SEPA scheme.

Response example
{
"id": "d4aa447c-b9ef-4a0b-86ac-59bc4e8d590e",
"token": "74d501db-3abe-4bdb-bef2-9a73e01f8a13",
"order_id": "64d38f09-d04e-a9b5-b394-991f8a527eb3",
"state": "pending",
"amount": 100,
"currency": "EUR",
"payment_method": {
"type": "sepa_direct_debit",
"debtor_iban_last_four": "7890",
"debtor_name": "John Doe",
"mandate_reference": "69E6085A8B8FA31BBB82E833650700AD"
}
}

Store the following values from the response for later use:

FieldWhat to do
payment_method.idUse as the saved_payment_method.id in subsequent recurring payment requests. Not returned in the pending state — retrieve it from the payment after receiving the ORDER_COMPLETED webhook.
payment_method.mandate_referenceInclude in pre-debit notifications sent to your customers as required by SEPA rules.

5. Handle payment outcomes via webhooks

Once the payment request is submitted, processing moves entirely to the backend — no polling is required. SEPA Direct Debit payments follow a multi-day settlement process: after Revolut submits the debit instruction to the scheme, there is a refusal window during which the debtor's bank can return the payment.

Most outcomes — whether completed or declined — can arrive up to 5 business days after submission. Do not assume a pending state means the payment has failed, and do not fulfil orders until you receive a final webhook event.

Warning

For SEPA Direct Debit, webhooks are not optional. Your backend must be set up to receive and process webhooks before you go live.

Set up your webhook endpoint by subscribing to the following events via the Create a webhook endpoint:

ORDER_COMPLETED, ORDER_PAYMENT_DECLINED, ORDER_PAYMENT_FAILED, ORDER_CANCELLED

Info

For detailed information on setting up webhooks, see: Use webhooks to track order and payment lifecycle.

Handle the following scenarios:

The payment has been captured and completed.

Webhook expected:

Webhook eventDescription
ORDER_COMPLETEDThe payment has been captured and completed

What to do:

Fulfil the order (ship goods, grant access, etc.) once ORDER_COMPLETED is received.

If you passed save_for: "merchant" in the initial payment request, also retrieve the payment after ORDER_COMPLETED to obtain payment_method.id — store it for subsequent recurring payment requests.

Implementation checklist

Before deploying your implementation to your production environment, complete the checklist below:

Account setup

  • Obtained a valid SEPA Creditor ID.
  • Contacted your account executive to have SEPA Direct Debits enabled on your merchant account.
  • Shared your Creditor ID with Revolut.

API integration

  • Successfully created an order using the Merchant API and extracted the order id.

Mandate management

  • Mandates collected with all mandatory SEPA fields: debtor name, IBAN, creditor identifier, and customer consent.
  • Mandates stored securely for at least 14 months after the last collection.
  • Mandate reference extracted from the payment response and stored for use in pre-debit notifications.

Notifications & timing

  • Pre-notification workflow in place: customers notified at least 14 calendar days before each debit.
  • First or single SDD instructions submitted at least 5 business days before the payment date.
  • Recurring SDD instructions submitted at least 2 business days before the payment date.

Webhook handling

  • Webhook endpoint configured and subscribed to ORDER_COMPLETED, ORDER_PAYMENT_DECLINED, ORDER_PAYMENT_FAILED, ORDER_CANCELLED.
  • Backend implementation handles delayed webhook delivery (payment outcomes can arrive up to 5 business days after submission).
  • Error handling implemented for declined payments with appropriate customer-facing messaging.
  • (If saving payment methods for recurring use) Payment retrieved after ORDER_COMPLETED to obtain payment_method.id, and stored securely for subsequent recurring payment requests.
Sandbox availability

SEPA Direct Debit is not available in the Sandbox environment. Integration testing requires a production merchant account with SEPA Direct Debits enabled.

Success

Congratulations! You've successfully integrated SEPA Direct Debit with the Revolut Merchant API.


Disputes

SEPA Direct Debit provides a dispute process through which customers can challenge payments with their bank.

Unconditional dispute window (up to 8 weeks)

Customers can dispute any SEPA Direct Debit payment through their bank within 8 weeks of being debited, without providing a reason. Disputes within this period are automatically honoured.

Unauthorised payment claims (8 weeks to 13 months)

After 8 weeks and up to 13 months, a customer can dispute a payment only on the grounds that it was unauthorised. When Revolut receives a dispute notification from the SEPA scheme, it is automatically booked as lost.

Caution

SEPA Direct Debit disputes are final — there is no appeal process. If a customer successfully disputes a payment, you must contact them directly to resolve the situation. If they agree to return the funds, they must initiate a new payment.

If a dispute is raised against a payment associated with a mandate, that mandate may be deactivated. Check the mandate status after any dispute and re-collect consent from the customer if their mandate is no longer active.

You can view and monitor SEPA Direct Debit disputes programmatically using the Disputes API.

Note

SEPA Direct Debit disputes cannot be challenged. When Revolut receives a dispute from the SEPA scheme, it is automatically booked as lost - there is no response or evidence submission process.

Refunds

You can refund SEPA Direct Debit payments for up to 5 days after receiving the ORDER_COMPLETED webhook — full amount only. Refunds are free, but processing fees for the original payment are non-refundable.

To issue a refund, use the Refund an order endpoint.

Info

For full details on issuing refunds, see: Refunds.

Timing

Refunds typically take 3-4 business days to process. Funds appear in the customer's account within 5 business days. SEPA refunds appear as credits on the customer's bank statement with a reference to the original payment — they are not explicitly labelled as refunds.

Always notify the customer when issuing a refund and inform them that it may take up to 5 business days to appear in their account.


What's next