After the payment
Refunds
Refund all or part of a payment, and follow the refund to its end.
A refund returns all or part of a paid payment to the payer's card. You can refund through the API with a key that has the refunds:write scope, or from the dashboard.
Refund a payment
Without an amount, everything that can still be refunded is refunded. With one, it is that many centimes.
curl https://api.rais.app/v1/payments/5b1c2f4e-9d3a-4c61-8a7e-0f2d6b9e1a33/refunds \
-H "Authorization: Bearer rais_sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4b0f8a7a-6a5e-4d0f-9f55-2c3e8d1a9b10" \
-d '{
"amount": 150000,
"reason": "Customer returned one item"
}'{
"id": "0c8a1d52-6e7b-4f0a-9b3d-7d2e4a8c5f10",
"object": "refund",
"payment_id": "5b1c2f4e-9d3a-4c61-8a7e-0f2d6b9e1a33",
"amount": 150000,
"currency": "DZD",
"status": "succeeded",
"reason": "Customer returned one item",
"failure": null,
"fees": {
"satim": 800,
"rais": 200,
"total": 1000
},
"livemode": false,
"created": 1793000900
}The refund is carried out with the gateway before the API answers, so the answer is the outcome. After a successful refund the payment's amount_refunded grows, its status becomes partially_refunded or refunded, and a refund.succeeded event is sent. Always send an Idempotency-Key: if the connection drops, repeating the request can never refund twice. See Idempotency and retries.
What a refund costs
Every refund has its own fee, 10.00 DA excluding VAT (SATIM 8.00 DA plus Raïs 2.00 DA), whatever the amount: refunding 1.00 DA costs as much as refunding 100,000.00 DA. The refund object carries it in fees, with the satim and rais parts and their total, in centimes.
- The fee is charged when the refund succeeded.
feesisnullwhile the refund ispending, and when itfailed: a refund that does not happen costs nothing. - The fee of the payment itself is not returned, in full or in part: refunding a payment never gives back what it cost. What you keep is
netof the payment, minus the amount refunded, minus the fee of each refund. - A live refund is taken out of your balance together with its fee: the balance must cover the amount and the fee. While a refund is
pending, both are reserved. - A sandbox refund shows the simulated fee, moves no money and needs no balance.
See Pricing and fees for the whole price list.
Rules
- Only a payment with the status
paidorpartially_refundedcan be refunded. Any other status answers409withpayment_not_refundable. - The smallest refund is 100 centimes (1.00 DA). A smaller one answers
amount_too_small. - A payment can be refunded several times, never beyond what was paid. Asking for more than what is left answers
refund_exceeds_balance; refunds that are still pending count as already taken. - A live refund is paid out of your store's balance, which must cover the refund and its fee (10.00 DA): otherwise the answer is
insufficient_balance, "The store's balance is not sufficient to cover this refund and its fee." Nothing is refunded and nothing is taken: a top-up of the balance is needed, or refund a smaller amount that the balance covers. A full refund is therefore not possible while the balance falls short of the amount and the fee, and the refund dialog of the dashboard says what the balance can cover and how much is missing. Because the fee of the payment is not returned either, a store that has received a single payment can refund at most its balance minus 10.00 DA. A sandbox refund moves no money and never touches a balance. reasonis for your records, up to 255 characters.
Who can refund what
| An API key | Only payments of its own store, in its own environment. Any other payment answers 404, whether it exists or not. The key needs refunds:write. |
| The dashboard | The owners and admins of the business, for the payments of the stores of their business. Developers, accountants and viewers cannot refund. |
Statuses
| Status | HTTP | Meaning |
|---|---|---|
succeeded | 201 | The bank refunded the amount. |
failed | 402 | The bank refused. The error is refund_declined; the refund object, which you can still read in GET /refunds, has a failure with the reason. Nothing was refunded. When the gateway could not be reached at all, the refund is recorded as failed too and the answer is 503 gateway_unavailable. |
pending | 202 | The request reached the gateway but its answer was lost. The amount stays reserved until the refund is checked. |
Pending refunds
A pending refund means that Raïs does not know yet whether the money went back. Do not repeat the refund with a new Idempotency-Key: that could refund twice. The amount stays reserved on the payment, and for a live refund on your balance (together with the refund's fee, which is only charged if the refund goes through), while the refund is pending. Raïs never guesses the outcome and has no automatic check for it: a pending refund is settled by hand with the payment gateway. Read the refund to see where it stands, and contact support with the refund id and the Rais-Request-Id of the request if it is still pending after a few minutes. Do not wait for an event to settle it.
curl https://api.rais.app/v1/refunds/0c8a1d52-6e7b-4f0a-9b3d-7d2e4a8c5f10 \
-H "Authorization: Bearer rais_sk_test_..."Timing
The refund itself is immediate: the API answers once the gateway has. How quickly the amount shows on the payer's statement is up to their bank, and Raïs cannot speed it up. Tell your customers that it may not appear at once.
List refunds
List the refunds of your store, or only those of one payment.
curl 'https://api.rais.app/v1/refunds?payment=5b1c2f4e-9d3a-4c61-8a7e-0f2d6b9e1a33' \
-H "Authorization: Bearer rais_sk_test_..."Receipts after a refund
The payer's receipt is regenerated after a refund, so it always shows the refunds made so far, and the refunded payment is marked refunded or partially refunded on its result page. See Receipts.
Errors
| Status | Code | When |
|---|---|---|
| 404 | payment_not_found | No such payment for this key. |
| 409 | payment_not_refundable | The payment is not paid. |
| 400 | amount_too_small | Less than 100 centimes. |
| 400 | refund_exceeds_balance | More than what is still refundable. |
| 400 | insufficient_balance | Your balance cannot cover a live refund and its fee: top it up, or refund a smaller amount. |
| 402 | refund_declined | The bank refused the refund. |
| 409 | idempotency_in_progress | The first request with this key is still running. |
| 422 | idempotency_key_reused | The key was used with different parameters. |
| 503 | gateway_unavailable | The gateway cannot be reached. Nothing was refunded: retry. |