Stripe, Adyen and GoCardless all support SEPA Direct Debit, but none of them will collect under the B2B scheme, and Mollie doesn't document it either. That matters more than it sounds. B2B is the version where the payer cannot claw the money back, and if you sell to businesses you have probably been told it exists, that it is safer, and that you should "just switch it on". Through a PSP API, in 2026, you can't.
The guides that rank for "SEPA Direct Debit Core vs B2B" are written for finance teams: Core is for consumers, B2B is for companies, B2B has no refund. That's accurate, and it won't help you write the code that handles an MD06 return seven weeks after you shipped the goods. This guide works from the European Payments Council's 2025 rulebooks and implementation guidelines (in force since 5 October 2025), Regulation (EU) 260/2012 and PSD2, and the current developer docs of four PSPs.
What Is the Difference Between SEPA Direct Debit Core and B2B?
They are two separate EPC schemes with two separate rulebooks. They share the mandate model and the ISO 20022 messages, and the differences sit almost entirely in who can reverse a collection and when.
| SDD Core | SDD B2B | |
|---|---|---|
| Rulebook | EPC016-06, 2025 v1.0 | EPC222-07, 2025 v1.0 |
| Who can be the payer | Consumers and businesses | Non-consumers only |
| Refund of an authorised debit | Yes, 8 weeks, no questions asked | No |
| Refund of an unauthorised debit | 13 months | 13 months, not recoverable from the creditor's PSP |
| Debtor bank checks the mandate | No | Yes, against the debtor's confirmation, every collection |
| Latest presentation | D-1 inter-PSP business day | D-1 inter-PSP business day |
| Return window (debtor PSP) | D+5 inter-PSP business days | D+3 inter-PSP business days |
| PSP API support (Stripe, Adyen, GoCardless) | Yes | No |
Core accepts business accounts too. Stripe's docs spell it out: the Core scheme "supports both business and personal bank accounts". So the choice is never "Core for consumers, B2B for companies". The real choice is whether you can get your business customers to do the extra work B2B requires, and whether your bank will sponsor you for it.
How Long Does a SEPA Direct Debit Take? D-1, D+5 and the 14-Day Window
Since rulebook v9.0 took effect in November 2016, every collection type, first, recurrent and one-off, must reach the debtor's PSP by D-1, one inter-PSP business day before the due date. Before 2016, first and one-off collections needed five days and recurrent ones two. A lot of integration code written in that era still carries the old lead times.
You can present a collection no earlier than 14 calendar days before the due date. Separately, you owe the payer a pre-notification at least 14 calendar days ahead unless you agree a shorter period with them. Most PSP mandate texts shorten it. Stripe's allows the notice to go out as late as two calendar days before the debit, and Adyen's docs ask for "at least one day".
The 2016 change also made FRST optional. A first collection can go out as RCUR, and a FRST collection "is processed as a recurrent Collection". The sequence type is still a mandatory field in pacs.003, with the four codes FRST, RCUR, FNAL and OOFF, so you still have to send one. The value just no longer changes the timeline.
What the payer experiences is much slower than D-1. Stripe's cut-off is 10:30 CET, and it tells you to "wait at least 6 business days before considering a SEPA Direct Debit payment as successful". Mollie holds settlement for 9 business days. GoCardless submits two working days before the charge date and pays out about six working days after submission. Plan for about a week between "created" and "safe to treat as paid", and then eight more weeks before a Core debit is truly final.
SEPA Direct Debit Refund Rules: 8 Weeks vs 13 Months
There are two clocks, and they come from different legal sources.
The 8-week right comes from PSD2 Article 76(1), which gives the payer an "unconditional right to a refund" for direct debits under Regulation 260/2012, and Article 77(1), which sets the window from the debit date. The Core rulebook turns that into a no-questions-asked refund. The payer's bank refunds them and recovers the money from your PSP, which recovers it from you.
The 13-month window is for unauthorised debits, meaning no valid mandate exists. It comes from PSD2 Article 71. This one requires the payer to claim the debit was not authorised, and in theory you can show a mandate. In practice:
- Stripe: SEPA disputes "are final and there is no process for appeal".
- Adyen: "You cannot defend SEPA chargebacks." Its webhook carries
defendable: "false". - German payers: Stripe notes their disputes arrive without a reason, for privacy.
SEPA Mandate Requirements: UMR, Creditor ID and the 36-Month Rule
A mandate is identified by the pair (Unique Mandate Reference, Creditor Identifier). Three details catch people out.
The UMR length limit lives in the implementation guideline, not the rulebook. The rulebook "does not limit the length", butMndtId in the XML is Max35Text. It is case-insensitive. Allowed characters are a-z A-Z 0-9 / - ? : ( ) . , ' + and space, and it must not start or end with / or contain //. Uniqueness is per Creditor Identifier, ignoring the business code. Mollie warns that "some banks will decline Direct Debit payments if the mandate reference is not unique", so don't reuse a customer ID as the UMR if a customer can hold two mandates.
The Creditor Identifier has a checksum. The format is country code, two check digits, a three-character business code (ZZZ if unused), then up to 28 characters of national ID. The check digits use ISO 7064 MOD 97-10 computed over the national part plus the country code plus 00, with the business code ignored. A validator takes ten lines:
function validCreditorId(ci: string): boolean {
const s = ci.replace(/\s/g, "").toUpperCase();
const national = s.slice(7).replace(/[^A-Z0-9]/g, "");
const digits = (national + s.slice(0, 2) + s.slice(2, 4))
.replace(/[A-Z]/g, (c) => String(c.charCodeAt(0) - 55));
let rem = 0;
for (const d of digits) rem = (rem * 10 + Number(d)) % 97;
return rem === 1;
}
Mandates die after 36 months of silence. If no collection has been presented for 36 months, the creditor must cancel the mandate. The clock runs from the latest collection, and a rejected, returned or refunded one still counts. The UK equivalent is a 24-month dormancy rule at the paying bank. If you run annual subscriptions with long pauses, store last_presented_at per mandate and expire it yourself. Otherwise the payer's bank will reject you with MD01.
Changing the IBAN does not require a new mandate. Set AmdmntInd to true and fill AmdmntInfDtls. If the payer moved to a different bank, the original debtor account is sent as the literal string SMNDA ("same mandate, new debtor account"). Get this wrong and the first collection after the change bounces.
You also probably aren't the creditor on paper. Stripe uses its own Creditor ID by default, Adyen uses NL48ZZZ342764500000 unless Support configures yours, and GoCardless offers both. That's convenient until you migrate PSPs: mandates belong to a Creditor ID, so if you collected under the PSP's ID, those mandates can't come with you. Stripe also says you can't change the Creditor ID after live payments. Decide this on day one.
SEPA Direct Debit Return Codes: AM04, MD06, MS02 and the Rest
The EPC uses six R-transaction types. Your code will see three of them: rejects, returns and refunds.
| R-type | Raised by | Deadline | Message |
|---|---|---|---|
| Reject | Any party, before settlement | Before settlement | pacs.002 (RJCT) |
| Return | Debtor PSP, after settlement | Core D+5, B2B D+3 | pacs.004 |
| Refund | Debtor (Core only for authorised debits) | 8 weeks / 13 months | pacs.004 |
| Reversal | Creditor, after settlement | 5 inter-PSP business days after due date | pacs.007 |
| Refusal | Debtor | Becomes a reject or a return | pacs.002 / pacs.004 |
| Revocation / cancellation request | Creditor or its PSP | Before settlement | Bilateral, not in the scheme |
camt.056 does not appear in the Core inter-PSP guideline at all. If you're coming from SEPA Instant recalls, unlearn that. The collection itself goes PSP-to-PSP as pacs.003. You submit it to your bank as pain.008, the direct-debit sibling of the pain.001 covered in my ISO 20022 message guide.
The reason codes that drive retry logic, with GoCardless's documented mapping:
| SEPA code | Meaning | GoCardless cause | Retry? |
|---|---|---|---|
AM04 | Insufficient funds | insufficient_funds | Yes, after payday |
MS02 | Debtor refused | refer_to_payer | Ask first |
MS03 | Reason not specified | refer_to_payer | Once, cautiously |
SL01 | Debtor bank blocks DDs / creditor | refer_to_payer | No, needs the payer |
AC04 | Account closed | bank_account_closed | No, new mandate |
AC01 | Invalid IBAN | invalid_bank_details | No |
AC06 / AG01 | Account blocked / DD not allowed | direct_debit_not_enabled | No |
MD01 | No valid mandate | mandate_cancelled | No, mandate is dead |
MD06 | Refund requested (Core) | charged_back / refund_requested | Never auto-retry |
MD07 | Debtor deceased | bank_account_closed | No |
AC13 | Debtor is a consumer (B2B only) | n/a | Switch to Core |
Two warnings. Adyen notes that MS03 "can replace other reason codes (AC04 and AM04...)" for data-protection reasons, so a large share of your MS03 traffic is really insufficient funds or a closed account. And SL01 typically means the payer used their Regulation 260/2012 Article 5(3)(d) right to block your Creditor ID or cap the amount. Retrying it wastes your failed-payment fee and annoys the customer.
Stripe exposes 13 failure_code values for sepa_debit (insufficient_funds, debit_not_authorized, account_closed, refer_to_customer and so on) but doesn't publish its mapping from SEPA codes. Mollie is the most transparent: its payment object carries the raw bankReasonCode and bankReason. If you need scheme-level analytics, that difference matters.
Stripe vs GoCardless vs Adyen vs Mollie for SEPA Direct Debit
| Stripe | GoCardless | Adyen | Mollie | |
|---|---|---|---|---|
| B2B scheme | No | No (sepa_core only) | No | Not documented |
| Mandate object | Mandate, status active/inactive/pending | Mandate, 10 statuses incl. suspended_by_payer, expired | None; additionalData.sepadirectdebit.mandateId = original pspReference | Mandate, status valid/pending/invalid |
| Default per-payment cap | €10,000 (plus €10,000/week for new accounts) | Not published | €500 | €1,000 |
| Price (EU) | €0.35 | 1% + €0.20, capped at €2 | Not checked | €0.35 |
| Dispute / failure fee | €15.00 / €3.50 | Not checked | Not checked | Not published |
| Raw SEPA reason code exposed | No | Mapped to cause | Yes, chargebackReasonCode | Yes, bankReasonCode |
| Who sends pre-notification | Stripe, by default | GoCardless, ~3 days ahead | You | You |
Prices are from each PSP's Irish or French page, read on 3 October 2026. The trade-off is clear enough. GoCardless is the most direct-debit-native: richest mandate lifecycle, best-documented reason mapping, and percentage pricing that costs more than Stripe's flat €0.35 on any debit above €15, up to the €2 cap that applies from €180. Stripe gives a flat €0.35 and the easiest integration if you already take cards, but it hides the scheme codes and charges €15 per dispute, which on an 8-week no-questions refund is a cost you cannot contest. Adyen reports refunds and returns as CHARGEBACK webhooks with the scheme code intact, but its €500 default cap will surprise anyone billing annual B2B contracts. Mollie has the best raw data and needs a first payment through iDEAL or Bancontact to create the mandate.
SEPA Direct Debit vs Bacs Direct Debit in the UK
If you run both, as most UK companies with EU customers do, the models differ in the places that matter for code.
| SEPA Core | Bacs Direct Debit | |
|---|---|---|
| Payer refund window | 8 weeks unconditional, 13 months unauthorised | Unlimited (Direct Debit Guarantee) |
| Advance notice to payer | 14 calendar days unless agreed | 10 working days unless agreed |
| Mandate dormancy | 36 months, creditor must cancel | 24 months at paying bank |
| Cycle | D-1 presentation | 3-day file cycle |
| Message format | ISO 20022 XML | Bacs Standard 18 |
| Failure reporting | pacs.002 / pacs.004 reason codes | ARUDD, ADDACS, AUDDIS |
The refund window is the big one. A SEPA Core debit is final after 13 months even in the worst case. A Bacs debit never is. I covered the Bacs side in detail in the Faster Payments vs Bacs vs CHAPS guide. The practical point is that your dispute-reserve logic needs a per-scheme horizon, not one global "chargeback window" constant.
SEPA Direct Debit Changes in 2026 and 2027
15 November 2026: unstructured addresses end. Originally 22 November, the date moved in October 2025 to line up with the Swift MX release. After the cut-off (measured against the inter-PSP settlement date) a debtor or creditor address must be structured or hybrid: structured elements with at most two 70-characterAdrLine entries, and Ctry plus TwnNm always mandatory. If your mandate capture stores addresses as one free-text blob, fix it now.
There is no 2026 rulebook. The next SDD rulebooks are 2027 editions, due for publication in November 2026 and taking effect in November 2027. The EPC consultation (13 March to 11 June 2026) recommended extending the name field to 140 characters, a new fraud reason code FR01 for rejects and returns, and a FRAD code for refunds. It rejected shortening the cycle from D-1 to same-day and rejected letting the creditor's PSP contest unauthorised-refund claims. Those are recommendations, not final decisions, but the direction is clear: more fraud signalling, the same consumer protection.
What does not apply: the Instant Payments Regulation's Verification of Payee covers credit transfers only. SDD gets no name-check on the IBAN.
My View: SEPA B2B Will Stay a Bank-Only Product
My prediction: no major PSP will expose SDD B2B through a self-serve API before the 2029 rulebooks, and payment teams should stop planning for it.
The reason is the debtor-side work. B2B only works if the payer registers each mandate with their own bank before the first collection, and the bank then checks every debit against it. That's a manual step for the customer's finance team, and it fails silently into an MD01 or AC13 if skipped. PSPs make their margin on fast onboarding, and B2B onboarding is slow by design. The volume doesn't justify it either: the ECB counted 11.7 billion euro-area direct debits in H2 2025, about 14% of non-cash payments, and the bulk is utilities, telcos and insurance collected under Core.
The defensible route for B2B is a direct bank relationship: your own Creditor ID, pain.008 files to a sponsoring bank, and a customer-success process that walks payers through mandate registration. For most SaaS companies, Core plus good reason-code handling will cost less than building that.
What This Means for Engineers Collecting Euros
1. Model the mandate as its own entity, keyed on (UMR, Creditor ID), with signed_at, last_presented_at and creditor_id_owner. Expire it yourself at 36 months of inactivity.
2. Decide whose Creditor ID you collect under before your first live debit. Collecting under the PSP's ID locks your mandates to that PSP.
3. Treat "succeeded" as provisional for 8 weeks and "final" only after 13 months. Ship goods on settlement only if the goods are recoverable or cheap.
4. Branch retry logic on the reason code: retry AM04 after a likely payday, never auto-retry MD06, MD01, AC04 or SL01. Stripe caps you at 2 retries in 30 days anyway.
5. Validate the Creditor ID checksum and the UMR character set at mandate creation, not at first collection.
6. Structure your address capture before 15 November 2026.
7. Keep dispute reserves per scheme: 8 weeks for SEPA Core, open-ended for Bacs, and use idempotency keys on every collection call so a retried pain.008 never debits twice.
Direct debit is the cheapest way to collect recurring euros, at €0.35 a debit against a card's percentage. The cost is in the edge cases, and they're all written down in the rulebook if you go and read it. I'm Tom Wang, and I write these guides from the primary documents so you don't have to.