Game Top-Up API — Order Processing Flow
Top-ups are the one digital-goods category where you deliver an action on somebody else's account rather than a product. There is no code, no undo, and the recipient is determined by a string the buyer typed by hand. Below is the full processing flow for such an order, and the places where that difference breaks an architecture copied from selling keys.
How a top-up differs from a code
| Property | Gift card / key | Account top-up |
|---|---|---|
| What the supplier returns | A code string | A confirmation of credit |
| Can you hold the goods | Yes, the code sits with you | No, the credit is instant and targeted |
| Recipient determined by | Whoever you gave the code to | The ID the buyer entered |
| Reversal after fulfilment | Sometimes possible via the issuer | Practically impossible |
| Primary risk | Code fails to redeem | Currency landed on the wrong account |
From which follows the central design rule: all protection moves to the stage before you take money. With codes you can fix a lot after the fact. With top-ups, almost nothing.
Step 1. Validating the player ID before you charge
This is the most important part of the whole integration, and it lives entirely on your side.
Format validation
The minimum you must check before taking money:
- Length and character set. Every game has its own identifier format — digits only in some, alphanumeric in others, sometimes with a separator.
- Server or region. Many games require a server or zone alongside the ID. Without it the top-up lands in the wrong place or fails outright.
- Junk. Leading and trailing whitespace, a pasted "ID:" prefix, stray characters from a messenger. Normalise the string before sending it.
Account existence check
Some suppliers expose a dedicated identifier-check endpoint that returns the player's nickname. Some do not, and availability varies by game. Ask your supplier whether that check exists for the games you sell.
Where it does, use it and show the buyer the nickname before payment. It is the cheapest dispute prevention available: someone who sees a stranger's name fixes their own ID.
Buyer confirmation
Even without a nickname lookup, a confirmation screen before the debit is mandatory. It shows:
- The ID exactly as it will be sent to the supplier.
- The region or server.
- An explicit statement that the credit is irreversible.
- A confirmation timestamp that goes into your log.
That log is your answer when a buyer claims a week later that they typed a different number.
Step 2. Placing the order
The order is created like any other, but with extra data on the line item:
curl -X POST "https://public-api.foxreload.com/api/orders" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"itemId": "product_01krgfgww8eth9xvvysd6y7r4j",
"quantity": 1,
"note": {"player_id": "123456"}
}
],
"isMock": false
}'
On FoxReload the player identifier travels in the line item's note field — an object accepting up to 10 keys of additional data. Which keys a specific product expects is described in its attributes and userGuide.
On idempotency. Some APIs accept an Idempotency-Key header so a resend cannot create a second order. Verify whether your supplier implements it — many do not. FoxReload does not, so a timeout on order creation must never trigger a blind retry: query the order list first and confirm nothing was created. On top-ups the cost of that mistake is higher than on codes — a duplicate means a second credit you will never recover.
Step 3. Asynchronous completion
The order moves through states sequentially and in one direction only:
| State | Meaning | What your system does |
|---|---|---|
active |
Order created, awaiting balance debit | Record order_id, start polling |
paid |
Balance debited | Nothing, keep waiting |
processing |
Supplier is crediting the account | Keep polling with backoff |
completed |
Currency credited to the account | Notify the buyer, close the order |
cancelled |
Order cancelled, see cancelReason |
Refund the buyer |
failed |
Fulfilment failed, see items[].error |
Classify the reason, decide refund or retry |
Status is retrieved by polling:
curl "https://public-api.foxreload.com/api/orders/{order_id}" \
-H "X-API-Key: YOUR_API_KEY"
Check whether your supplier offers webhooks. If they do, use them as an accelerator but keep polling as the source of truth, because delivery is never guaranteed. FoxReload does not support webhooks, so polling is the only mechanism here.
Polling shape: frequent for the first minute, then a widening interval, with your own deadline and a queue for orders that exceed it. That queue matters more for top-ups than anywhere else — a buyer who cannot see currency in-game contacts support faster than a buyer waiting on a key.
A deeper treatment of designing these state machines is in the order state machine article.
Step 4. Terminal versus retryable failures
Splitting failures into two classes is what separates a working integration from one that burns money.
Terminal — retrying is pointless
- Invalid player ID. The account does not exist or the format is wrong. A retry returns the same answer. Refund the buyer, ask them to check the ID.
- Region not supported. The product cannot be credited to an account in that region. Refund.
- Product unavailable for that account. For example, a bundle not sold to players below a certain level, or not sold in that country.
- Auth and request-validation errors —
HTTP 400,401,403. That is your bug, not an outage.
On a terminal failure, remove the order from the polling loop immediately and hand it to your refund path.
Retryable — worth another attempt
HTTP 429— rate limit exceeded. Exponential backoff with jitter.HTTP 5xx— supplier-side fault. Backoff, bounded attempts.- Network timeout. Special care here: check the order's state first, decide second.
- Temporary game unavailability. Publisher maintenance is a classic cause of stuck
processing. Wait; do not re-create the order.
The mistake almost everyone makes early: treating a timeout as retryable and immediately placing a new order. On top-ups that means a double credit and money you will not get back.
Step 5. Refunds and reversals
Accept the reality plainly here: there is no automatic reversal of a credit.
The scenarios and what to do with them:
- Order reached
cancelledorfailedbefore crediting. You refund the buyer through your payment method; the supplier returns funds to your balance under their own rules — establish those rules in advance. - Credit succeeded but the buyer is unhappy. The goods were delivered. A refund here is a commercial decision, not a technical operation.
- Credit went to an ID the buyer entered wrongly. Technically unfixable. Your position is the confirmation log. This is precisely why the confirmation screen is not optional.
- Partial fulfilment on a multi-line order. Handle lines independently: keep what completed, refund what did not.
Budget a small reserve for disputed cases in your unit economics. At volume they are unavoidable, and it is better to see them as a line item than to be surprised by a margin dip. How to model that is covered in reseller unit economics.
Step 6. Reconciliation
Daily reconciliation is basic hygiene, not an optional extra.
Pull the supplier's order list:
curl "https://public-api.foxreload.com/api/orders/?statuses=completed,failed,cancelled&limit=100" \
-H "X-API-Key: YOUR_API_KEY"
And compare it against your own database. What to look for:
- Orders at the supplier that you have no record of. The classic fingerprint of a duplicate from a blind retry.
- Orders you still show as in-flight that the supplier has already terminated. Your poller broke or a process died.
- Amount mismatches. The price at order time differs from your record, meaning you are capturing price at the wrong moment.
- Balance debits with no matching order. Investigate immediately.
Reconciliation surfaces problems in hours rather than at month-end, when there is nothing left to reconcile against.
Where to source top-ups wholesale
Top-ups are worth sourcing from the same place as the rest of your range — one integration instead of several. FoxReload is a wholesale digital-goods supplier with 900+ SKUs covering game-account top-ups, gift cards, keys, eSIM and software licences, all behind one REST API with automated delivery and multi-region SKUs. One order model and one status vocabulary across every category, including products that require a player ID.
