API reference
Refunds
Give money back to a customer, in full or in part. You can only refund a payment that has succeeded, and only within 180 days of the payment.
The refund object#
{
"id": "re_y7AjzQHb6BAEcn6zJ4A3DdvH",
"object": "refund",
"payment": "pay_r3QA7YeEEBY3ABp3e2zS8iq9",
"amount": "100.00",
"currency": "AED",
"status": "pending",
"reason": null,
"livemode": false,
"created_at": "2026-10-20T11:00:00.000Z"
}
| Field | Details |
|---|---|
idstring | The refund id. Starts with re_. |
objectstring | Always "refund". |
paymentstring | The id of the payment that was refunded. |
amountstring | The refund amount in AED with two decimals. |
currencystring | Always "AED". |
statusstring | pending, succeeded or failed. |
reasonstring or null | The reason you sent, if any. |
livemodeboolean | true for a live refund, false for a test refund. |
created_atstring | When the refund was created. ISO 8601, UTC. |
Refund statuses#
| Status | Meaning |
|---|---|
pending | The refund has been requested and is being processed. Its amount is already set aside, so the same money cannot be refunded twice. |
succeeded | The refund is done. It now counts in the payment's amount_refunded. |
failed | The refund did not go through. Its amount is free to refund again. |
A refund can finish after your request returns. Listen for the refund.succeeded and refund.failed webhooks to know when.
Create a refund#
| Field | Details |
|---|---|
amountstring | How much to refund, in AED with two decimals, such as "100.00". It must be more than zero. If you leave it out, TigerPay refunds everything that is still refundable. |
reasonstring | A short note, up to 64 characters. |
# Partial refund of AED 100.00
curl https://api.tigerpay.app/v1/payments/pay_r3QA7YeEEBY3ABp3e2zS8iq9/refunds \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: refund-order-1001-1" \
-d '{ "amount": "100.00", "reason": "Customer returned one item" }'
# Refund everything that is left: send an empty object
curl https://api.tigerpay.app/v1/payments/pay_r3QA7YeEEBY3ABp3e2zS8iq9/refunds \
-H "Authorization: Bearer sk_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: refund-order-1001-2" \
-d '{}'
const response = await fetch(
"https://api.tigerpay.app/v1/payments/pay_r3QA7YeEEBY3ABp3e2zS8iq9/refunds",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TIGERPAY_SECRET_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "refund-order-1001-1",
},
body: JSON.stringify({ amount: "100.00", reason: "Customer returned one item" }),
}
);
const refund = await response.json();
<?php
$ch = curl_init('https://api.tigerpay.app/v1/payments/pay_r3QA7YeEEBY3ABp3e2zS8iq9/refunds');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('TIGERPAY_SECRET_KEY'),
'Content-Type: application/json',
'Idempotency-Key: refund-order-1001-1',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => '100.00',
'reason' => 'Customer returned one item',
]),
]);
$refund = json_decode(curl_exec($ch), true);
curl_close($ch);
Response: 200 with the refund object.
Rules#
- Only a payment with status
succeededcan be refunded. - You can refund a payment for 180 days after it succeeded. See The 180-day limit.
- You can refund a payment more than once, in parts.
- The refunds that are
pendingorsucceeded, added together, can never be more than the amount the customer paid.
Possible errors#
| Code | When |
|---|---|
resource_HTTP 404 | No such payment for your account and mode. |
payment_HTTP 400 | The payment has not succeeded. |
refund_HTTP 400 | The payment succeeded more than 180 days ago. See The 180-day limit. |
payment_HTTP 400 | Nothing is left to refund. |
refund_HTTP 400 | amount is more than what is left. The message tells you how much is left. |
parameter_HTTP 400 | amount or reason is not valid. |
refund_HTTP 502 | The payment provider declined the refund. The refund is saved as failed and its amount can be refunded again. |
provider_HTTP 502 | A temporary problem. The refund may still be pending. |
After a provider_unavailable error, do not retry straight away
The refund may already be on its way, and its amount is held back until it finishes. Wait for the refund.succeeded or refund.failed webhook, or look at the payment's amount_refunded, before you try again.
The 180-day limit#
You can refund a payment for 180 days after it succeeded (the paid_at time on the payment). Days are counted as 24 hours each. A refund requested exactly 180 days after the payment is still allowed. One moment later, it is not.
After that, the API refuses the refund with 400 and the error code refund_window_expired. No refund is created, and nothing is held back on the payment. The message includes the date the payment was made:
{
"error": {
"type": "invalid_request",
"code": "refund_window_expired",
"message": "This payment can no longer be refunded. Refunds are possible for 180 days after the payment, and this payment was made on 2026-01-01."
}
}
The limit is fixed and cannot be changed for a single payment. If you need to give money back after 180 days, arrange it with the customer another way, for example by bank transfer.
The limit applies to every refund, including part refunds. If you plan to refund part of a payment now and the rest later, do the second refund inside the 180 days too. Do not retry a refund_window_expired error, because it will not change.
Retrieve a refund#
curl https://api.tigerpay.app/v1/refunds/re_y7AjzQHb6BAEcn6zJ4A3DdvH \
-H "Authorization: Bearer sk_test_YOUR_KEY"
Returns the refund object. A wrong id, or a refund from another account or mode, gives 404 resource_missing.
There is no endpoint to list refunds. Keep the refund ids you get back, and use webhooks to follow them.