Reversals

A reversal returns money to the cardholder with one call. Moov checks the payment's settlement state, then cancels it if it can or refunds it if it can't.

Use reversals as the default way to undo card payments. Call it with your partner account's /accounts/{accountID}/transfers.write scope. For ACH, see cancel an ACH transfer; ACH has no refunds.

Card payment state Request What Moov does Resulting status Confirm with
Authorized, not settled No amount Cancels the authorization, so the charge drops off the card Transfer canceled transfer.updated, cancellation.updated
Settling or settled No amount Issues a full refund to the card Refund completed refund.updated
Any amount set Issues a partial refund (partial cancellations aren't supported) Refund completed refund.updated

Canceling costs less and returns funds faster than refunding. A refund debits the merchant's wallet immediately, and the cardholder usually sees the credit post in 5 to 7 business days.

Reversal rules

  • 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, the surcharge must be specified in the request

Initiate a reversal

Call the reversals POST endpoint. amount is required: set it to the full transfer amount for a full reversal, or to a smaller amount for a partial refund. With a partial refund, the cardholder sees the full charge followed by a partial credit.

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: v2026.07.00" \
  --data-raw '{
    "amount": 2500
  }'
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.

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.

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 or refunds endpoint instead.

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: v2026.07.00"

Track the outcome

The reversal response tells you synchronously whether Moov canceled or refunded the payment. Follow it with the webhooks below, or the cancellation or refund GET endpoints.

{
  "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 documentation for further information on HTTP error codes.

If a transfer has a refund or cancellation in any status, the transfer response includes it too.

{
  "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