Refunds
Test-mode refunds through the API; live refunds requested from the dashboard and counted once the provider confirms them.
Refunds work differently in test and live mode.
| Test key | Live key | |
|---|---|---|
| How | POST /api/v1/payments/{id}/refunds, full or partial |
A refund request from the dashboard |
| When it counts | At once (simulated) | Only when the provider confirms it |
| API answer | 201 with the payment |
422 refunds_processed_manually |
| Webhook | payment.partially_refunded or payment.refunded |
The same, once the refund is confirmed |
Handle refunds from the webhook, not from your own request: then the same code works in both modes.
Refund in test mode
With a test key the refund is simulated at once. Send the amount to refund in whole IQD and a reason. You can refund part of the payment, then more, until the whole amount is returned.
curl -s -X POST "$BRIDGE_URL/api/v1/payments/01a13c8c-8592-70f4-9ef9-d3767e74d54c/refunds" \
-H "Authorization: Bearer $BRIDGE_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"amount": 10000, "reason": "One item out of stock"}'
| Field | Type | Rules |
|---|---|---|
amount |
integer | Required. At least 1, at most amount − refunded_amount. |
reason |
string | Required. Up to 500 characters. Stored as the refund's note. |
The answer is 201 Created with the whole payment: status is partially_refunded while some
money remains and refunded when nothing does, refunded_amount grows, and the new entry is in
refunds:
{
"id": "01a13c8c-8592-70f4-9ef9-d3767e74d54c",
"status": "partially_refunded",
"amount": 25000,
"refunded_amount": 10000,
"refunds": [
{"id": 1, "amount": 10000, "source": "api", "provider_reference": "01a13c8c-8595-723d-90e3-978995c21827", "note": "One item out of stock", "created_at": "2026-10-14T22:40:11+00:00"}
]
}
(Shortened; the full payment shape is on Payments.) The matching webhook,
payment.partially_refunded or payment.refunded, is sent too.
Live refunds
The provider behind live payments (APS) has no refund API, so this endpoint does not refund live
payments. With a live key the same request answers 422, whatever its body, and docs_url
points to this page:
{
"error": {
"code": "refunds_processed_manually",
"message": "Live refunds are not made through the API. Request the refund from the application dashboard; it is processed by the payment provider.",
"docs_url": "https://<your-bridge-domain>/docs/en/refunds"
}
}
A live refund is requested from the dashboard, on the payment's page, and recorded manually. Who may request it depends on the provider account your application uses:
| Provider account | Who requests the refund |
|---|---|
| Alphabet's shared account | Alphabet, on your behalf. Contact Alphabet support with the payment id, the amount and the reason. |
| Your application's own account | Your application's Owner, from the payment's page in the application dashboard, or Alphabet. |
What happens next:
- The request is created with an amount (full or partial) and a reason. Its state is Requested. The amount can never be more than the paid amount minus refunds already confirmed and requests still open.
- The bridge emails the request to the provider's refund desk, which makes the refund.
- The provider confirms or declines. When the refund is confirmed, Alphabet (or, on your own account, your Owner) records the provider's reference, or the bridge sees the provider report the refund by itself. If the provider declines, the request is closed as Rejected with a note.
- Only a confirmed refund counts. Then the payment becomes
partially_refundedorrefunded,refunded_amountgrows, arefundsentry withsource: manualappears, and the webhook is sent.
| Request state | Meaning | Payment | Webhook |
|---|---|---|---|
| Requested | Sent to the provider, waiting for its answer | Unchanged | None |
| Confirmed | The provider made the refund | partially_refunded or refunded |
payment.partially_refunded or payment.refunded |
| Rejected | The provider declined | Unchanged | None |
Your application dashboard lists every refund request on the payment, with its amount, reason, state, who requested it and when.
If the provider reports a refund that nobody requested in the bridge, the payment is marked
refunded, you receive payment.refunded with a refunds entry of source: provider_detected,
and Alphabet reviews it.
Rules
- Only
paidandpartially_refundedpayments can be refunded. Otherwise the API answers409 payment_not_refundablewith the currentstatus. - Refunding more than is left answers
422 refund_amount_exceeds_refundablewithrefundable_amount. - The money goes back to the card that paid. It can take some days to reach the customer's statement.
- Fees are not returned on a refund.