Wallet
The wallet is the payment source for every order. It has separate USD, EUR and GBP balances. The API never auto-converts a wallet balance to cover an order in another currency.
Code
Required scope: wallet:read.
Balances
Code
| Field | Meaning |
|---|---|
postedMinor | Credited funds, including completed funding and refunds, minus completed debits. |
heldMinor | Funds reserved by an operation. Current wallet orders debit immediately, so this is normally 0. |
availableMinor | postedMinor - heldMinor. The order check uses this value. |
Amounts are integer minor units. currencyMode: native means balances are held in their own
currency; no conversion is applied at read time.
Paying for an order
An order is paid from the wallet in the quote currency. There are three possible outcomes:
- Enough available credit: the purchase is created, the wallet is locked, the debit and ledger
entry are written in the same transaction, and the order returns
completedorprocessing. - Not enough credit: the API returns
402 insufficient_funds. No purchase, child order or debit is created. - Price or stock moved: the API returns
409 price_changedor409 out_of_stock. No purchase or debit is created.
The target contract changes case 2 to 402 payment_required with a funding_url. That
shape is Planned and not returned by every deployment yet. Handle both insufficient_funds
and payment_required.
Fund the wallet
Code
Required scope: wallet:fund.
Code
amountMinor must be an integer from 1 to 1,000,000. currency must be USD, EUR or GBP.
The response is a hosted Stripe Checkout URL and a payment operation id.
Code
The wallet is not credited when this response is returned. Credit is issued only after the signed Stripe webhook confirms a paid session, exactly once per operation.
Gating
Stripe funding is behind a deployment flag and a configured Stripe account. When it is disabled:
| Status | Code | Meaning |
|---|---|---|
| 501 | capability_unavailable | Funding is deliberately disabled. |
| 503 | payment_pending | Stripe is not configured. |
| 409 | idempotency_conflict | That funding key is already paid or already used. |
Sandbox credit is added by RoamWorks staff. A live partner receives written wallet terms before funding is enabled. Direct card purchase and saved payment methods are not available through the partner API.
Funding rules
- Use a new
Idempotency-Keyper funding intent. Reuse it only for a retry of that intent. - Do not create a second funding session for the same intent with a new key.
- Do not treat
checkoutUrlas proof of payment. Poll the wallet or wait for the webhook. - The API and the dashboard share the wallet. A dashboard top-up and an API top-up both appear in the same balances and ledger.
- The funding hook does not accept card data and never returns card data. The card form is hosted by Stripe.
- Treat
checkoutUrlas a sensitive, short-lived URL. Do not post it in a public channel or send it to an unrelated service.
Sandbox
Sandbox wallets are isolated from live. Use a sandbox key and the test-mode funding path when it is enabled, or ask RoamWorks support for test credit. Sandbox balances and upstream fulfilment are not real money or real inventory.