Skip to main content

Refund requests

The refund API starts and tracks monetary refunds owned by the payment service. It uses payment-row locking, cumulative partial-refund accounting, and a durable merchant c_id to prevent duplicate money movement.
Prerequisites: use refunds.create to request a refund, refunds.read to query it, and refunds.comment to add a merchant note. The referenced payment must belong to the same merchant and satisfy the API key’s actual currency and service policy.

Methods

Refund statuses are pending, approved, rejected, and processed.

Money contract

amount is a JSON string containing a positive integer in the payment currency’s minor units. Do not send a JSON number, decimal point, sign, currency, or thousands separators.
  • "5000" means 5,000 minor units.
  • Omitting amount requests the complete refundable remainder calculated at execution time.
  • Currency is resolved from the payment and cannot be overridden.
  • The requested amount cannot exceed the current payment remainder after all processed partial refunds.
  • The largest accepted value is 9223372036854775807, the PostgreSQL signed bigint limit.
Always keep refund money as integer strings. Values such as "9007199254740993" are valid but cannot be represented exactly by a JavaScript number; preserve the string through signing, storage, retries, webhook handling, and reconciliation.

Request a refund

Use a stable, merchant-generated params.identifiers.c_id. It is the durable creation idempotency key.
Example result:

Safe retries and partial refunds

If refund.request times out, retry the exact body with the same c_id, a fresh timestamp, and a fresh nonce. A committed request returns the same public refund result. Reusing that c_id with another amount, reason, notes, or payment returns code 1013. Only one active pending or approved request is allowed for a payment. After a partial request becomes processed, you may create another request with a new c_id; the available amount is calculated from the current cumulative remainder under a database lock. Do not create a new c_id while the status of a timed-out request is unknown. First query:

List and summarize

refund.list accepts statuses, one payment reference, created_from, created_to, limit, and an opaque cursor:
The response contains items and next_cursor, never a full total. Use refund.summary with optional ISO 8601 created_from/created_to to obtain by_status counts.

Refund comments

Refund comments are a separate merchant-visible conversation store. Adding a comment does not create or link a support ticket and does not approve or process the refund.
Use refund.comments.list with the refund identifier, optional limit, and optional cursor. Returned comments contain a public comment h_id, author (merchant or support), body, and timestamps.

Error handling

Best practices

  • Generate refund c_id values on your server before the first attempt and persist them with the order.
  • Keep amounts as decimal digit strings at database, queue, and JSON boundaries, including values above JavaScript’s safe-integer limit.
  • Reconcile on both refund h_id and payment h_id; never use internal numeric IDs.
  • Treat processed_amount as an observed result, not permission to calculate a new refund without querying current state.