# Refunds

> Refund all or part of a payment, and follow the refund to its end.

Source: https://rais.app/docs/refunds

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.


**Request**

```bash
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"
}'
```

**Response** (`201`)

~~~json
{
  "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](https://rais.app/docs/idempotency.md).

## 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](https://rais.app/docs/pricing.md) 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 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.


**Request**

```bash
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.


**Request**

```bash
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](https://rais.app/docs/receipts.md).

## 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. |
