Adding SEPA Direct Debit to a Subscription Product
SEPA Direct Debit is the default way European consumers and small businesses pay for recurring services, and it behaves almost nothing like a card. There is no authorisation, no decline code, and no immediate answer — you submit an instruction, wait several business days, and find out later whether the money arrived or came back. This guide sits under Alternative Payment Methods & Local Rails and covers what has to change in a card-shaped billing system before the first mandate is collected.
The reason to bother is straightforward: in markets where direct debit is normal, it converts better than cards at signup and fails less at renewal, because there is no expiry date and no issuer decline. The reason to be careful is equally straightforward: the customer can reclaim a consumer debit for eight weeks with no justification required, and thirteen months if they claim it was unauthorised.
Trade-offs
| Property | Card | SEPA Direct Debit |
|---|---|---|
| Outcome latency | Seconds | 2–5 business days |
| Failure taxonomy | Issuer decline codes | Scheme return reason codes |
| Customer reclaim window | Chargeback, 120+ days | 8 weeks unconditional, 13 months unauthorised |
| Recurring authorisation | Stored credential | Mandate with a unique reference |
| Expiry | Card expiry date | Dormancy after 36 unused months |
| Cost per transaction | Percentage of value | Typically a small fixed fee |
The fixed per-transaction fee changes unit economics in a useful direction for higher-value subscriptions and an unhelpful one for very small amounts. A €9 monthly plan on direct debit can cost proportionally more than the same plan on a card once return fees are included, so the rail is usually offered above a price threshold rather than universally.
Step-by-Step Implementation
1. Collect the mandate with its evidence
The mandate is a legal authorisation, and the evidence for it is what you will produce if the customer later claims it was never given. Capture the exact wording shown, the timestamp, and the originating address.
INSERT INTO payment_mandates
(customer_id, rail, provider_mandate_ref, status,
accepted_at, acceptance_ip, acceptance_text)
VALUES
($1, 'sepa_debit', $2, 'pending', now(), $3,
'By providing your IBAN and confirming this payment, you authorise '
|| $4 || ' and your bank to debit your account. You are entitled to a refund '
|| 'from your bank under the terms of your agreement with your bank, '
|| 'which must be claimed within 8 weeks starting from the debit date.');
Storing the wording as data rather than referencing a template version means a later change to the checkout copy cannot retroactively alter what a past customer is recorded as having agreed to.
2. Send the pre-notification
The scheme requires the customer to be told the amount and date before the debit is taken, with a notice period that the creditor declares — commonly reduced from fourteen days to two by agreement. For a subscription with a stable amount, an annual notification covering the schedule satisfies this; for variable amounts, each debit needs its own notice.
Practically, this means the renewal email is not a courtesy. It is a scheme obligation, and a debit taken without it is challengeable on process grounds regardless of whether the customer owed the money.
3. Treat the debit as processing
// The charge call returns 'processing', not success. Provision on it deliberately.
const result = await provider.chargeOffSession({
providerCustomerId, paymentMethodRef: mandateRef,
amountMinor: invoice.amountDue, currency: "EUR",
idempotencyKey: `inv:${invoice.id}:attempt:${invoice.attemptCount}`,
invoiceId: invoice.id,
});
if (result.status === "processing") {
await invoices.markProcessing(invoice.id, result.chargeRef);
await entitlements.grantProvisional(invoice.accountId); // service starts now
await metrics.increment("sepa.debit.submitted");
}
Provisioning on processing is the pragmatic choice — nobody waits five days for access — but it should be a recorded decision with a risk position attached, not an accident of reusing the card code path. Track the value of unsettled provisioned service as a metric; it is the exposure you are carrying.
4. Handle returns
5. Refresh dormant mandates
-- Mandates approaching the 36-month dormancy limit.
SELECT mandate_id, customer_id, last_used_at
FROM payment_mandates
WHERE rail = 'sepa_debit' AND status = 'active'
AND coalesce(last_used_at, accepted_at) < now() - INTERVAL '33 months';
Three months of margin is enough to run a re-collection campaign without urgency. The accounts most likely to appear here are annual subscribers who paused, which is exactly the cohort where a failed renewal is most costly.
Provisioning Policy and Risk Position
The decision to grant service before settlement is a credit decision, and it deserves the same explicitness a credit decision gets elsewhere. Three levers shape it.
The first is amount. A €19 monthly plan carries trivial exposure; a €4,800 annual prepayment does not. A common policy is to provision immediately below a threshold and to require settlement above it, communicated at checkout as “access begins once your first payment clears” — which customers accept readily for large amounts and resent for small ones.
The second is the customer’s history. A subscriber whose last six debits settled without incident is a materially different risk from a new signup, and the policy can reflect that: settlement-gated for the first debit, immediate thereafter. This is the arrangement most subscription products converge on, because it concentrates the caution where the uncertainty actually is.
The third is the fallback. Requiring a card alongside the mandate for the first cycle gives you an instant outcome on the risky charge and moves the customer to direct debit afterwards. It costs a little conversion at signup and removes most of the first-payment exposure, and it is worth measuring rather than assuming in either direction.
That asymmetry shapes the operational routine. Revocation cannot be polled for: banks do not notify creditors when a customer cancels a mandate on their side, so the first evidence is a debit that comes back with a mandate-related reason code. The correct response is to mark the mandate revoked immediately and route the customer to collect a new one, never to retry — a retry against a cancelled mandate is both futile and a scheme-visible event. Dormancy, by contrast, is entirely predictable from data you already hold, which is why the monthly query above is worth running even though it will return nothing for most of the year.
Whatever the policy, record the unsettled provisioned value as a first-class metric and review it monthly. It is the number that tells you whether a rising direct-debit share is quietly increasing the amount of service you are giving away to customers whose payments will come back.
Verification & Testing
Providers supply test IBANs that deterministically produce settlement, an insufficient-funds return, and a disputed reclaim. Wire all three into an integration suite that advances the provider’s test clock rather than waiting in real time, and assert the full state sequence for each: processing provisions, succeeded confirms, returned enters the rail’s grace window without revoking data access.
Test the out-of-order case explicitly. Deliver a settlement event and a return event in reverse order and assert the terminal state is returned — across a multi-day window, ordering guarantees are weak, and the version or timestamp comparison that protects you must be tested rather than assumed.
Assert the pre-notification obligation in code: a debit submitted without a recorded notification for that amount and date should fail a precondition check in a test, so that a refactor cannot quietly remove a scheme requirement. Finally, test the dormancy query with a fixture mandate at 35 and 37 months and confirm the campaign picks up the first and treats the second as lapsed.
Gotchas & Production Pitfalls
- Treating
processingas success in reporting. Revenue dashboards that count submitted debits overstate every growing month, because the returns land later. Recognise on settlement. - Reusing the card retry ladder. A retry issued before the return has been reported is rejected or, worse, succeeds and is also returned — two fees, one payment.
- Mandate reference not shown to the customer. The reference appears on their bank statement, and a customer who cannot connect it to your product is a customer who reclaims the debit as unrecognised.
- IBAN validation done only client-side. Validate the checksum server-side too; a malformed IBAN produces a rejection days later rather than an error at checkout.
- Amount changed without a fresh pre-notification. A plan upgrade that raises the debit amount needs a new notice, and skipping it makes the debit challengeable.
Frequently Asked Questions
Can I take a SEPA debit without collecting a mandate myself? Only if the provider collects it on your behalf and gives you the reference and evidence. Either way you must be able to produce the mandate details on request, so ensure the provider’s flow returns them into your own record.
What return rate should I expect? Well-run consumer subscriptions typically see a low single-digit percentage of debits returned, dominated by insufficient funds. Rates above that usually indicate a pre-notification or expectation-setting problem rather than a payments one.
Does a returned debit count as involuntary churn? Once retries are exhausted, yes, and it should be reported alongside card-driven involuntary churn. The remedies differ, though — the fix for direct debit is usually timing and communication, not smarter retry scheduling.
How do refunds work? As ordinary credit transfers back to the same account, initiated through the provider. They are not instant and they are not reversals — the original debit stays in the ledger and the refund is its own movement.