Appearance
Refund a payment
POST /api/v1/payments/{id}/refunds
Permission: refunds:create. The original payment must have succeeded and have a receipt.
http
Authorization: Bearer YOUR_APPLICATION_TOKEN
Idempotency-Key: order-1042-refund
Content-Type: application/jsonjson
{"reason":"Customer requested a refund"}HTTP 202 returns a refund ID. Read GET /api/v1/refunds/{id} to follow its result. The original amount, currency and payer determine the return. One full refund is supported per payment.
Reserve the credited funds
The gateway sends a signed POST to your Reserve funds URL with type: refund.reserve, refund_id, payment_id, reference, amount_minor, currency and environment. Verify its signature using the webhook procedure; the event header contains the refund ID.
Recover the original credited value once, using refund_id as the unique reservation key. If the customer has spent it and funds are unavailable, return HTTP 409. Otherwise return:
json
{
"status": "reserved",
"refund_id": "RECEIVED_REFUND_ID",
"payment_id": "RECEIVED_PAYMENT_ID",
"amount_minor": 100,
"currency": "USD",
"adjustment_reference": "YOUR_DURABLE_ADJUSTMENT_ID"
}A repeated reservation request must return the same adjustment reference.
Follow the result
| Refund status | Action |
|---|---|
awaiting_funds | The gateway is waiting for the application reservation |
processing | Keep the funds reserved while EcoCash processes the return |
succeeded | Finalize the debit; the refund has a provider receipt |
failed | Release the reservation once |
needs_review | Inspect the reason in the dashboard and keep the original operation |
Staff use the same reservation and return process through Payments → Refund.