Skip to content

Integration Checklist ​

Items for the operator to verify before go-live. During certification, we check them together using this list.

Signing and security ​

  • [ ] All 3 test vectors (POST, GET with an encoded query, wallet debit) match the expected signatures.
  • [ ] The API secret is used as the key as the 64-character string, as is, without hex-decoding.
  • [ ] The signed body bytes are identical to the body bytes actually sent (no double serialization).
  • [ ] Query values are percent-encoded (+ → %2B), and that exact string is signed.
  • [ ] X-Api-Key is included on every Operator API request.
  • [ ] A new timestamp, nonce, and signature are generated on retries.
  • [ ] The operator server clock is synchronized with NTP (tolerance ±5 minutes).
  • [ ] The API key and API secret exist only in the server configuration and never appear in browser code, apps, repositories, or logs.
  • [ ] The public IPs of all servers that call the Operator API are registered in the IP allowlist.
  • [ ] The wallet URL uses HTTPS, and the firewall allows the platform's outbound IPs for wallet callbacks.
  • [ ] Switched to the production credentials, base URL, and game screen origin (no test values remain).

Wallet callbacks — common ​

  • [ ] Callback signatures are verified with the raw body bytes, and X-Operator, the timestamp (±5 minutes), and a constant-time comparison are all checked.
  • [ ] Callback nonces are kept for at least 5 minutes in storage shared by all servers, and reuse is rejected.
  • [ ] Even if a reverse proxy rewrites the path, the signature is verified using the original path of the registered wallet URL.
  • [ ] All business outcomes, including rejections, are returned as HTTP 200 + a status in the body.
  • [ ] The response balance is the balance after processing, as an integer in the currency's minor unit.
  • [ ] tx_id idempotency: when an already processed tx_id arrives again, the balance is not changed again and the same response as the first time is returned (the same rejection if it was rejected).
  • [ ] Concurrent processing of transactions for the same player does not corrupt the balance (DB transactions, row locks).
  • [ ] Response times are short enough — the platform waits 3 seconds for balance and debit, and 5 seconds for credit and rollback.
  • [ ] The wallet ledger records tx_id, round_id, reason, amount, and the processing result so that reconciliation is possible.

balance ​

  • [ ] Responds with PLAYER_NOT_FOUND for a nonexistent player and CURRENCY_MISMATCH when the currency differs.

debit ​

  • [ ] If the balance is insufficient, nothing is deducted and INSUFFICIENT_FUNDS is returned.
  • [ ] Players who are blocked or self-excluded are rejected with PLAYER_BLOCKED.
  • [ ] If a debit arrives late for a tx_id whose rollback has already arrived, nothing is deducted and TX_ALREADY_ROLLED_BACK is returned.
  • [ ] The implementation assumes that when a debit ends in a timeout, an HTTP error, or UNKNOWN_ERROR, the platform does not retry the debit and sends a rollback immediately.
  • [ ] The reason (bet, ante, double, split, buy_in, top_up) is recorded in the ledger.

credit ​

  • [ ] A credit with amount 0 (settlement of a lost round) is processed normally and OK is returned.
  • [ ] Credits are applied even to blocked players (wins and cash-outs from a game in progress).
  • [ ] You understand that a credit is retried indefinitely unless it returns OK, regardless of status, and you never return a status other than OK for a valid transaction.
  • [ ] Even if the same tx_id repeats at the retry intervals (1s → 2s → 5s → 15s → 1 min → 5 min, then every 5 minutes), it is applied only once.

rollback ​

  • [ ] The original debit is looked up by ref_tx_id.
  • [ ] If the original debit succeeded, its amount is reversed and OK is returned.
  • [ ] If there is no record of the original debit (the debit never arrived), nothing is reversed and OK is returned, and that ref_tx_id is recorded so that a late-arriving debit is rejected.
  • [ ] If the original debit was already reversed or was rejected, it is not reversed again and OK is returned.
  • [ ] The implementation assumes that a rollback is also retried indefinitely unless it returns OK.
  • [ ] The reason (cancel_bet, round_void, timeout, system) is recorded in the ledger.

Failure scenarios ​

During certification, it is useful to deliberately inject failures into a test wallet and verify the following.

  • [ ] Delay the debit response by more than 3 seconds → the bet or seating fails, a rollback (timeout) arrives, and the balance returns to its original value.
  • [ ] Return HTTP 500 for a debit → same as above.
  • [ ] Return HTTP 500 for a credit a few times and then respond normally → through retries it is ultimately applied exactly once.
  • [ ] Sending the same tx_id twice changes the balance only once.
  • [ ] Even if the wallet server goes down briefly and comes back up, all pending credits and rollbacks are applied after it recovers.

Game launch ​

  • [ ] POST /launch is called only from the operator server.
  • [ ] A new launch_url is obtained every time the player clicks (60 seconds, single use) and opened exactly as received.
  • [ ] A new window is opened directly inside the click handler, and noopener is not used.
  • [ ] If embedding in an iframe, the embed domain is registered and the iframe is closed when game.closed is received.
  • [ ] A return_url is sent or a default return URL is registered (without either, no postMessage messages are sent).
  • [ ] When receiving postMessage messages, event.origin and data.source === "games-platform" are checked.
  • [ ] external_id is a value that never changes for a given player and is 64 bytes or less.
  • [ ] nickname is sent within 2–16 characters.
  • [ ] The fact that a player's currency is fixed (CURRENCY_MISMATCH) is taken into account.
  • [ ] operator_session_id uses an opaque ID rather than the raw login token.
  • [ ] Launch errors such as PLAYER_BLOCKED, GAME_MAINTENANCE, and TABLE_NOT_FOUND are communicated appropriately to the player.

Player management ​

  • [ ] POST /players/{external_id}/logout is called on site logout, self-exclusion, and account suspension (block: true for suspension).
  • [ ] When lifting a suspension, it is called again with block: false.

Reconciliation and operations ​

  • [ ] Wallet transactions for a period are fetched with GET /transactions and matched against your own wallet ledger per tx_id (a scheduled job).
  • [ ] Transactions in pending and uncertain status are reviewed separately during reconciliation.
  • [ ] If you need a bet history screen, use GET /rounds and GET /rounds/{round_id}.
  • [ ] Under prepaid operation, the prepaid credit balance is monitored with GET /credit, and a top-up is requested before it drops below the warning threshold (warn_below).
  • [ ] Operator API 429 and 5xx responses are retried after a wait (for write requests, check the result first).
  • [ ] The contact person and channel for outages and reconciliation mismatches have been decided.

Docs v1.0.0 · Operator API v1