> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lyseis-pay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Automate Recurring Charges with Direct Debit Mandates

> Learn how to set up direct debit mandates, activate them with customer consent, and automatically charge customers on a recurring schedule.

Direct debit lets you pull funds from a customer's bank account on a recurring basis without requiring them to initiate each payment. The customer provides authorization once through a mandate, and you can then debit them within the agreed limits as often as needed.

The full flow is: **create a mandate → initiate activation → validate activation → debit**.

<Warning>
  You must complete the full activation flow before attempting to debit a mandate. Attempting a debit on an unactivated or cancelled mandate returns a `409` error.
</Warning>

<Steps>
  <Step title="Create a Mandate">
    Send a `POST` request to `/direct-debits/mandates` with the customer's bank details and the parameters governing future debits.

    ```json Request theme={null}
    {
      "customer_name": "Ada Lovelace",
      "customer_email": "ada@example.com",
      "account_number": "0123456789",
      "bank_code": "058",
      "mandate_reference": "mandate_123",
      "start_date": "2026-02-01",
      "end_date": "2027-02-01",
      "max_monthly_amount": 50000.00,
      "max_monthly_debit_count": 4,
      "currency": "NGN",
      "metadata": { "plan_id": "premium_monthly" }
    }
    ```

    | Field                     | Description                                                 |
    | ------------------------- | ----------------------------------------------------------- |
    | `customer_name`           | Full legal name of the account holder                       |
    | `customer_email`          | Customer's email address                                    |
    | `account_number`          | Customer's bank account number to debit                     |
    | `bank_code`               | Three-digit code of the customer's bank                     |
    | `mandate_reference`       | Your unique identifier for this mandate                     |
    | `start_date`              | Date the mandate becomes active (ISO 8601 date)             |
    | `end_date`                | Date the mandate expires (ISO 8601 date)                    |
    | `max_monthly_amount`      | Maximum total amount that can be debited per calendar month |
    | `max_monthly_debit_count` | Maximum number of debit attempts allowed per calendar month |

    <Note>
      The duration from `start_date` to `end_date` must be **at least 30 days**. Mandates with a shorter duration are rejected.
    </Note>

    A successful response returns a `mandate_reference` and an initial `status` of `pending_activation`.
  </Step>

  <Step title="Initiate Mandate Activation">
    Trigger the bank's customer verification process by sending a `POST` request to `/direct-debits/mandates/{mandate_reference}/initiate-activation`.

    ```http Request theme={null}
    POST /direct-debits/mandates/mandate_123/initiate-activation
    ```

    This call instructs the customer's bank to send them an OTP or similar challenge. The customer must receive and complete this challenge before activation can be validated in the next step.

    <Note>
      You do not need a request body for this call. The `mandate_reference` in the URL path is sufficient.
    </Note>
  </Step>

  <Step title="Validate Mandate Activation">
    Once the customer has received their OTP (and, where required, their PIN), submit the credentials to complete activation:

    ```json Request theme={null}
    POST /direct-debits/mandates/mandate_123/validate-activation

    {
      "mandate_reference": "mandate_123",
      "param1": "otp",
      "value1": "123456",
      "param2": "pin",
      "value2": "1234"
    }
    ```

    | Field               | Description                                            |
    | ------------------- | ------------------------------------------------------ |
    | `mandate_reference` | The reference of the mandate being activated           |
    | `param1` / `value1` | First credential type and its value (typically `otp`)  |
    | `param2` / `value2` | Second credential type and its value (typically `pin`) |

    A successful response changes the mandate status to `active`. Paylink also fires a `mandate_activated` webhook event to your configured endpoint.

    <Warning>
      If you try to call `validate-activation` before calling `initiate-activation`, the API returns a `409 Mandate activation needs to be initiated first` error.
    </Warning>
  </Step>

  <Step title="Debit the Mandate">
    With an active mandate in place, you can now pull funds from the customer's account. Send a `POST` request to `/direct-debits/debit`:

    ```json Request theme={null}
    {
      "mandate_reference": "mandate_123",
      "debit_amount": 1500.00,
      "narration": "Monthly subscription — February 2026",
      "customer_email": "ada@example.com",
      "payment_reference": "subscription_2026_02"
    }
    ```

    | Field               | Description                                        |
    | ------------------- | -------------------------------------------------- |
    | `mandate_reference` | Reference of the active mandate to charge          |
    | `debit_amount`      | Amount to debit in the mandate's currency          |
    | `narration`         | Description shown on the customer's bank statement |
    | `customer_email`    | Must match the email on the mandate                |
    | `payment_reference` | Your unique reference for this specific debit      |

    <Warning>
      Each `payment_reference` must be unique. Re-using a reference returns a `409 Direct debit payment already exists for the given reference` error.
    </Warning>

    <Note>
      Ensure `debit_amount` does not cause the month's total to exceed `max_monthly_amount`, and that the number of debits this month stays within `max_monthly_debit_count`.
    </Note>
  </Step>

  <Step title="Check Debit Status">
    Debit requests are processed asynchronously. Poll `GET /direct-debits/status/{payment_reference}` to check the outcome:

    ```http Request theme={null}
    GET /direct-debits/status/subscription_2026_02
    ```

    ```json Response theme={null}
    {
      "status": "success",
      "payment_reference": "subscription_2026_02",
      "mandate_reference": "mandate_123",
      "amount": 1500.00,
      "narration": "Monthly subscription — February 2026"
    }
    ```

    Paylink also fires a `direct_debit_success` (or `direct_debit_failure`) webhook event so you don't need to poll repeatedly.
  </Step>
</Steps>

## Additional Operations

### Look Up a Mandate

Retrieve the current state of any mandate at `GET /direct-debits/mandates/{mandate_reference}`:

```http Request theme={null}
GET /direct-debits/mandates/mandate_123
```

### Cancel a Mandate

To revoke a mandate, send a `PATCH` request to `/direct-debits/mandates/{mandate_reference}/cancel`:

```http Request theme={null}
PATCH /direct-debits/mandates/mandate_123/cancel
```

Once cancelled, the mandate cannot be reactivated. You must create a new mandate if you need to resume debiting the customer.

### Disbursements

After collecting funds, use `POST /direct-debits/disburse` to move money to your desired destination account. See the [Transfers guide](/guides/transfers) for details on payout flows.

## Webhook Events

| Event                  | Fired when                                           |
| ---------------------- | ---------------------------------------------------- |
| `mandate_activated`    | A mandate successfully completes the activation flow |
| `direct_debit_success` | A debit is processed and funds are received          |
| `direct_debit_failure` | A debit attempt is unsuccessful                      |
