Refunds
Return all or part of a successful payment. The total refunded can never exceed what the buyer paid.
Create a refund
POST/v1/refunds
| Field | Type | Notes |
|---|---|---|
reference | string, required | Your unique id for this refund. |
paymentReference | string, required | The reference of the checkout you are refunding. |
amount | integer, required | Kobo, at least 1. Partial refunds are fine. |
reason | string | Up to 255 characters. Kept for your records. |
bash
curl -s $BASE/v1/refunds \
-H "Authorization: Bearer $KEY" -H "X-Merchant-Id: $MID" \
-H "Idempotency-Key: $(uuidgen)" -H "Content-Type: application/json" \
-d '{
"reference": "RF-1001-1",
"paymentReference": "ORD-1001",
"amount": 250000,
"reason": "Item returned"
}'Response 201
{ "id": "rfd_41ab...", "reference": "RF-1001-1", "status": "pending" }A refund starts as pending and ends as succeeded or failed. You are told by the refund.succeeded or refund.failed webhook.
Retrieve a refund
GET/v1/refunds/:reference
Returns the refund with its status, amount, paymentReference, reason and, if it failed, failureReason.
Rules
- Only a
succeededpayment can be refunded. Otherwise you get409 payment_not_paid. - An unknown
paymentReferencereturns404 payment_not_found. - You can refund in several parts. If the amount is more than what is still refundable you get
422 refund_exceeds_paid, and the message says how much is left. - A failed refund frees its amount again, so you can retry with a new reference.
- The checkout's
refundedAmountfield shows the running total.
In the sandbox, a refund settles within a few seconds. Send the reason
sandbox_fail to see how your code handles refund.failed.