Sepa Direct Debit (SDD OUT)

SEPA Direct Debit (SDD) is a pull-based payment scheme that allows a creditor to debit a debtor's bank account.

Similarly to other SEPA transfers, an SDD requires the IBAN (and occasionally the BIC) of both the sender and the recipient's bank accounts.

However, it differs from other SEPA transfers in that the roles are reversed: the recipient of the funds is the one who must request the money transfer from the sender.

SEPA Direct Debit is only available in Euros and can be used for both one-off transactions and recurring payments. It is often used for recurrent payments so that customers can avoid missing payments and being charged additional fees.
The debtor must sign a valid SDD mandate to authorize the creditor to withdraw the money from the debtor's account. Additionally, there are other rules governing SDDs, such as pre-notifications, refunds, returns, etc.

👍

Xpollens provides a complete solution to create mandates and manage Sepa Direct Debit (SDD). If you already have a Sepa Creditor ID (SCI), you will be able to use it to direct debit your customer. If not, we can provide you with one within 48 hours.

General sequence diagram

sequenceDiagram
Title: Create an SDD Out (Core & B2B)
autoNumber
Actor User
Participant Partner
Participant XPO

Note over Partner, XPO: Create a beneficiary
Partner ->> XPO : POST api/sca/v2.0/users/appUserId/beneficiary
XPO ->> Partner : http 20X 

Note over Partner, XPO: Create a mandate
Partner ->> XPO : POST /api/v2.0/accounts/accountId/mandates {beneficiaryId]
XPO ->> Partner : http 20X
XPO -->> Partner: webhook MandateCreatedOrUpdated

Partner -->> User: Sign the mandate
User -->> Partner: Signature


Note over Partner, XPO: Activate the mandate
Partner ->> XPO : POST /api/v2.0/accounts/accountId/mandates/{mandateId}/activate
XPO ->> Partner : http 20X
XPO -->> Partner: webhook MandateCreatedOrUpdated


Note over Partner, XPO: Create an SDD OUT
Partner ->> XPO : POST /api/v2.0/sepa-direct-debits
XPO ->> Partner : http 20X
XPO -->> Partner: webhook SepaDirectDebitCreatedOrUpdated (status: Created)
XPO -->> Partner: webhook SepaDirectDebitCreatedOrUpdated (status: Approved)

Note over Partner, XPO: Completion of the SDD on the settlement date
XPO -->> Partner: webhook SepaDirectDebitCreatedOrUpdated (status: Completed)

Mandate

The mandate creation is a prerequesite to create an SDD (see "State diagram for an SDD OUT").

State diagram for a debtor mandate (Core & B2B)

stateDiagram
    [*] --> Created : when created
    Created --> Activated: when activated
		Created --> Revoked : when revoked
    Activated --> Revoked : when revoked
    Revoked --> [*]
❗️

Xpollens does not create a document for the mandate.

If you want to display a document to your customers, you must create it.




Mandate creation

The prerequesite to create a mandate is to create the beneficiary.

sequenceDiagram
Title: Create a mandate (Core & B2B)
autoNumber
Actor User
Participant Partner
Participant XPO

Note over Partner, XPO: Create a beneficiary
Partner ->> XPO : POST api/sca/v2.0/users/appUserId/beneficiary
XPO ->> Partner : http 20X

Note over Partner, XPO: Create a mandate
Partner ->> XPO : POST /api/v2.0/accounts/{accountId}/mandates {beneficiaryId, type}
XPO ->> Partner : http 20X {mandateId}
XPO -->> Partner: webhook MandatedCreatedOrUpdated

To use this mandate and create and SDD, the mandate must be activated.


Mandate activation


sequenceDiagram
Title: Activate the mandate
autoNumber
Actor User
Participant Partner
Participant XPO

Note over Partner, XPO: Create a mandate

Partner -->> User: Sign the mandate
User -->> Partner: Signature

Note over Partner, XPO: Activate the mandate
Partner ->> XPO : POST /api/v2.0/accounts/{accountId}/mandates/{mandateId}/activate
XPO ->> Partner : http 20X

Mandate revocation

Why and when

The mandate can not be modified. As a consequence, if a modification is needed, you must :

  • revoke the mandate
  • create a new one

Impacts

❗️

The revocation of the mandate does not cancel already scheduled SDDs.


