# Reversals

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

The reversals `POST` [endpoint](/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](#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](/guides/money-movement/accept-payments/card-acceptance/surcharges/), the surcharge must be specified in the request

## [Initiate a reversal](#initiate-a-reversal)

Use the reversals `POST` [endpoint](/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.

[Full refund](#tab-246879513-1-0) [Partial refund](#tab-246879513-1-1)

```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" \
```

```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 '{
    "amount": 1000 // $10.00
  }'
```

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](/guides/dashboard/transfers/#reversal).

## [Initiate a cancellation](#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](/api/money-movement/transfers/cancel/).

[Request a cancellation](#tab-793528416-3-0) [Retrieve a cancellation](#tab-793528416-3-1)

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](#initiate-a-reversal) or [refunds](/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" \
```

You can get the details of a cancellation using the cancellation details `GET` [endpoint](/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](#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](#webhooks) or [refunds](#webhooks) as well as the [cancellation](/api/money-movement/transfers/cancel-details/) or [refunds](/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.

[Cancellation](#tab-184972365-4-0) [Refund](#tab-184972365-4-1)

```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](/api/money-movement/refunds/cancel/) API documentation for further information on HTTP error codes.

```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](/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.

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

## [Webhooks](#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`
