This guide details how to reverse or refund transfers using Moov's flexible reversals endpoint.

The reversals `POST` [endpoint](https://docs.moov.io/api/money-movement/refunds/cancel/) offers a robust solution for returning funds to a cardholder, regardless of the current state of the transfer. When possible, the reversals endpoint cancels the transfer, reversing the authorization and swiftly returning funds. If settlement is in progress or completed, a refund is issued instead. Canceling a transfer offers certain advantages over refunds, such as reducing processing costs and expediting returns to cardholders.

## Guidelines

- A reversal cannot exceed the original transfer amount
- Once requested, reversals cannot be canceled
- Avoid requesting a reversal for a payment disputed by the cardholder to prevent a potential double charge
- If a reversal request fails, you can initiate it again for the same transfer
- If a reversal includes a [surcharge](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/surcharges/), the surcharge must be specified in the request

## Initiate a reversal

Use the reversals `POST` [endpoint](https://docs.moov.io/api/money-movement/refunds/cancel/) to initiate a reversal. This endpoint dynamically orchestrates one of two actions based on the settlement process:

- Cancels the transfer (reverses the authorization) if it hasn't yet settled
- Initiates a refund if the transfer is already in the process of settlement, or has been settled

The request body is optional and its behavior is as follows:

- **No amount specified**: Moov first attempts to cancel the transfer. If settlement is in progress or complete, a full refund is initiated.
- **Partial amount specified**: Moov immediately initiates a partial refund, as partial cancellations aren't supported. The cardholder will see a full debit followed by a partial credit. The `amount` is required to process a partial refund.

Ask

```zsh
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/reversals" \
  -H "Authorization: Bearer {token}" \
  -H "X-Idempotency-Key: UUID" \
  -H "x-moov-version: v2024.01.00" \
```

Ask

```zsh
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/reversals" \
  -H "Authorization: Bearer {token}" \
  -H "X-Idempotency-Key: UUID" \
  -H "x-moov-version: v2024.01.00" \
  --data-raw '{\n    "amount": 1000 // $10.00\n  }'
```

For immediate error correction, we recommend requesting a full reversal and creating a new transfer to create a smoother cardholder experience.

You can also initiate a reversal through the Moov [Dashboard](https://docs.moov.io/guides/dashboard/transfers/#reversal).

## Initiate a cancellation

While a reversal will cancel the transaction if possible, you also have the option of requesting a cancellation directly with the cancel a transfer `POST` [endpoint](https://docs.moov.io/api/money-movement/transfers/cancel/).

Ask

If you request a cancellation, but the card network has already settled, you'll receive an error. If the cancellation window has passed, use the [reversals](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/#initiate-a-reversal) or [refunds](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/refunds/) endpoint instead.

```zsh
curl -X POST "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/cancellations" \
  -H "Authorization: Bearer {token}" \
  -H "X-Idempotency-Key: UUID" \
  -H "x-moov-version: v2024.01.00" \
```

Ask

You can get the details of a cancellation using the cancellation details `GET` [endpoint](https://docs.moov.io/api/money-movement/transfers/cancel-details/).

```zsh
curl -X GET "https://api.moov.io/accounts/{accountID}/transfers/{transferID}/cancellations/{cancellationID}" \
  -H "Authorization: Bearer {token}" \
  -H "X-Idempotency-Key: UUID" \
  -H "x-moov-version: v2024.01.00" \
```

## Settlement status

Moov automatically checks the settlement status to determine if a transfer can be canceled. A successful request updates the transfer status to `canceled`, reversing the pending authorization. If settlement has already begun, a refund is initiated, which you can monitor using the [cancellation](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/#webhooks) or [refunds](https://docs.moov.io/guides/money-movement/accept-payments/card-acceptance/reversals/#webhooks) as well as the [cancellation](https://docs.moov.io/api/money-movement/transfers/cancel-details/) or [refunds](https://docs.moov.io/api/money-movement/refunds/get/)`GET` endpoints.

Moov provides a synchronous response to inform you of the reversal outcome, including relevant details based on whether a cancellation or refund occurred.

Ask

```jsx
{
  "cancellation": {
    "cancellationID": "string",
    "createdOn": "2024-08-24T14:15:22Z",
    "status": "completed"
  }
}
```

A cancellation typically completes instantly. However, if there's an error with the card network response, a `pending` status is returned until a confirmation is received.

A `4xx` error after reversal initiation signifies a decline from the card networks or a processing error. Retry the request with a new idempotency key. See our [reversal](https://docs.moov.io/api/money-movement/refunds/cancel/) API documentation for further information on HTTP error codes.

Ask

Ask

```jsx
{
  "refund": {
    "refundID": "ec7e1848-dc80-4ab0-8827-dd7fc0737b43",
    "createdOn": "2024-08-24T14:15:22Z",
    "updatedOn": "2024-08-24T14:15:32Z",
    "status": "pending",
    "amount": {
      "currency": "USD",
      "value": 1204
    },
    "cardDetails": {
      "status": "confirmed",
      "confirmedOn": "2023-09-10T18:23:56Z"
    }
  }
}
```

A [refund](https://docs.moov.io/api/money-movement/refunds/cancel/) will have a `pending` status while waiting for authorization, or a `failed` status if it was declined by the card networks. The refund's `cardDetails.status` will update with one of the following detailed rail specific statuses:

| Rail-specific status | Description |
| --- | --- |
| `initiated` | Refund has been initiated by the user |
| `confirmed` | Refund has been accepted by the card network |
| `settled` | Refund has been settled |
| `completed` | Refund has completed |
| `failed` | Refund has failed |

If the `refund` status updates to `failed`, the `cardDetails` object will update with a failure code.

```jsx
{
  "refund": {
    "refundID": "ec7e1848-dc80-4ab0-8827-dd7fc0737b43",
    "createdOn": "2024-08-24T14:15:22Z",
    "updatedOn": "2024-08-24T14:15:32Z",
    "status": "failed",
    "amount": {
      "currency": "USD",
      "value": 1204
    },
    "cardDetails": {
      "status": "failed",
      "failureCode": "suspected-fraud",
      "failedOn": "2023-09-10T18:23:56Z"
    }
  }
}
```

If a transfer has a refund or cancellation in any status, we’ll also include that information in the transfers response itself.

Ask

```jsx
 "transferID": "string",
  "createdOn": "2024-08-24T14:15:22Z",
  "status": "canceled",
  "cancellations": [\
    {\
     "cancellationID": "string",\
     "createdOn": "2023-09-09T14:15:22Z",\
     "status": "completed"\
    }\
  ],
```

## Webhooks

Subscribe to the following webhook event, which will provide you with relevant _reversal_ updates:

- `transfer.updated`notifies you once the reversal status changes to any of the following:

- `canceled`
  - `source.canceled`

Subscribe to the following webhook events, which will provide you with relevant _cancellation_ updates:

- `cancellation.created` notifies you when the cancellation was successfully created
- `cancellation.updated`notifies you when the cancellation was updated

- `pending`
  - `completed`
  - `failed`

Subscribe to the following two webhook events, which will provide you with relevant _refund_ updates:

- `refund.created` notifies you when the refund was successfully created
- `refund.updated`notifies you once the refund status changes to any of the following:

- `pending`
  - `completed`
  - `failed`
