Skip to content

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"
}'
Response201
{
  "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. fees is null while the refund is pending, and when it failed: 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 net of 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 paid or partially_refunded can be refunded. Any other status answers 409 with payment_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.
  • reason is for your records, up to 255 characters.

Who can refund what

An API keyOnly 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 dashboardThe owners and admins of the business, for the payments of the stores of their business. Developers, accountants and viewers cannot refund.

Statuses

StatusHTTPMeaning
succeeded201The bank refunded the amount.
failed402The 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.
pending202The 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

StatusCodeWhen
404payment_not_foundNo such payment for this key.
409payment_not_refundableThe payment is not paid.
400amount_too_smallLess than 100 centimes.
400refund_exceeds_balanceMore than what is still refundable.
400insufficient_balanceYour balance cannot cover a live refund and its fee: top it up, or refund a smaller amount.
402refund_declinedThe bank refused the refund.
409idempotency_in_progressThe first request with this key is still running.
422idempotency_key_reusedThe key was used with different parameters.
503gateway_unavailableThe gateway cannot be reached. Nothing was refunded: retry.