Skip to main content

SEPA Direct Debit

Description

SEPA Direct Debit lets you collect euro payments directly from a payer's bank account within the Single Euro Payments Area (SEPA). The payer authorises the collection by granting a SEPA mandate, which you must present at checkout and which the payer must accept before the payment is created.

This payment method supports both SEPA schemes:

  • dd for the consumer (B2C) scheme
  • dd_b2b for the business-to-business (B2B) scheme

There is no hosted page and no browser redirection. The transaction is submitted to the payer's financial institution during the next export cycle, so it stays in the started status until submission happens, and its final status is delivered asynchronously via postback.

Availability

Available for bank accounts denominated in EUR within the SEPA zone.

For the B2B scheme, the payer must be a business and the debtor's bank must support SEPA B2B collections.

Transaction Types

The following transaction types are currently available:

Payment Flow

The transaction moves through the following statuses (identical for B2C and B2B). The Status Code column is the transaction's status code:

StatusStatus CodeWhen
started1Payment created; queued for the next SEPA export cycle
pending2Collection submitted to the bank via the export file. Treated as a successful state
completed3The debit settled and no return was received
chargeback13The collection was returned (a return with or without a reason code)
declined6Return with a decline reason code
error4Return with an error reason code
note

The started status in the synchronous response is not the final result. SEPA is processed asynchronously, so use the postbacks sent on each status change as the source of truth. A standalone mandate reference created with the Mandate Reference API stays in the registered (9) status.

Before creating an initial SEPA Direct Debit payment you must display the SEPA mandate information to the payer and have them explicitly agree to the collection of the debited amount. The mandate text must include the creditor details, the mandate reference, the account holder, and the IBAN.

caution

For B2C, the payer has the right to demand a refund of a charged amount for up to eight weeks from the date of the charge. For B2B, there is no refund right for authorised collections after the debit. All examples of SEPA legal texts are provided for guidance only and are not guaranteed to be legally compliant.

For recurring collections, the payer must additionally receive a pre-notification announcing the amount and the due date before each collection.

API Implementation

Supported payment_type values:

  • dd for SEPA Direct Debit B2C
  • dd_b2b for SEPA Direct Debit B2B

Implementation Flow

Collect the payer's IBAN and mandate acceptance in your own checkout, then send the payment request directly to the API. There is no hosted page and no browser redirection. You can provide the mandate reference in one of three ways:

  • pass your own reference in the sepa_mandate parameter,
  • create one upfront with the Mandate Reference API and pass the returned token as sepa_mandate, or
  • omit sepa_mandate and let the API generate one automatically.

Steps:

  1. Present the SEPA mandate at checkout and capture the payer's agreement.
  2. Make a Payment API request including the bank account data (iban, account_holder) and the relevant payment_type (dd or dd_b2b). The synchronous response returns the transaction in the started status.
  3. The collection is queued for the next SEPA export cycle. Once it is submitted to the bank, the transaction moves to pending and a postback is sent.
  4. After the bank reconciles the collection, the transaction reaches its final status (completed, or chargeback / declined / error on a return), and a postback is sent for the change.

A postback is sent on each status change, so use it, not the synchronous response, as the source of truth for the final result.

Payment API

Payment API Request

The request structure is the same for both schemes. Only the payment_type value changes:

  • dd for B2C
  • dd_b2b for B2B
payment_typeStringrequired
dd for B2C or dd_b2b for B2B
order_idStringrequired
Any alphanumeric string to identify the Merchant's order
amountFloatrequired
Amount of the transaction including all taxes and shipping fees
currencyStringrequired
3 letter currency code. SEPA collections are processed in EUR
account_holderStringrequired
Bank account holder's name
ibanStringrequired
IBAN of the payer's bank account (max. 31 characters)
bicString
BIC of the payer's bank account (max. 11 characters). Optional for SEPA IBANs
sepa_mandateString
Mandate reference number (max. 35 characters). If omitted, a mandate reference is generated automatically
postback_urlStringrequired
The URL where updates about transaction status are posted
This example includes only the parameters required to create a SEPA Direct Debit payment. See the Create Payment API reference for the full list of supported parameters, including the Direct Debit Parameters block.
Example Request (B2C)
POST /rest/payment
Authorization: Basic <base64(api_key:api_password)>
Content-Type: application/json
{
"payment_type": "dd",
"order_id": "SEPA-12345",
"amount": "15.90",
"currency": "EUR",
"account_holder": "Max Mustermann",
"iban": "DE89370400440532013000",
"first_name": "Max",
"last_name": "Mustermann",
"address": "Teststr. 5",
"city": "Berlin",
"postal_code": "15557",
"country": "DE",
"postback_url": "https://your-postback.url.com"
}

For a B2B payment, use the same payload with payment_type: "dd_b2b". Example:

{
"payment_type": "dd_b2b",
"order_id": "SEPA-B2B-12345",
"amount": "150.00",
"currency": "EUR",
"account_holder": "Muster GmbH",
"iban": "DE89370400440532013000",
"first_name": "Max",
"last_name": "Mustermann",
"address": "Teststr. 5",
"city": "Berlin",
"postal_code": "15557",
"country": "DE",
"postback_url": "https://your-postback.url.com"
}

