SUCCEEDED payment to the customer’s card.
Refunds always use the currency of the original payment.
Create a refund
amountis always required, in minor units. For a full refund, send the payment’s currentamount_refundable.merchant_referenceis optional, belongs to this refund, and must be an integer with exactly 10 digits (from1000000000to9999999999).reasonis required free text for your support and audit trail.- A payment can be refunded multiple times until the accumulated refunded
amount reaches the original amount. A refund that would exceed
amount_refundableis rejected with422anderror.code: "amount_exceeds_refundable".
201 Created with a Refund object:
Refund lifecycle
Refunds are processed asynchronously.201 means accepted, not completed.
Track refund status by re-retrieving the parent payment — every payment
carries its refunds in the
refunds array (oldest first), with
amount_refunded and amount_refundable kept up to date. Webhooks also emit
refund.succeeded and refund.failed when terminal refund status changes are
available.
Idempotent refunds
Refund creation is idempotent on (Idempotency-Key, request body):
- Retrying with the same key and the same body returns the original refund — it is safe to retry on timeouts.
- Reusing a key with any field changed (a different
amount,reason, ormerchant_reference) is rejected with409anderror.code: "idempotency_key_reused". - Retrying while the original request is still processing returns
409witherror.code: "idempotency_key_in_use"; wait briefly and retry the same body.
refund-{orderId}-{sequence} — so retries collapse correctly even across
processes. More in Idempotency.
Operational notes
- Refunds can take several business days to appear on the customer’s
statement, even after
SUCCEEDED. - If a refund
FAILED(for example the card account was closed), resolve it with the customer through another channel; creating the same refund again will typically fail for the same reason.