Direct Debit integration patterns

Adfin powers your full direct debit experience. Use this guide to navigate how best to get your users working with Adfin's direct debits.

Introduction

This guide explains how to manage Direct Debit mandates via the Adfin API, including creating, fetching, and scheduling mandate authorisation flows. It outlines mandate statuses, the customer signing process, UI gating patterns, and best practices for implementation, with practical examples for seamless integration.

Glossary

Quick reference if you are not used to direct debit flows or payment implementations.

  • Mandate: A customer’s authorisation that allows a business to collect Direct Debit payments from their bank account.
  • Collections: The process of automatically withdrawing funds from a customer’s bank account based on the agreed payment schedule.
  • Redirect URL: A secure link where the customer completes the mandate signing process.

Mandate Lifecycle

A mandate will have a status that refers to what the customer, or you, can do with the mandate.

StatusAdfin LabelDescription
CREATEDAwaiting SignatureMandate created, customer has not yet signed.
PENDINGSignedCustomer signed, awaiting bank confirmation
ACTIVEActiveThe bank approved the mandate, and collections can begin.
CANCELLEDNo MandateCancelled by user or bank (e.g., customer revoked via banking app).

⚠️ If cancelled by a bank, failureReason may be present. It is not human-readable and should not be displayed.



Creating mandate requests

Request

All mandates start with mandate creation. A customer will have a direct debit created against their specific customer ID. Make sure you read the mandated behaviour here.

http://api.staging.adfin.com/api/customers/id/directdebitmandates

curl --request PUT
     --url <http://api.staging.adfin.com/api/customers/{id}/directdebitmandates>
     --header 'accept: application/json
📘

Mandate behaviour

  • If the customer has a no mandate, a new one is created
  • If the customer has an active or pending mandate, no new one is created.
  • A URL is returned where the user should be redirected to complete the signing process.
  • If the mandate is cancelled a new one is generated. This allows you to support new mandate processes within Adfin. Cancellations can be user triggered, platform triggered, or bank triggered. You should be ready to be able to support new mandate signatures if they are cancelled

Response

Returns a redirectUrl which must be used to redirect the user to complete the mandate setup.

You can see the full details of the response here: https://docs.adfin.com/reference/create#/

Redirect URI: Adfin provides a redirect URI for you to send the user to; you should use this to get the mandate signed. The mandate will only moved to PENDING once the user has completed this form, it will stay in CREATED.

Next Step: Redirect the user to the URL to complete the mandate.

{
    "id": "WiGr3EBGuORksFWPEj",
    "creationTime": "2025-05-23T14:50:32.132UTC",
    "status": "CREATED",
    "customer": {
        "id": "54e2ffc3-560e-413d-aadb-bfd8f8af4de6",
        "name": "Adfin financial services Ltd",
        "people": [
            {
                "firstName": "Nathan",
                "lastName": "Hall",
                "email": "[email protected]",
                "phoneNo": "+09876543211"
            }
        ],
        "addresses": [
            {
                "city": "London",
                "postalCode": "1245",
                "country": "UK",
                "addressLine1": "Street"
            }
        ],
        "directDebitMandate": {
            "status": "CREATED"
        },
        "timezone": "Europe/London"
    },
    "url": "<https://adfin.com/dd-mandate/WiGr3EBGuORksFWPEj>",
    "sender": {
        "name": "MyNewPlatform"
    },
    "bankAccountNumber": "redacted"
}

Next Step: Redirect the user to the URL to complete mandate signing.

Fetching a Customer's Mandate

To retrieve the latest mandate status for a customer, use:

Endpoint GET /customers/id

It returns the full customer profile, and the directDebitMandate field contains the latest mandate.

Response example (includes just the relevant fields for this guide)

{
	"id": "54e2ffc3-560e-413d-aadb-bfd8f8af4de6",
	"directDebitMandate": \{
	"id": "WiGr3EBGuORksFWPEj",
	"status": "PENDING",
  "lastUpdatedTime": "2025-05-23T15:05:00Z"
}


Tips for Implementation

  • IgnorefailureReason: Only relevant for debugging cancellations by banks.
  • Label mandates based on status for consistent UI/UX.
  • Use schedule templates to automate reminders and retries.
  • Idempotent behavior: re-triggering on a customer with a valid mandate won’t create duplicates.