Max SystemsMAXFIdeveloper hub
APIRefund

Refund a payment

Refunds a payment in full or in part. You can make several partial refunds until the payment is fully refunded; each one reduces remaining. Only payments with status succeeded or partially_refunded can be refunded.

MAXFI sends the refund to the payment provider during the call. When the provider accepts it, the response is 200 and a payment.refunded event is queued for your account’s webhook URL at once. If the provider’s answer is not known yet, the response is 202 with status refund_pending.

POST/v2/payments/{id}/refund
Authentication: sk_live_ / sk_test_. Secret API key. Use it only on your server.
Make retries safe
Send a unique key for each refund you intend to make: the idempotency_key field in the body or the Idempotency-Key header. A repeat with the same key within 24 hours does not refund again: it returns the stored result with its status code — 202 for refund_pending — and the idempotent-replay: true header. The same key with another payment, amount or reason returns 409 IDEMPOTENCY_KEY_REUSED. The header also protects against a repeat sent while the first request is still running: such a repeat gets 409 IDEMPOTENCY_IN_PROGRESS. Without a key, a retried request can refund again as long as an amount remains.

Path parameter

ParameterDescription
{id}Payment ID: cs_… for payments made on the payment page, pay_… for payments created with POST /v2/payments. Test keys see only test payments, live keys only live ones.

Request body

FieldTypeDescription
amountintegerAmount to refund, in minor units. Omit it to refund the whole remaining amount. An amount larger than what remains returns 400.
reasonstring(500)Your note. Returned in the response and in data.refund.reason of the payment.refunded event.
idempotency_keystring(128)Key that makes retries safe (see above).

Response — 200

FieldTypeDescription
idstringPayment ID.
payment_idstringPayment ID (the same value as id).
statusstringrefunded once the payment is fully refunded; partially_refunded while an amount remains.
amount_refundedintegerAmount refunded by this call.
total_refundedintegerTotal refunded on this payment.
remainingintegerAmount that can still be refunded.
reasonstringYour note, echoed.
connector_refund_idstring | nullThe payment provider’s reference for this refund, if it returned one. Quote it in support requests.

Response — 202 refund_pending

The provider did not confirm the outcome in time (for example, a timeout). The refund may still go through. Do not send it again; check the payment later with GET /v2/payments/{id}.

FieldTypeDescription
statusstringrefund_pending.
amount_refundedinteger0 until the outcome is confirmed.
refund_pending_amountintegerAmount being verified.
messagestringExplanation in English.

Errors

HTTPCodeReason
400VALIDATION_ERRORamount is not a positive integer, or reason is longer than 500 characters.
400BAD_REQUESTThe payment’s status does not allow a refund, it is already fully refunded, the amount exceeds what remains, or the provider declined the refund.
401UNAUTHORIZEDMissing or invalid API key.
403FORBIDDENA restricted key without refunds:write.
404NOT_FOUNDNo payment with this ID in your account and mode.
409CONFLICTAnother refund of this payment is being processed at the same moment, or the payment cannot be refunded automatically — contact support.
409IDEMPOTENCY_KEY_REUSEDThe key (idempotency_key or Idempotency-Key) was already used with a different request — another payment, amount or reason.
409IDEMPOTENCY_IN_PROGRESSA request with the same Idempotency-Key header is still being processed. Retry later.
429RATE_LIMIT_EXCEEDEDMore than 100 requests in 60 seconds from your IP address.

Webhook

After a 200 response MAXFI queues payment.refunded. data.status is refunded or partially_refunded; data.refund holds amount, currency, reason, is_partial, total_refunded and connector_refund_id. Delivery takes up to 8 attempts until your endpoint answers with 2xx — see Webhooks.

POST /v2/payments/{id}/refund · MAXFI Developer Hub