Get StartedYour first order

First gaming top-up order

Place a gaming top-up against a player ID and poll until terminal

Gaming top-ups (PUBG UC, Free Fire diamonds, Mobile Legends, etc.) are identified by a player/account ID, sometimes plus a server/region. Unlike vouchers, fulfilment is mostly asynchronous — the order endpoint returns quickly, and status moves from PENDING to DELIVERED (or FAILED) over seconds to a few minutes.

Two requests after authentication: place the order, then poll the order endpoint until terminal.

This page assumes HOST and TOKEN are exported as described on the authentication step.

1. Place the order

input_data carries the per-product identifiers (player_id, optional server). Always send only the fields returned by GET /topups/products/:id under input_fields — unrecognised keys are rejected.

curl -X POST "$HOST/api/v1/topups/orders" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "product_id": 4218,
    "amount": 4.99,
    "input_data": {
      "player_id": "5123456789",
      "server": "asia"
    },
    "client_reference": "FIRST_GAMING_001"
  }'

The order endpoint returns immediately. The status field tells what to do next:

statusWhat it meansNext
PENDINGOrder accepted, fulfilment in progress. Typical.Move to step 2 — poll.
DELIVEREDFulfilled inside the request.Done.
FAILED (with is_user_fixable: true)Rejected — wrong player ID, suspended account, etc.Surface failure_reason. Wallet auto-refunded.

The wallet is debited synchronously

Even for PENDING orders, the wallet has already been charged. Only fulfilment is pending. Failed orders auto-refund — the debit and refund are separate transactions, both visible in the wallet log.

2. Poll until terminal

For PENDING orders, fetch the order until status reaches a terminal value.

ORDER_ID=9123456
while true; do
  resp=$(curl -s "$HOST/api/v1/topups/orders/$ORDER_ID" \
    -H "Authorization: Bearer $TOKEN")
  status=$(echo "$resp" | jq -r '.status')
  case "$status" in
    DELIVERED|FAILED|CANCELLED) echo "Terminal: $status"; break ;;
  esac
  sleep 5
done

The detail endpoint refreshes the latest status on each call for PENDING orders, so polling returns the freshest known state. Most gaming top-ups resolve within 5–30 seconds; if foreground polling hits its budget without terminating, Octopus Cards's retry loop keeps trying server-side — switch to a notification-based wait.

What just happened

  1. Created a top-up order with player-ID input. The wallet was debited synchronously.
  2. Polled the detail endpoint until the order reached DELIVERED / FAILED / CANCELLED.

Next

After completing this flow, the others are short cousins of the same pattern. Then:

On this page