FoxReload Order Flow Explained — Reservation, Fulfilment, Delivery
If you are integrating FoxReload at scale, you need to model order state carefully on your side: customer support, refunds, and reconciliation all hinge on understanding what each state means and when transitions happen. This article walks through the full FoxReload order flow as it actually runs in production.
The five states
Every order moves through up to five states. Most happy-path orders complete in under 60 seconds.
| State | Meaning | Typical duration |
|---|---|---|
pending |
Order created, awaiting balance check | <1 s |
reserved |
Stock locked, FX rate locked for 15 min | 0–5 s |
processing |
Supplier fulfilment in flight | 1–60 s |
delivered |
Code/PIN returned and signed | terminal |
failed |
Reservation or fulfilment failed | terminal |
The state machine is strictly forward-only — a delivered order cannot revert to processing. Refunds are a separate object (POST /v1/refunds) that does not change order state.
1. Pending → reserved
When you call POST /v1/orders with a sku, quantity, and idempotency_key, FoxReload first validates your balance and locks stock at the upstream supplier. The FX rate (for non-USD SKUs) is locked at this moment and held for 15 minutes — long enough for downstream retries without giving you free re-pricing.
A successful reservation returns HTTP 201 with status: "reserved" and the locked unit_price_usd. If your balance is insufficient you get HTTP 402 insufficient_funds; if the SKU is out of stock, HTTP 409 out_of_stock.
2. Reserved → processing → delivered
The reservation is dispatched to the supplier within ~200 ms. The supplier returns codes either synchronously (within the same HTTP round-trip, most gift cards) or asynchronously (eSIM activations, some regional PSN codes — up to 60 s).
When delivery succeeds, FoxReload fires the order.delivered webhook with the payload:
{
"event": "order.delivered",
"order_id": "ord_8f2c91",
"codes": [
{ "type": "pin", "value": "ENCRYPTED_PAYLOAD", "redeem_url": "..." }
],
"delivered_at": "2026-05-18T10:24:31Z"
}
Code values are encrypted at rest with a per-order data key — decrypt them server-side using your webhook_secret and an AES-GCM helper from the SDK.
3. The failed path
Failures fall into three buckets, each with a distinct failure_reason code:
supplier_timeout— upstream did not respond in 60 s. Auto-refunded to your balance within 10 minutes.invalid_region— buyer region mismatch (rare; usually a routing bug on your side).stock_revoked— supplier revoked stock between reservation and fulfilment.
All failed orders return funds to your account automatically. There is nothing to do on your side except update your UI and notify the buyer.
Want to see the full state diagram and try sample webhook payloads in the sandbox? Sign up at foxreload.com — sandbox keys are free and let you simulate every state transition, including induced failures, before going live.
