Added

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.

  1. disabled becomes canceled to align with the SEPA and BACS terminology
  2. Mandate amendments are versioned.
  3. Stricter handling of collections on inactive mandates.
  4. Richer mandate data.
  5. Mandate review workflow

The estimated timelines for the changes deployment is provided at the end of the page.

1. canceled status replaces disabled

The status, the webhook event and the API endpoint are renamed to match SEPA and Bacs terminology.

ItemBeforeAfter
Mandate statusdisabledcanceled
Action endpointPOST /direct_debit_mandates/{id}/disablePOST /direct_debit_mandates/{id}/cancel (same behaviour)
Webhook eventdirect_debit_mandate:disableddirect_debit_mandate:canceled
Existing dataMandates in disabledMigrated to canceled

What you need to do

  1. Move calls from /disable to /cancel.
  2. Update status filters and mappings from disabled to canceled.
  3. Subscribe to direct_debit_mandate:canceled in your webhook handlers and stop relying on direct_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 active or blocked:
    1. The current mandate moves to canceled and its next_mandate_id points to the new one.
    2. A new mandate is created as a copy with your changes, version + 1, and previous_mandate_id pointing to the old one.
    3. The new mandate keeps the previous status (active or blocked).
    4. POST /direct_debit_mandates/{id} returns the new mandate id.

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 = true amends 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, expired or disabled mandate are never amended. SEPA collections are rejected with MD01. 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 id across amendments; use the id returned by the amend call or follow next_mandate_id.
  • Expect canceled webhooks on the old version when an amendment occurs, followed by an event for the new version. Do not treat these as customer-initiated cancellations. Use next_mandate_id to 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_date and last_debit_collection_date are on the mandate. Both refresh on each outgoing payment that is approved and each incoming payment that is received.
  • Collections against an expired mandate are rejected: MD01 for SEPA, ARUDD reason code 6 for Bacs.
  • New: incoming SEPA collections on expired mandates were previously accepted and are now rejected.
  • Re-activate with POST /direct_debit_mandates/{id}/authorize, optionally passing new_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_account and debtor_account support full structured address, organization_identification and private_identification (these are mutually exclusive).
  • last_debit_collection_date is 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: when false (default), a created mandate moves pending_review > active immediately, provided required fields are present (signature date, debtor information, creditor information, frequency for SEPA, reference). When true, it stays in pending_review until validated or rejected.

Lifecycle

  • pending_review becomes active (manually via POST /direct_debit_mandates/{id}/activate, or by the bank), rejected (bank or validation failure), or canceled (via POST /direct_debit_mandates/{id}/cancel, or the counterparty).
  • activate returns 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.
  • 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

ChangesTransition phaseProduction 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 canceled

ETA: Nov 17 2026
disabled status, endpoint and event is removed. canceled will be the only official status

ETA: Dec 17 2026
Versioning of amendmentsNew 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 workflowCustomers 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