Refunds
Generated page, from the OpenAPI specification the gateway serves (
GET /v1/openapi.json). Do not edit it by hand: it is rewritten on every build.
| Method | Path | Description |
|---|---|---|
GET |
/v1/payments/{id}/refunds |
A collection's refunds |
GET |
/v1/refunds |
List refunds |
POST |
/v1/refunds |
Refund a payment |
GET |
/v1/refunds/{id} |
Retrieve a refund |
GET /v1/payments/{id}/refunds
A collection's refunds
This collection's refunds, newest first — the same object as the items of GET /v1/refunds, with the same pagination. The collection is named by its identifier or its internal reference; another account's answers 404, like an unknown identifier.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id |
path | yes | |
page |
query | no | Page, starting at 1. |
per_page |
query | no | Page size, 100 at most. |
Responses
200— OK (OperationList)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)404— No payment with that identifier (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
GET /v1/refunds
List refunds
Same pagination as payments.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
page |
query | no | Page, starting at 1. |
per_page |
query | no | Page size, 100 at most. |
payment_id |
query | no | Only list THIS payment's refunds: its identifier or its internal reference. An unknown payment, or another account's, gives an empty list. |
Responses
200— OK (OperationList)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
POST /v1/refunds
Refund a payment
Full or partial refund of a successful payment; the funds come off the available balance at the time of the call. Omitting amount_minor refunds the remaining balance.
⚠️ The Idempotency-Key header must be specific to THIS refund, never the original payment's identifier: a payment can be refunded in several parts, and a key carrying the parent's identifier would make the second partial refund look like a replay of the first — success on the merchant's side, customer not refunded.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
Idempotency-Key |
header | no | An idempotency key specific to THIS operation. Replaying the same key with the same payload returns the original; replaying it with a different payload is refused (409). |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
payment_id |
string | yes | The parent collection: its id or its internal reference. |
amount_minor |
string | no | Amount in MINOR UNITS, as a string. Never a floating-point number: both lose centimes. The asset's decimal count comes from GET /v1/assets. |
description |
string | no | |
reason |
string | no | The refund reason. A closed vocabulary, enforced by a database constraint. |
Responses
201— Refund created (Operation)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)409— Idempotency key replayed with a different payload (Error)422— Refund refused — the error code says why:refund_exceeds_refundable(the amount is above what remains refundable; the error carriesamount_refundable_minor),wave_partial_refund_window_closed(the Wave partial-refund period has passed: only a full refund remains possible),wave_partial_refunds_disabled,wave_refund_window_closed(Wave collection already partly refunded and period passed: no further refund),payer_not_found(Wave does not name the payer: a partial refund cannot be paid to them),insufficient_funds. (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
GET /v1/refunds/{id}
Retrieve a refund
The same masked view as GET /v1/payments/{id}.
Parameters
| Name | In | Required | Description |
|---|---|---|---|
id |
path | yes | Internal identifier, the operation's reference, or your own client_ref. |
Responses
200— OK (Operation)401— API key missing or rejected (Error)403— The key does not carry the required scope, or the account is not active (Error)429— The key's request budget is exhausted (300/min) — honour Retry-After (Error)
Schemas
The shapes the operations above return.
OperationList
| Field | Type | Description |
|---|---|---|
data |
Operation[] | |
data[].id |
string | The operation's public id. It is the one in the /v1/payments/{id} paths. |
data[].ref |
string | Our internal, readable reference. Distinct from the id: quote this one to support. |
data[].client_ref |
string | The reference you supplied at creation, returned unchanged. |
data[].kind |
string | payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which. |
data[].status |
string | The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail. |
data[].outcome |
string | pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on. |
data[].asset_id |
integer | The operation's asset, by its id (GET /v1/assets). |
data[].amount_minor |
string | The GROSS amount in minor units, as a string. |
data[].fee_minor |
string | The fee taken, in minor units. |
data[].net_minor |
string | The net in minor units: amount_minor less fee_minor. |
data[].platform_id |
integer | The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose. |
data[].is_test |
boolean | True for an operation created with a test key. No real money moves. |
data[].payment_url |
string | The hosted payment page, when the rail provides one. Absent until submission has succeeded. |
data[].deeplink |
string | The deep link into the rail's app, when it provides one. |
data[].qrcode_url |
string | The QR to show the payer, when the rail provides one. |
data[].risk |
Risk | The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block. |
data[].risk.status |
string | held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report. |
data[].risk.case_ref |
string | The operational case reference, to quote to support. Null when the hold is a compliance review. |
data[].risk.case_kind |
string | Accompanies case_ref, or nothing at all. |
data[].risk.reason |
string | The only free text this block carries, and it is identical for every hold. |
data[].risk.signals |
object[] | Product signals, advisory. Absent when there are none. |
data[].risk.signals[].code |
string | |
data[].risk.signals[].detail_fr |
string | |
data[].amount_refunded_minor |
string | Collections only: the sum of SUCCEEDED refunds, in minor units. |
data[].amount_refund_pending_minor |
string | Collections only: the sum of refunds IN PROGRESS, in minor units. |
data[].amount_refundable_minor |
string | Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…). |
data[].refund_count |
integer | Collections only: the number of refunds that did not fail. |
data[].partial_refund_deadline |
string | Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled. |
page |
integer | |
per_page |
integer |
Error
| Field | Type | Description |
|---|---|---|
error |
object | |
error.code |
string | |
error.message |
string |
Operation
One money operation — collection, payout, refund, transfer or rebalance. The same object across all five families.
| Field | Type | Description |
|---|---|---|
id |
string | The operation's public id. It is the one in the /v1/payments/{id} paths. |
ref |
string | Our internal, readable reference. Distinct from the id: quote this one to support. |
client_ref |
string | The reference you supplied at creation, returned unchanged. |
kind |
string | payin | payout | withdrawal | refund | chargeback | adjustment | transfer | rebalance. The same object serves all five families; this field says which. |
status |
string | The rail's detailed state. ⚠️ To decide whether the money arrived, read outcome: status carries journey detail and its vocabulary depends on the rail. |
outcome |
string | pending | succeeded | failed | cancelled | expired | reversed. The only field to base a business decision on. |
asset_id |
integer | The operation's asset, by its id (GET /v1/assets). |
amount_minor |
string | The GROSS amount in minor units, as a string. |
fee_minor |
string | The fee taken, in minor units. |
net_minor |
string | The net in minor units: amount_minor less fee_minor. |
platform_id |
integer | The platform that carried the operation. Absent while a hosted collection is still waiting for the payer to choose. |
is_test |
boolean | True for an operation created with a test key. No real money moves. |
payment_url |
string | The hosted payment page, when the rail provides one. Absent until submission has succeeded. |
deeplink |
string | The deep link into the rail's app, when it provides one. |
qrcode_url |
string | The QR to show the payer, when the rail provides one. |
risk |
Risk | The state of the risk check (FRAML). Absent when the operation was not assessed — which is not the same thing as “clear”. The outbound webhook and this read return the same block. |
risk.status |
string | held: the funds have not moved. review: the payment ran its course, something is being looked at. clear: nothing to report. |
risk.case_ref |
string | The operational case reference, to quote to support. Null when the hold is a compliance review. |
risk.case_kind |
string | Accompanies case_ref, or nothing at all. |
risk.reason |
string | The only free text this block carries, and it is identical for every hold. |
risk.signals |
object[] | Product signals, advisory. Absent when there are none. |
risk.signals[].code |
string | |
risk.signals[].detail_fr |
string | |
amount_refunded_minor |
string | Collections only: the sum of SUCCEEDED refunds, in minor units. |
amount_refund_pending_minor |
string | Collections only: the sum of refunds IN PROGRESS, in minor units. |
amount_refundable_minor |
string | Collections only: what can be refunded NOW, in minor units — the original amount less succeeded and in-progress refunds, or "0" when the refund rule allows none (collection not successful, Wave period passed after a partial refund…). |
refund_count |
integer | Collections only: the number of refunds that did not fail. |
partial_refund_deadline |
string | Wave collections only: until when a partial refund is possible (RFC 3339). Absent for other rails, or when Wave partial refunds are disabled. |