Skip to content

Refunds

A refund sends the full amount of a succeeded payment back to the customer’s wallet. There are no partial refunds.

Terminal window
curl -s -X POST http://localhost:4000/v1/payments/$PAYMENT_ID/refunds \
-H "Authorization: Bearer $XAALIS_KEY" \
-H "Idempotency-Key: refund:order_1042"
{ "id": "re_…", "object": "refund", "payment_id": "pay_…", "amount": 15000, "currency": "XOF",
"status": "succeeded", "fee_refunded": 0, "created_at": "…" }
  • Idempotency-Key is required. Repeating the request returns the same refund — a payment can never be refunded twice, however many times you retry.
  • Only succeeded Wave payments can be refunded (test mode simulates Wave).
  • GET /v1/payments/{id}/refunds returns the refund (a list of zero or one) — use it to check an outcome without retrying.

The customer always gets the gross amount back. By default Xaalis keeps its fee, so your available balance must cover the gross amount:

Payment Your fee Refund debits your balance Customer receives
15 000 225 15 000 15 000

fee_refunded shows the fee Xaalis returned (0 under the default policy). If your balance can’t cover it, the request fails with 422 insufficient_funds and nothing happens; retry once funds arrive.

status Meaning You do
succeeded the money is back with the customer; the payment is now refunded nothing — you also get payment.refunded
pending the provider’s answer isn’t known yet (the API may have returned 503) wait for payment.refunded, or retry with the same key
needs_review the provider refused; the amount stays reserved from your balance contact Xaalis — an operator reconciles it with the provider

A refunded subscription invoice stays paid; refunding doesn’t restart its billing cycle.