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

# Collect payments with SEPA Direct Debit

> Collect payments with SEPA Direct Debit from your customers

SEPA Direct Debit (SDD) lets you collect payments directly from your customers' bank accounts — no manual action required in the Qonto app. With the SDD Collection API, you can automate your entire receivables workflow: create mandates, trigger one-off collections, and track outcomes in real time.

This is particularly useful if you:

* Issue invoices from an external tool (e.g. an ERP or invoicing platform) and want to trigger SDD collections programmatically
* Build a direct debit payment method into your own product on top of Qonto

This guide walks you through the available API endpoints and how to integrate them into your business operations.

<Note>To use the API, you must be eligible for SEPA Direct Debit and have the feature activated in the Qonto app. Go to Business Account → Incoming Direct Debits to check your eligibility and create your SCI (SEPA Creditor Identifier).</Note>

***

## How SDD collection works

### 1. Authenticate with the right scopes

All SDD endpoints are protected by OAuth 2.0. Request the following scopes depending on the operations you need:

| Scope                     | Access                                        |
| ------------------------- | --------------------------------------------- |
| `sepa_direct_debit.read`  | Read mandates, subscriptions, and collections |
| `sepa_direct_debit.write` | Create mandates and subscriptions             |

You can manage your OAuth credentials from the [Developer Portal](https://developers.qonto.com).

***

### 2. Create a mandate

A mandate is the authorization from your customer (the debtor) to collect payments from their bank account. You must have a valid, signed mandate before collecting any payment.

To create a mandate, send a `POST` request to `/v2/sepa/direct_debit_mandates`. The `payment_info` object is optional; when provided, it stores the first payment details on the mandate and is used for the signature request and for the approval flow (e.g. for creating or scheduling the first collection once the mandate is signed).

Minimal request (mandate only):

```json theme={null}
{
  "direct_debit_mandate": {
    "client_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
  }
}
```

You can omit `payment_info` to create only the mandate. To attach first payment details and use them for the signature request and approval flow, include the optional `payment_info` object. To have a collection run after the customer signs, create a subscription via `POST /v2/sepa/direct_debit_subscriptions` referencing the mandate and the same payment details.

Example with `payment_info`:

```json theme={null}
{
  "direct_debit_mandate": {
    "client_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "payment_info": {
      "first_payment": {
        "collection_date": "2026-01-01",
        "amount": { "value": "250.00", "currency": "EUR" },
        "reference": "INV-2025-001"
      },
      "notify_client": true,
      "schedule_type": "one_off"
    },
    "send_mandate_signature_email": true
  }
}
```

When `payment_info` was provided in the request, the response includes a `sign_url` — a link your customer must visit to sign the mandate electronically. You can send this URL yourself or have Qonto send the signature request email automatically by setting `send_mandate_signature_email: true`. If `payment_info` was omitted, `sign_url` is not returned.

```json theme={null}
{
  "direct_debit_mandate": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "unique_mandate_reference": "UMR-...",
    "client_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "status": "pending_signature",
    "schedule_type": "one_off",
    "notify_client": true,
    "sign_url": "https://...",
    "created_at": "2026-01-01T10:00:00Z"
  }
}
```

When `payment_info` was included in the request, the response includes `schedule_type` and `notify_client`.

Once your customer signs, you will receive a `v1/sepa-direct-debit-mandates` webhook with event `accepted` (see [Webhooks](#webhooks) below). You can also poll the mandate status with a `GET` request to `/v2/sepa/direct_debit_mandates/{direct_debit_mandate_id}`.

You can list all mandates for a given client by sending a `GET` request to `/v2/sepa/direct_debit_mandates?client_id={client_id}`.

***

### 3. Create a subscription

A subscription represents a one-off payment request against a mandate. Once you have a signed mandate, you can trigger a subscription at any time.

Send a `POST` request to `/v2/sepa/direct_debit_subscriptions`:

```json theme={null}
{
  "direct_debit_subscription": {
    "client_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "direct_debit_mandate_id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "bank_account_id": "497f6eca-6276-4993-bfeb-53cbbbba6f09",
    "initial_collection_date": "2026-01-01",
    "amount": { "value": "250.00", "currency": "EUR" },
    "reference": "INV-2025-001",
    "notify_client": true,
    "schedule_type": "one_off"
  }
}
```

**Using an existing mandate**: provide the `direct_debit_mandate_id` as shown above.

**Creating a mandate and collection in one step**: omit `direct_debit_mandate_id`. A new mandate will be created automatically and the response will include a `sign_url`.

You can retrieve a specific subscription with a `GET` request to `/v2/sepa/direct_debit_subscriptions/{direct_debit_subscription_id}`, or list all subscriptions with `GET /v2/sepa/direct_debit_subscriptions`.

***

### 4. Track collection outcomes

Once a subscription has been triggered, Qonto processes it through the SEPA banking network. You can track the outcome in two ways:

**Webhooks (recommended):** subscribe to `v1/sepa-direct-debit-collections` to receive real-time notifications when a collection status changes (see [Webhooks](#webhooks) below).

**Polling:** retrieve a collection by ID with a `GET` request to `/v2/sepa/direct_debit_collections/{direct_debit_collection_id}`, or list all collections — optionally filtered by subscription — with `GET /v2/sepa/direct_debit_collections?direct_debit_subscription_id={id}`.

```json theme={null}
{
  "direct_debit_collection": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "direct_debit_subscription_id": "497f6eca-6276-4993-bfeb-53cbbbba6f09",
    "amount": { "value": "250.00", "currency": "EUR" },
    "collection_date": "2026-01-01",
    "status": "completed",
    "unique_mandate_reference": "UMR-..."
  }
}
```

***

## Mandate statuses

| Status              | Description                                                     |
| ------------------- | --------------------------------------------------------------- |
| `pending_signature` | The mandate has been created but not yet signed by the customer |
| `approved`          | The mandate has been signed and is ready to use for collections |

***

## Collection statuses

| Status      | Description                                                                                           |
| ----------- | ----------------------------------------------------------------------------------------------------- |
| `pending`   | The collection has been scheduled and is awaiting processing                                          |
| `completed` | The payment was successfully collected and settled                                                    |
| `declined`  | The collection was declined before processing                                                         |
| `rejected`  | The collection was rejected during processing                                                         |
| `canceled`  | The collection was canceled                                                                           |
| `returned`  | The payment was reversed by the debtor's bank (typically up to D+5 after settlement)                  |
| `refunded`  | The payment was reversed following a request by the debtor (typically up to 8 weeks after settlement) |

When a collection fails, the `status_reason` field provides additional detail (e.g. `insufficient_funds`, `amount_limit_reached`, `account_closed`). The full list of allowed values is documented in the API reference.

***

## Webhooks

Subscribe to webhook topics to receive real-time notifications about key events. The `event` field in the webhook payload body identifies what happened.

### `v1/sepa-direct-debit-mandates`

| Event      | Description                                 |
| ---------- | ------------------------------------------- |
| `accepted` | The mandate has been signed by the customer |

Example payload:

```json theme={null}
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "organization_id": "123e4567-e89b-12d3-a456-426614174000",
  "type": "v1/sepa-direct-debit-mandates",
  "created_at": "2026-01-01T10:55:00Z",
  "data": {
    "event": "accepted",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "unique_mandate_reference": "UMR-...",
    "status": "approved",
    "mandate_signature_date": "2026-01-01T10:54:00Z"
  }
}
```

### `v1/sepa-direct-debit-collections`

| Event       | Description                                                                                                                                                       |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `completed` | The payment was successfully collected and settled                                                                                                                |
| `failed`    | The collection did not succeed. Check `data.status` for the fine-grained reason (`declined`, `rejected`, or `canceled`) and `data.status_reason` for more details |
| `returned`  | The payment was reversed by the debtor's bank, typically within D+5 of settlement                                                                                 |
| `refunded`  | The payment was reversed at the debtor's request, typically up to 8 weeks after settlement                                                                        |

> **Tip:** The `event` field uses a simplified set of outcomes (`completed`, `failed`, `returned`, `refunded`). For `failed` events, `data.status` retains the fine-grained value (`declined`, `rejected`, or `canceled`) so you can handle each case precisely.

Example payload (failed):

```json theme={null}
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "organization_id": "123e4567-e89b-12d3-a456-426614174000",
  "type": "v1/sepa-direct-debit-collections",
  "created_at": "2026-01-01T10:55:00Z",
  "data": {
    "event": "failed",
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "direct_debit_subscription_id": "497f6eca-6276-4993-bfeb-53cbbbba6f09",
    "amount": { "value": "250.00", "currency": "EUR" },
    "reference": "INV-2025-001",
    "status": "rejected",
    "status_reason": "insufficient_funds"
  }
}
```

***

## Summary

Here are the steps to follow when integrating SDD collection:

1. **Request the right OAuth scopes**: `sepa_direct_debit.read` and/or `sepa_direct_debit.write` from the Developer Portal
2. **Create a mandate**: `POST /v2/sepa/direct_debit_mandates` — share or send the `sign_url` to your customer
3. **Wait for mandate acceptance**: subscribe to `v1/sepa-direct-debit-mandates` webhooks, or poll `GET /v2/sepa/direct_debit_mandates/{id}`
4. **Create a subscription**: `POST /v2/sepa/direct_debit_subscriptions` with the signed mandate ID, amount, and collection date
5. **Track the outcome**: subscribe to `v1/sepa-direct-debit-collections` webhooks, or poll `GET /v2/sepa/direct_debit_collections/{id}`

| Step                     | Endpoint                                            |
| ------------------------ | --------------------------------------------------- |
| Create a mandate         | `POST /v2/sepa/direct_debit_mandates`               |
| Get a mandate            | `GET /v2/sepa/direct_debit_mandates/{id}`           |
| List mandates            | `GET /v2/sepa/direct_debit_mandates?client_id={id}` |
| Create a subscription    | `POST /v2/sepa/direct_debit_subscriptions`          |
| Get a subscription       | `GET /v2/sepa/direct_debit_subscriptions/{id}`      |
| List subscriptions       | `GET /v2/sepa/direct_debit_subscriptions`           |
| Get a collection outcome | `GET /v2/sepa/direct_debit_collections/{id}`        |
| List collection outcomes | `GET /v2/sepa/direct_debit_collections`             |
