Direct debit mandate logic update
We are updating how direct debit (DD) mandates are managed in Mambu Payments. Today a mandate is simply registered as an agreement signed outside of the platform. The following changes aim to make the mandate lifecycle more robust, especially when a mandate is amended, and lay the foundation for managing mandates end to end with the scheme.
disabledbecomescanceledto align with the SEPA and BACS terminology- Mandate amendments are versioned.
- Stricter handling of collections on inactive mandates.
- Richer mandate data.
- Mandate review workflow
The estimated timelines for the changes deployment is provided at the end of the page.
1. canceled status replaces disabled
canceled status replaces disabled The status, the webhook event and the API endpoint are renamed to match SEPA and Bacs terminology.
| Item | Before | After |
|---|---|---|
| Mandate status | disabled | canceled |
| Action endpoint | POST /direct_debit_mandates/{id}/disable | POST /direct_debit_mandates/{id}/cancel (same behaviour) |
| Webhook event | direct_debit_mandate:disabled | direct_debit_mandate:canceled |
| Existing data | Mandates in disabled | Migrated to canceled |
What you need to do
- Move calls from
/disableto/cancel. - Update status filters and mappings from
disabledtocanceled. - Subscribe to
direct_debit_mandate:canceledin your webhook handlers and stop relying ondirect_debit_mandate:disabled
2. Mandate amendments are versioned
Amending an active or blocked mandate no longer overwrites it: the current mandate is moved to canceled and a new version is created. The new version, previous_mandate_id and next_mandate_id attributes let you trace the history.
How it works
- Mandate is
pending_review: the update is applied in place on version 1. This is not an amendment because the mandate was never active. - Mandate is
activeorblocked:- The current mandate moves to
canceledand itsnext_mandate_idpoints to the new one. - A new mandate is created as a copy with your changes,
version+ 1, andprevious_mandate_idpointing to the old one. - The new mandate keeps the previous status (
activeorblocked). POST /direct_debit_mandates/{id}returns the new mandate id.
- The current mandate moves to
New attributes: version (starts at 1), previous_mandate_id, next_mandate_id.
Editable on amendment: signature date (only while pending_review), expiry date, reference (SEPA mandates, or any mandate while pending_review), creditor information (creditor identifier on SEPA only), debtor information, custom fields, metadata.
Incoming collections (SEPA and Bacs)
- SEPA Core/B2B: a collection with amendment indicator =
trueamends the matching mandate. The original mandate is found by its current key, or by the original reference or creditor identifier supplied in the amendment details. No indicator means the existing mandate is used as-is. - Bacs and other schemes: if the mandate exists but its data differs from the collection, the mandate is amended; if nothing differs, it is used as-is.
- An amendment is applied only if it is newer than the mandate's latest version, so replaying an old file cannot restore stale data.
- Collections matching a
canceled,expiredordisabledmandate are never amended. SEPA collections are rejected withMD01. For Bacs the case is logged because there is no rejection mechanism. A collection on a mandate that was changed after the collection's file arrived is still accepted, since it was valid when received.
What you need to do
- Do not cache a mandate
idacross amendments; use the id returned by the amend call or follownext_mandate_id. - Expect
canceledwebhooks on the old version when an amendment occurs, followed by an event for the new version. Do not treat these as customer-initiated cancellations. Usenext_mandate_idto tell the two apart. - Update reconciliation or reporting that joins payments to mandates by id.
3. Stricter handling of collections on inactive mandates
Incoming SEPA collections against an expired mandate are now rejected with MD01. Previously they were accepted.
How it works
- A mandate unused for 36 months (SEPA Core/B2B) moves to
expired. For Bacs the period is a bank-level setting. expiry_dateandlast_debit_collection_dateare on the mandate. Both refresh on each outgoing payment that isapprovedand each incoming payment that isreceived.- Collections against an
expiredmandate are rejected:MD01for SEPA, ARUDD reason code 6 for Bacs. - New: incoming SEPA collections on
expiredmandates were previously accepted and are now rejected. - Re-activate with
POST /direct_debit_mandates/{id}/authorize, optionally passingnew_expiry_date(YYYY-MM-DD, capped at the scheme maximum). Returns 409 if the mandate is past its expiry and no new date is given.
What you need to do
- No action is required from you
4. Richer mandate data
Creditor and debtor details now support full structured addresses, organisation identification and private identification.
How it works
creditor_accountanddebtor_accountsupport full structured address,organization_identificationandprivate_identification(these are mutually exclusive).last_debit_collection_dateis initialised from the signature date for mandates created via the API.- Address sub-fields align with those on payments.
5. Mandate review workflow
Mandates can pass through pending_review before becoming active, with new activate and cancel actions. Existing integrations are unaffected unless you opt in.
How it works: Configuration (connected account level)
mandate_need_review: whenfalse(default), a created mandate movespending_review>activeimmediately, provided required fields are present (signature date, debtor information, creditor information, frequency for SEPA, reference). Whentrue, it stays inpending_reviewuntil validated or rejected.
Lifecycle
pending_reviewbecomesactive(manually viaPOST /direct_debit_mandates/{id}/activate, or by the bank),rejected(bank or validation failure), orcanceled(viaPOST /direct_debit_mandates/{id}/cancel, or the counterparty).activatereturns 400 listing any missing mandatory field.- Incoming mandates with
mandate_need_review = true:- SEPA Core is created
active, - SEPA B2B is created
pending_review, - Bacs is unchanged.
- SEPA Core is created
- Bacs outgoing mandates already auto-activate after 2 business days without a rejection; this logic is being generalised.
New events:
direct_debit_mandate:pending_review,direct_debit_mandate::rejected,direct_debit_mandate::active
6. Estimated timelines
| Changes | Transition phase | Production phase |
|---|---|---|
canceled rename + new cancel endpoint (deprecation notice on disable) | Both disabled and canceled events will be sent to the customer. Mandate status will be canceledETA: Nov 17 2026 | disabled status, endpoint and event is removed. canceled will be the only official statusETA: Dec 17 2026 |
| Versioning of amendments | New customers will have the versioning activated by default. Existing customers can enable this feature in sandbox ETA: Nov 17 2026 | All customers will use the versioning of amendments ETA: Dec 17 2026 |
| Review workflow | Customers decide whether the review workflow should be activated or not ETA: Nov 30 2026 | Customers decide whether the review workflow should be activated or not ETA: decision per customer |
