API reference
Refunds
Refund a session in full or in part, as many times as needed, up to what it received. SaphraONE is non-custodial and never moves a merchant’s money, so your server requests a refund and the merchant approves and sends it in SaphraONE.
How a refund works
Request it
POST /v1/refundsreturns a refund with statusrequested. Its amount is reserved at once, so refunds can never add up to more than the session received.The merchant sends it
The business gets a notification and a Refund request in Checkout. They send it from their business wallet, or decline it (cancelled). Merchants can also start refunds themselves in SaphraONE.It succeeds
Once the transfer is verified on chain the refund becomessucceededwith itstx_hash, the session’samount_refundedgoes up, and a refund.succeeded webhook is sent.
The refund object
Fields
idstring- Unique id,
re_live_…orre_test_…. objectstring- Always
refund. sessionstring- The checkout session refunded.
amountstring- Decimal string in the session currency.
currencystringUSDCorEURC.statusenumrequested(waiting for the merchant),succeeded(sent and verified on chain) orcancelled(declined by the merchant).destination_walletstring- The Arc wallet the refund goes to.
tx_hashstring | null- The refund transaction once
succeeded, else null. reasonstring | null- Why, up to 200 characters, or null.
created_at, succeeded_atstring | null- ISO 8601 timestamps.
{
"amount": "10",
"created_at": "2026-10-18T10:02:11.000Z",
"currency": "USDC",
"destination_wallet": "0x8f3c…a21d",
"id": "re_live_4h7k2m9q8x3c5vtn1rj6bdwz",
"object": "refund",
"reason": "Item out of stock",
"session": "cs_live_4f9k2m7q1x8v4b6n0c5d2h7j",
"status": "requested",
"succeeded_at": null,
"tx_hash": null
}Request a refund
POST/v1/refunds
Body parameters
sessionstringrequired- The checkout session to refund.
amountstring- Decimal string. Defaults to everything still refundable; at least 0.01.
destination_walletstring- The buyer’s Arc wallet. Optional when the buyer paid from a wallet or a SaphraONE account (the refund goes back to it). Required when they paid by card, bank or from another chain, because then the paying wallet isn’t the buyer’s.
reasonstring- Shown to the merchant, up to 200 characters.
curl https://api.saphra.one/v1/refunds \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{"session": "cs_live_4f9k2m7q1x8v4b6n0c5d2h7j", "amount": "10", "reason": "Item out of stock"}'Retrieve a refund
GET/v1/refunds/{id}
curl https://api.saphra.one/v1/refunds/re_… \
-H "Authorization: Bearer sk_live_…"List a session’s refunds
GET/v1/refunds?session={id}
Returns {object: "list", data, has_more}, oldest first. Every refund also appears in the session’s own refunds array.
curl "https://api.saphra.one/v1/refunds?session=cs_live_4f9k2m7q1x8v4b6n0c5d2h7j" \
-H "Authorization: Bearer sk_live_…"