M
MAXFIdeveloper hub
APIRefund

Refund a payment

Issue a full or partial refund. Multiple partial refunds chain — each decrements remaining. Refunds are asynchronous at the acquirer: we return immediately, then deliver payment.refunded webhook(s) as the money clears (typically 1-5 business days).

POST/v2/payments/{id}/refund
sk_live_ / sk_test_
Idempotency is on you.
Use a unique idempotency_key per refund attempt. Without it, two queue retries can issue two refunds. With it, the second call returns the cached result instantly (24h TTL).

Path parameter

ParamDescription
{id}Any of: cs_* session id, pay_* id, your order_id, or the connector reference. We resolve them all.

Request body

FieldTypeDescription
amountintegerAmount to refund in minor units. Omit for full refund of the remaining balance. Cannot exceed remaining (we 400 instead of overdrafting).
reasonstring(500)Free-form note. Stored in audit log, returned in payment.refunded webhook.
idempotency_keystring(128)Replay-safe key. Strongly recommended for queue-driven systems.

Response

FieldTypeDescription
statusstringrefunded when fully refunded; partially_refunded while balance remains.
amount_refundedintegerThis call's refund amount.
total_refundedintegerSum across all refund calls on this payment.
remainingintegerStill refundable balance.
connector_refund_idstringProvider-side ref for support cases.

Errors

HTTPCodeReason
400VALIDATION_ERRORNegative or zero amount.
400REFUND_EXCEEDS_BALANCERequested amount > remaining (already refunded shown in error).
400INVALID_PAYMENT_STATEOnly succeeded or partially_refunded can be refunded.
404NOT_FOUNDNo payment matches {id} for your merchant.
502CONNECTOR_REFUND_FAILEDProvider rejected the refund — check error_message.

Webhook fired

On every successful refund call we enqueue payment.refunded to your webhook URL. Includes the refund object and updated total_refunded. Retried 8 times across 24h until you ACK with 2xx.