---
title: "Cancel BACS mandate [beta]"
method: POST
path: "/v1/payments/bacs/directdebit/mandates/{id}/cancel"
tags: ["BACS direct debit"]
---

# Cancel BACS mandate \[beta\]

`POST /v1/payments/bacs/directdebit/mandates/{id}/cancel`

## Request

- Base URL: `https://sandbox.pismolabs.io/bacs`
- URL: `https://sandbox.pismolabs.io/bacs/v1/payments/bacs/directdebit/mandates/{id}/cancel`
- Auth: none declared. Required headers: `Authorization`

Cancel a BACS direct debit mandate.

Cancel of an existing mandate, applied asynchronously through the BACS scheme.

**Notes:**

  * The cancel is persisted with `status` = `CANCEL_PENDING` under the payer account, and enqueued for the asynchronous submission worker, which submits it to Form3 through the PSP gateway.

  * Allowed only when the mandate is in `SUBMITTED` or `CONFIRMED`; any other state is rejected with a **409 Conflict** (`EBACS0103`).

  * `version` is a Form3 optimistic-concurrency passthrough that must equal the stored version; a mismatch is rejected with a **409 Conflict** (`EBACS0104`). This call does not increment it.

  * The optional `status_reason` records why the mandate is being cancelled; it is persisted on the mandate and forwarded on the generated event.

  * This endpoint moves the mandate to `status` = `CANCEL_PENDING` and generates a [BACS mandate status changed](https://developers.pismo.io/events/docs/bacs-mandate-status-change-1) event. Subsequent status transitions generate further events (for example `CANCELLED`, `FAILED`).

## Path parameters

- `id` string, required

## Headers

- `Authorization` string, required

## Request body

- MandateCancelRequest: Payload to cancel an existing mandate. `version` is required for optimistic concurrency; `status_reason` optionally records why the mandate is being cancelled.
  - `version` integer, required: Caller's expected current mandate version. A Form3 optimistic-concurrency passthrough that must match the stored version. This call does not increment this.
  - `status_reason` 'account_closed' | 'account_transferred_to_new_psp' | 'cancelled_by_originator' | 'cancelled_by_payer' | 'payer_deceased' | 'paying_bank_cancellation': Reason code for the cancellation (mirrors Form3's mandate cancellation reasons). The client sends only the code; the human-readable description is derived server-side. * `account_closed` - Account closed * `account_transferred_to_new_psp` - Account transferred to a new PSP * `cancelled_by_originator` - Cancelled by originator * `cancelled_by_payer` - Cancelled by payer * `payer_deceased` - Payer deceased * `paying_bank_cancellation` - Paying bank cancellation

## Response `202`

Cancel intent accepted and enqueued

- MandateCancelResponse: Returned by the cancel endpoint after the pending intent is persisted.
  - `id` string: Form3-assigned mandate ID
  - `status` 'CANCEL_PENDING' | 'CANCELLED' | 'FAILED': Lifecycle status reachable when cancelling a mandate. * `CANCEL_PENDING` - Cancel intent accepted; pending submission to Form3 via the PSP gateway * `CANCELLED` - Mandate cancelled. Terminal state * `FAILED` - Cancel processing failed. Terminal state
  - `version` integer: Mandate version. This call does not change it (Form3 passthrough — not incremented).

## Other responses

- `400`: Bad Request
- `403`: Forbidden
- `404`: Not Found
- `409`: Conflict
- `500`: Internal Server Error

---

[API](https://skmtc.dev/pismo/apis/payment-rails-bacs-payments.md) - [All operations](https://skmtc.dev/pismo/apis/payment-rails-bacs-payments/llms.txt) - [OpenAPI document](https://skmtc.dev/pismo/apis/payment-rails-bacs-payments/revisions/d0f145ee1aba?raw)
