Skip to main content
This feature is in Beta. Behavior may change before general availability, and production access depends on your RadiumOne rollout. Contact support to confirm availability for your account.
A standalone (or “open”) refund credits a card with no original RadiumOne transaction to bound the amount, the card, or the timing — you supply the card token and amount directly. It’s the escape hatch for refunding an order that was never paid for through RadiumOne (a legacy order, a goodwill credit, a chargeback pre-emption), not the normal refund path.
This is a high-risk operation. Because there’s no original transaction, RadiumOne can’t cap the amount, enforce a time window, or confirm the refund matches the card that was originally charged. Every secret key holds the transaction-refund-unreferenced scope by default — the scope itself isn’t what protects you, the acquirer channel/device enablement gate is. Once enabled, anyone holding that key can credit any card token for any amount, at any time. Prefer Refund a payment whenever an original transaction exists.
This request requires a valid access token. See Authentication to obtain one with POST /v1/auth/token before you continue.
This is a high-risk operation. Follow these practices:
  • Least privilege: request a secret key scoped to only the operations it needs, not a key with every scope.
  • Key storage: store secret keys in a server-side secrets manager, never in client code, source control, or logs.
  • Emergency revocation: if a key is compromised, rotate or revoke it immediately — see Emergency key revocation.
  • Monitoring: monitor refunds and settlements for unexpected activity and alert on anomalies.

Request fields

Same shape as a purchase: request_id, amount, card, channel, plus optional order_reference (up to 128 characters) and reason (up to 200 characters) for your own records.
Amounts are always integers in the currency’s minor unit. For example, 5000 for SGD means SGD 50.00.

Steps

1

Issue the refund

Use a secret key scoped to transaction-refund-unreferenced. The outlet must also be enabled for standalone refunds at the acquirer/terminal level. API reference.
If the operation isn’t enabled for your outlet, see Fix operations unavailable for your outlet.

Handle the result

Any 2xx response is a result you must branch on status — never on response_code (that’s the verbatim host/acquirer code; useful for support tickets, not for your app logic).
Balance inquiry also takes a request_id field, but it isn’t an idempotency key — there’s no dedup or replay store. Every call re-queries the rewards host, even with the same request_id.
Keys are 8–64 characters, [a-zA-Z0-9-] only, unique per merchant account. Generate one key per order attempt and persist it to your database before you send the first request — never mint a new key just to retry the same attempt. See Prevent duplicate payments.
PENDING means the outcome isn’t known yet — most often after a processor timeout. Don’t assume success or failure. Recover it one of two ways:
  1. Wait for a webhook (payment.*, authorization.*, refund.* — see Webhook event types).
  2. Call GET /v1/transactions/{id}/status for a live inquiry against the acquirer.
If you don’t have the transaction id yet — a client-side timeout before the first response arrived — replay the same request with the same request_id and body. The replay returns the stored transaction and its id, whatever status it’s reached. Never re-submit with a new idempotency key just because the first attempt is slow — that risks a second charge for the same order. Unlike a referenced refund, a standalone refund is a create-type operation: it returns 201 on success (and on a replay with the same request_id), matching purchase and authorize.

Errors

Full HTTP status and meaning for each of these is defined once on Problem format and retries — this list is only the standalone-refund-specific nuance:
  • auth:insufficient-scope — your key’s token doesn’t have the transaction-refund-unreferenced scope
  • routing:operation-disabled — standalone refunds aren’t enabled for any terminal that can route this request
  • device:operation-not-supported — the routed terminal has this operation toggled off
  • gateway:validation-error
  • transaction:idempotency-body-mismatch — same body-hash comparison as purchase and authorize: request_id, amount, currency, payment_method_type, channel_type, the card’s pan_prefix (first 8 digits, not the full token), metadata, and order_reference are hashed and compared. reason and the full card token aren’t hashed, so changing either on a retry still replays the original silently.

Voiding a standalone refund

A standalone refund is its own transaction and follows the same void-or-refund rule as any other capture: you can void it while its settlement batch is still open, and you can’t once it closes.

Monitoring

Because a leaked or over-scoped key can issue standalone refunds silently, treat refund volume and amount as a security signal, not just a finance one:
  • Alert on any standalone refund above your normal order size, or on a burst of them in a short window.
  • Reconcile standalone refunds against a real business reason (the goodwill credit, the chargeback case) — an unexplained one is an incident, not a bookkeeping question.
  • Review who holds keys scoped to transaction-refund-unreferenced on a regular cadence, and remove the scope from any key that doesn’t need it.

Test your integration

See Test your integration once enablement is confirmed for your sandbox outlet.

Go-live notes

  • Request a key scoped to only transaction-refund-unreferenced (not a general-purpose key) for whatever service issues these refunds.
  • Log every standalone refund with the business reason before you call the API, not after.
  • Review the full go-live checklist.

Next steps

Refund a payment

Use the referenced refund whenever an original transaction exists.

Security and PCI scope

Key storage, rotation, and emergency revocation guidance.
Last modified on September 15, 2026