What happens if the end user revokes the mandate from their external bank?

❗️

Xpollens is not aware that all SDDs have been opposed and that the mandate has been revoked.

However, we receive rejections for all direct debit attempts.


Sepa Direct Debit OUT (SDD OUT)

An SDD out is an SDD that debits an external account to credit the Xpollens account.

State diagram for an SDD OUT

stateDiagram-v2
    [*] --> Created  : internal status
    Created --> Approved : http 201
    Created --> Rejected:  rejected by The Payment Decision System
    Approved --> Rejected : /- rejected by BPCE <br/> /- rejected by the Interbank_market <br/> /- rejected by the external bank
        Approved --> Completed : accepted
		Rejected --> [*]
    Completed --> [*]



Sequence diagram for an SDD OUT

sequenceDiagram
Title: Create an SDD
autoNumber
Actor User
Participant Partner
Participant XPO
Participant BPCE
Participant Interbank_market

Note over Partner, XPO: Create an SDD OUT
Partner ->> XPO : POST /api/v2.0/sepa-direct-debits
XPO ->> BPCE: create SDD
XPO -->> Partner: webhook SepaDirectDebitCreatedOrUpdated {status Approved}


Note over XPO, Interbank_market: Every working day 21h (FR)
BPCE -->> XPO : SDDs sent {executionDate}
XPO -->> Interbank_market: SDD sent

Note over Partner, Interbank_market: On the executionDate
XPO -->> Partner:  webhook SepaDirectDebitCreatedOrUpdated {status Completed}

expectedExecutionDate

The expectedExecutionDate is the payment date expected by the partner (or its enduser) and entered in the request POST.
When the SDD creation on the SEPA exchange plateform, the expected execution date is recalculated. The value (new or not) is integrated in our system, and returns by the GET sdd. As a consequence, this date can evolve.

The expectedExecutionDate changes if the expectedExecutionDate is a day during a week-end or a day off. In this case, the expectedExecutionDate is the next working day.


🚧

Note: the expectedExecutionDate can not be in the past.

An SDD can only be created a maximum of 14 days before the expectedExecutionDate.
Therefore, you need to manage the debit schedule on your side to create the SDDs in a timely manner.

Rules

❗️

To schedule multiple SDDs in parallel for the same mandate, the first SDD must be finalized.

This occurs as soon as its status changes to "Completed".


SDD Core vs. SDD B2B

1- The characteristic is defined during the mandate creation, through the type = Core or B2B
2- This information is replicated during the SDD creation, same attribute type

Rules are different according to the sdd type:

SDD coreSDD B2B
UsesConsumer subscriptions
Telecoms, energy, insurance, subscriptions, associations, etc.
Business-to-business commercial relationships
Large or sensitive recurring B2B payments
Debtor profileIndividuals and companiesCompanies only
Mandate validity requirementsMandate signed by the debtor & mandate declared by the creditor to their bankMandate signed by the debtor & mandate declared by the creditor to their bank & mandate declared and validated by the debtor with their bank
Right to refund8 weeks without reason (from the due date)
13 months if no mandate (from the due date)
No refund possible, even within 8 weeks (from the due date)
Maximum presentation deadline14 days before the due date (settlement date)14 days before the due date (settlement date)
Creditor advantagesUniversal (individuals + companies)
Simple to implement (no obligation for the debtor to register and validate the mandate)
Reduced risk of post-debit non-payment: no refunds
Creditor disadvantagesHigher risk of post-debit non-paymentMore complex to implement (the mandate must be registered and validated at the debtor’s bank)
Debtor advantagesStrong protection: right to a refund (within 8 weeks)/
Debtor disadvantages/Obligation to register the mandate
No recourse after the debit



API & technical items

Error for a mandate creation

POST /api/v2.0/users/appuserId/mandates

Use caseHTTP codeCodeResponse
Wrong account404147"Code": 147,

"ErrorMessage": "The account accountId does not exist",

"Title": "The operation cannot succeed",

"Priority": 2,

"Date": "2026-01-19T15:12:19.2722244",

"OperationId": "ad0024bb182bfef80b604d3bbc7a0bed"
Beneficiary does not exist40420002"Code": 20002,

"ErrorMessage": "The beneficiary xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx does not exist",

"Title": "The operation cannot succeed",

