SUCCESS status, and the refund has its own ID and lifecycle. The merchant API supports eligible Stripe, Mollie, Revolut, Viva, Adyen and Checkout.com sales when the order and processing currencies match. Use the sale’s currency for the refund amount. Separately charged fees are excluded. Other connectors return 422 REFUND_NOT_SUPPORTED.
Revolut refunds use the provider order ID of the original sale and the matching sandbox or production connection. If a request times out, use the original refund ID to follow its outcome. Revolut card payments
Viva refunds additionally require the merchant API key in the connection settings. A timed-out
Viva refund stays PROCESSING for verification; it is never automatically sent a second time.
Adyen refunds require a captured payment and the connection’s authenticated Standard webhook.
An uncertain dispatch stays PROCESSING until the signed callback arrives; never create a new
refund to retry it. Later provider refund failures or reversals require operator reconciliation.
Checkout.com refunds require a captured payment and the connection’s signed refund webhooks.
Acceptance remains PROCESSING until the refund outcome arrives. After an uncertain dispatch,
automatic recovery waits for the webhook; contact operations if it remains unresolved instead
of creating another refund. Refunds made outside OrsunPay are not imported automatically.
Create a partial refund
amount is a positive decimal string in the sale’s currency, with that currency’s precision.
Omit it to refund the unreserved remainder. Both PENDING and PROCESSING refunds reserve
capacity, so another request cannot refund the same remaining money concurrently.
Reasons are requested_by_customer (default), duplicate, fraudulent, or other. Metadata
is optional JSON object data, limited to 16 KiB in UTF-8 and depth 10. Do not include card data,
secrets or unnecessary personal information.
data.id and poll that refund,
or consume the signed refund.succeeded / refund.failed webhooks.
Retry safely
Idempotency-Key is required. Keep both the key and request unchanged after a network error or
timeout. The same key replays the same stored response, including the refund ID, with
Idempotency-Replayed: true; it may still show PENDING after the refund has completed.
Use GET for fresh status. A changed request under the same key returns
422 IDEMPOTENCY_KEY_REUSED; a simultaneous request can return 409 IDEMPOTENCY_IN_PROGRESS
with Retry-After.
The standard idempotency window applies. Do not create another refund with a new
key, or retry creation after that window, merely because an earlier refund is still unresolved.
Use its ID and contact operations for reconciliation. An unresolved PSP response retains the
reserved amount; a timeout is not proof of failure.
Read status
{ "data": { ... } }; the payment list is
{ "data": [ ... ], "nextCursor": null }. The list accepts limit (1–100, default 100) and
an opaque cursor from its previous nextCursor. Continue until nextCursor is null; do not
assume the first page contains every partial refund.
Reads use the authenticated merchant and mode. Missing, foreign-merchant and wrong-mode IDs
return 404 without exposing another payment. Poll with backoff; GET reads the stored state and
does not dispatch a PSP request.
There is no public cancel endpoint in this release.
PROCESSING cannot be canceled merely to
release capacity. A provider reference can arrive while the status stays PROCESSING.
Errors
Transport failures are not business declines. Reuse the original key while its window is active,
then read the existing refund. Never show a raw PSP error message to the buyer.