Payment API Response

The synchronous response format is the same for both schemes:

transaction_idString
ID of the created transaction
payment_typeString
Payment type of the transaction
status_codeInteger
Status code of the transaction. Stays 1 (started) until the collection is submitted to the bank
statusString
Status of the transaction
order_idString
Order ID of the transaction
messageString
Optional additional information about the transaction result
additional_transaction_dataString
Additional transaction data provided by you. This will be shown in the dashboard as well as when you query for transaction data. It will also be sent back to your postback_url as part of the postback data.
amountFloat
Amount of the transaction
included_feesString
Included fees for the transaction
error_codeInteger
Error code for the response
mandate_idString
Mandate reference used for the collection
ibanString
IBAN of the payer's bank account
recurring_mandateInteger
1 if the mandate is recurring, 0 otherwise
execution_dateString
Date on which the collection is scheduled for execution
Example Response
{
"transaction_id": "6c2e7e30-b741-4c5e-bc50-91dffdf0e5fb",
"payment_type": "dd",
"status_code": 1,
"status": "started",
"order_id": "SEPA-12345",
"message": null,
"additional_transaction_data": null,
"amount": 15.9,
"included_fees": "0.00",
"error_code": 0,
"mandate_id": "a7678918bfbbfa449cf9ff78446b60a4",
"iban": "DE89370400440532013000",
"recurring_mandate": 0,
"execution_date": "2026-07-07"
}
note

Depending on your payment method configuration and acquirer, SEPA transactions are submitted to the financial institution either the same day or the next business day. Until submission happens on our side, the transaction stays in the started state. Use the postback as the source of truth for the final status.

Create a Mandate Reference

SEPA Direct Debit transactions depend on a mandate. You can either provide the mandate yourself via the sepa_mandate parameter in the Payment API, or create a mandate reference upfront using the Mandate Reference API.

Use the dedicated API reference page for:

  • the endpoint definition for POST /rest/create_mandate_reference
  • request and response examples
  • the full parameter list
  • how to use the returned transaction_id and mandate reference (token in the response, the value to show to the payer and to send later as sepa_mandate)

When creating the mandate reference, use payment_type: "dd" for B2C or payment_type: "dd_b2b" for B2B.

Recurring Payments

Mandates can be one-time or recurring. For recurring collections:

  1. Create an initial payment or a mandate reference with recurring: 1.
  2. Store the returned transaction_id.
  3. Create each subsequent collection with recurring: 1 and original_transaction_id set to the stored transaction_id.

The recurring flow is the same for both schemes.

Refund API

Refunds are supported in full and in part. A SEPA refund is processed as a credit transfer back to the payer's account, so the refund is created in the started status and completed asynchronously.

transaction_idStringrequired
ID of the transaction to be refunded
amountFloat
Refunded amount. When omitted, the full amount will be refunded
commentString
Any reference you would like to store on this refund. Displayed in the dashboard
See the Create a Refund API reference for the full list of supported parameters.
Example Request
POST /rest/refund
Authorization: Basic <base64(api_key:api_password)>
Content-Type: application/json
{
"transaction_id": "6c2e7e30-b741-4c5e-bc50-91dffdf0e5fb",
"amount": "15.90",
"comment": "Goods returned"
}

For B2B, note that the lack of payer refund rights for authorised collections does not change the merchant-side refund API flow.

Payout API

Payouts send money to a bank account without a prior payment (an unreferenced credit transfer). Provide the recipient bank account data.

payment_typeStringrequired
dd for B2C or dd_b2b for B2B
order_idStringrequired
Any alphanumeric string to identify the Merchant's order
amountFloatrequired
Amount to be paid out
currencyStringrequired
3 letter currency code
account_holderStringrequired
Recipient bank account holder's name
ibanStringrequired
Recipient IBAN
merchant_referenceString
Reference for the payout
postback_urlStringrequired
The URL where updates about transaction status are posted
See the Create a Payout API reference for the full list of supported parameters.
Example Request
POST /rest/payout
Authorization: Basic <base64(api_key:api_password)>
Content-Type: application/json
{
"payment_type": "dd",
"order_id": "PAYOUT-12345",
"amount": "15.90",
"currency": "EUR",
"account_holder": "Max Mustermann",
"iban": "DE89370400440532013000",
"merchant_reference": "Refund for order XYZ",
"postback_url": "https://your-postback.url.com"
}

Postbacks

When the collection is submitted and its status changes, a postback is sent to your postback_url. In addition to the standard Payment API postback fields, SEPA Direct Debit postbacks include mandate_id, iban, bic, recurring_mandate, and execution_date. This applies to both B2C and B2B. For retry policy and signature verification, see Postbacks.

Test Data

Use the following test bank account in the sandbox environment for both B2C and B2B:

FieldValue
account_holderMax Mustermann
ibanDE89370400440532013000
bicCOBADEFFXXX