"Priority": 2,

"Date": "2026-01-19T15:13:51.8055949",

"OperationId": "7d88eaa94c07a96738e28d6722aca127"
Missing attribute5001"Code": 1,

"ErrorMessage": "Une erreur technique est survenue, veuillez réessayer. Si l'erreur persiste, contactez le support client S-money. Object reference not set to an instance of an object.",

"Title": "Erreur technique",

"Priority": 2,

"Date": "2026-01-19T15:16:13.9885186",

"OperationId": "69eb472d4a63edfd5f9e13372aa1fa5a",

"ErrorDetails": null
Incorrect mandate type400715"Code": 715,

"ErrorMessage": "Paramètre(s) d'appel invalide(s). Mandate Type is empty or invalid",

"Title": "L'opération ne peut pas aboutir",

"Priority": 2,

"Date": "2026-01-19T15:23:20.4512095",

"OperationId": "61cf74a45500d286dc787a61b1979b91",

"ErrorDetails": null



Error for a mandate activation

POST api/v2.0/accounts/accountId/mandates/mandateId/activate

Use caseHTTP codeCodeResponse
Wrong mandate status4001025"Code": 1025,

"ErrorMessage": "Only outgoing mandate in Created status can be activated.",

"Title": "Invalid mandate status",

"Priority": 2,

"Date": "2026-01-19T15:21:51.8965169",

"OperationId": "3f8ad554f25de193c11e395a90409298"
Signature in the future4002"Code": 2,

"ErrorMessage": "Signature date cannot be in the future",

"Title": "Action not authorized",

"Priority": 2,

"Date": "2026-01-19T15:24:05.446649",

"OperationId": "50545b3f8c333e4b58584d465f7c2b24"
Missing attribute400715"Code": 715,

"ErrorMessage": "Paramètre(s) d'appel invalide(s). 'Signature Date' must not be empty.",

"Title": "L'opération ne peut pas aboutir",

"Priority": 2,

"Date": "2026-01-19T15:24:38.8877232",

"OperationId": "543aee3040f2235e9aaf2c0e4c869ca8",

"ErrorDetails": null



Error for a SDD OUT creation

POST /api/v2.0/sepa-direct-debits


Use caseSDD created ?HTTP codeCodeResponse
Incorrect executionDateNo400715"Code": 715,

"ErrorMessage": "Paramètre(s) d'appel invalide(s). expectedExecutionDate must be at least D+3.",
"Title": "L'opération ne peut pas aboutir",

"Priority": 2,

"Date": "2026-01-20T08:57:03.8992613",

"OperationId": "f89f6741f26c32624eb6a794200722ed",

"ErrorDetails": null
Yes400362"Code": 362,

"ErrorMessage": "Opération non autorisée",

"Title": "",

"Priority": 2,

"Date": "2026-01-20T08:57:38.4384898",

"OperationId": "3ac7316c5d414a362986136b9609faa8"
Missing or wrong attributeNo400715"Code": 715,

"ErrorMessage": "Paramètre(s) d'appel invalide(s). XXX is empty or invalid",

"Title": "L'opération ne peut pas aboutir",

"Priority": 2,

"Date": "2026-01-20T08:58:40.9090588",

"OperationId": "d145bcaf831e4c444d376bb209ac41a8",

"ErrorDetails": null
Account does not existNo400147"Code": 147,

"ErrorMessage": "Account does not exist",

"Title": "The operation cannot succeed",

"Priority": 2,

"Date": "2026-01-20T08:58:57.998904",

"OperationId": "ec6a66461e94d7b1c0bd381edb5a24c9"
Id already usedNo400710"Code": 710,

"ErrorMessage": "Operation with sepaDirectDebitId already exists for the partner xxx.",

"Title": "The operation cannot succeed",

"Priority": 2,

"Date": "2026-01-20T08:59:55.2351466",

"OperationId": "72b22b68815cbb2aa464d3c010bbc003"
Mandate type mentionned is not the same than the one in the mandate4002"Code": 2,

"ErrorMessage": "SddType (Core) is not compatible with MandateType (B2B)",

"Title": "Action not authorized",

"Priority": 2,

"Date": "2026-01-20T09:27:07.7111877",

"OperationId": "67ed9b7fec9ffb97b790d82dbd1344bc"

Error for a get sdd

