Todas las entradas
Integration30 de junio de 2026 · 2 min de lectura

Seamless wallet integration in four endpoints

A practical walkthrough of the only server work a casino has to do to run our games — balance, debit, credit, rollback — plus the failure cases that actually bite in production.

Most game integrations are described as "simple" and then arrive as a sixty-page specification. This one really is four HTTP endpoints, and the interesting part is not the happy path — it is what happens when the network misbehaves.

The four endpoints

You implement these. We call them.

POST /wallet/balance    { player_id, currency }
POST /wallet/debit      { player_id, currency, amount, game, round_id, transaction_id }
POST /wallet/credit     { player_id, currency, amount, game, round_id, transaction_id }
POST /wallet/rollback   { player_id, currency, round_id, transaction_id }

Each returns the resulting balance. That is the entire contract. Your ledger stays authoritative — we never hold player funds, we only ask your system to move them and record what it says.

Idempotency is the whole game

Every mutating call carries a transaction_id that we generate and that is stable for that specific operation. If you have already applied a transaction with that ID, do not apply it again — return the balance you already have.

This sounds obvious and it is the single most common source of production incidents we see. The scenario is boring: we send a debit, your service applies it, the response is lost to a timeout, we retry, and a naive implementation debits the player twice. The player notices immediately, because players always notice.

Implement it as a unique constraint on transaction_id in your transactions table, not as an application-level check. A check-then-insert has a race window; a unique index does not. On conflict, look up the existing row and return its resulting balance.

The rollback case

A rollback voids a debit that will never be settled. It fires when a round is cancelled, when a game crashes mid-round, or when our settlement call to you fails so persistently that we give up and unwind.

Two rules make rollbacks safe:

  1. Rollback of an unknown transaction must succeed. If you never saw the debit, there is nothing to undo, and the correct answer is a 200 with the current balance. Returning an error here causes us to retry forever.
  2. Rollback must be idempotent too. Same reasoning as above, same unique constraint, keyed on the rollback's own transaction_id.

Together these mean the unwind path converges no matter what order things arrive in.

Currency and amounts

Amounts are decimal strings, not floats. "1.00", not 1.0. If your wallet speaks integer minor units, convert at the boundary and be explicit about the scale for each currency — eight decimals for BTC, two for USD, six for USDT on most chains.

We never convert between currencies. A bet placed in EUR settles in EUR. If a player switches currency, that is a different balance in your wallet and, as far as we are concerned, a different sequence of rounds.

What we handle

Everything above the wallet: round lifecycle, the fairness commit-reveal, multiplayer synchronisation for Crash, reconnects when a player's phone drops off Wi-Fi mid-round, replaying the current state so the board looks right when they come back, and the per-currency bet limits you configure.

You do not implement game logic. You do not store round state. If a player reloads during a Mines round, we restore it; your wallet is not involved because no money moved.

Getting it wrong safely

Start in the sandbox, which is a full environment with every game and play money. It is the same code path as production with a different key. Our certification suite deliberately does the nasty things: duplicate transaction IDs, out-of-order settlement, rollbacks for debits that never existed, concurrent bets from the same player, and a debit that times out on your side but succeeds. If your wallet survives that, it will survive a Saturday night.

Most teams get through it in two to five working days with one backend engineer. The ones that take longer are usually not fighting the API — they are waiting on their own release process.