GET /v2.0/sepa-direct-debits/sepaDirectDebitId


Use caseHTTP codeCodeResponse
Wrong request400715"Code": 715,

"ErrorMessage": "Paramètre(s) d'appel invalide(s). MandatePublicId must be a valid and non-empty GUID",

"Title": "L'opération ne peut pas aboutir",

"Priority": 2,

"Date": "2026-01-20T09:00:49.6467942",

"OperationId": "abe2e5f26f47169468a935a833c1a4d0",

"ErrorDetails": null

R-transactions

Some direct debit transactions require exception handling, because one of the parties involved does not or cannot process the collection in the
normal way. This exception handling involves the sending of messages called R-transactions because their names all start with an R: Refusals,
Rejects, Returns, Refunds, Reversals. The definitions of the various SDD R-transactions are outlined this document :

🔗https://www.europeanpaymentscouncil.eu/sites/default/files/kb/file/2024-11/EPC173-14%20v8.0%20Guidance%20on%20Reason%20Codes%20for%20SDD%20R-transactions.pdf

General scheme

sequenceDiagram
Participant Before
Participant D-14
Participant D-1 bank business day
Participant D Payment Date
Participant D5 bank business day
Participant D8 weeks
Participant D13 months

Before -->> D-1 bank business day: Revocation by creditor
D-14 -->> D Payment Date: Request for cancellation from creditor's bank
D-14 -->> D Payment Date: Reject from the debitor's bank
D-14 -->> D Payment Date: Refusal from the debitor's bank

D Payment Date -->> D5 bank business day : Reversal by Creditor
D Payment Date -->> D5 bank business day : Return
D Payment Date -->> D8 weeks : Request for refund
D8 weeks -->> D13 months : Request for refund for <br/>an unauthorized transaction
  • Reject example: account closed
  • Refusal by debtor example: the user debited by the SDD OUT refused
  • Reversal by creditor example: external bank debit error.
  • Return example: insufficient balance

General sequence diagram

👍

In the case of a reject or a refusal the day or after the paymentDate, a new operation is created: this operation is named R-transaction.

Each of these two operations has an independent status diagram, but the R-transaction is linked to the original operation through the field refundReference.

Case refund after the payment date

sequenceDiagram
Title: R-transaction for a completed SDD OUT
autoNumber
Participant Partner
Participant XPO
Participant External_bank


Partner -->> XPO : SDD OUT
XPO -->> External_bank: SDD OUT
XPO -->> Partner: Webhook SepaDirectDebitCreatedOrUpdate {sepaDirectDebitId: X status 'Completed'}

Note over Partner, External_bank : Refund
External_bank -->> XPO: R-transaction refund
XPO -->> Partner: SepaDirectDebitCreatedOrUpdate {isRTransaction:true, status:'Completed', relatedSepaDirectDebitId:X}

The initial operation:

  • has a status Completed
  • has the refund reference in the attribute relatedSepaDirectDebitId

The refund operation

  • isRTransaction
  • has a status Completed
  • has the reference of the initial operation in the attribute relatedSepaDirectDebitId

Case reject or refusal before the payment date

sequenceDiagram
Title: R-transaction for a rejected SDD OUT
autoNumber
Participant Partner
Participant XPO
Participant ESP

Note over Partner, ESP : X days before payment date
Partner -->> XPO : SDD OUT
XPO -->> ESP: SDD OUT
ESP -->> XPO: ok
XPO -->> Partner: Webhook SepaDirectDebitCreatedOrUpdate {sepaDirectDebitId:X, status 'Approved'}

Note over Partner, ESP : Rejected
ESP -->> XPO: Reject
XPO -->> Partner: SepaDirectDebitCreatedOrUpdate {sepaDirectDebitId:X, status 'Rejected'}

ESP = Sepa Exchanger


sepaRejectCode & sepaRejectReason

These attributes are visible in the webhook SepaDirectDebitCreatedOrUpdate.

They are filled when the SDD is refused and a R-transaction

Please referee to this link, page 5, to find all code, definition and associated use cases.

🔗https://www.europeanpaymentscouncil.eu/sites/default/files/kb/file/2024-11/EPC173-14%20v8.0%20Guidance%20on%20Reason%20Codes%20for%20SDD%20R-transactions.pdf



Did this page help you?