Product API Single wallet vs transfer wallet
Single wallet vs transfer wallet
A technical comparison of the two wallet models used to connect an operator's player balance to a casino game API: who holds the money, which calls cross the network during a bet, how failures are recovered, and what you have to build on your side.
At a glance
| Aspect | Single wallet | Transfer wallet |
|---|---|---|
| Balance custody | Your database holds the only balance. The provider never keeps player funds. | The provider keeps a separate game balance. Funds move in and out with transfer calls. |
| Calls during a bet | Every bet and win triggers a server-to-server callback to you (balance, debit, credit, rollback). | None. The game runs against the provider-side balance. Calls happen only at transfer in and out. |
| Availability needed | Your wallet endpoints must answer every callback, normally within a few hundred milliseconds. If they are down, play stops. | Needed only for transfers. Rounds keep running if your system is briefly offline. |
| Consistency model | Your ledger is the real-time source of truth. Only game rounds need reconciliation, not balances. | Two ledgers that agree only at transfer boundaries. Needs transfer-level reconciliation. |
| Failure recovery | Timeouts are resolved by idempotent retries and rollback calls keyed by transaction ID. | Transfers are two-phase: pending, then success or failed. A status query resolves unknown outcomes. |
| Integration effort | Higher. You build and operate a low-latency callback service with idempotency and a ledger. | Lower. You call three or four REST endpoints, with no inbound traffic to secure or scale. |
| Player experience | One balance, no transfer step. Suits bonuses, cross-product play and live balance display. | Funds are moved in before play and out after. Adds a short delay and a risk of stranded balance if a player leaves mid-session. |
| Typical fit | Operators with their own wallet or platform and strict control over funds and promotions. | Operators who want a fast launch or do not have a real-time wallet service. |
Single wallet (seamless)
In the single wallet (seamless) model your system is the wallet. When a player places a bet the SSG API calls your callback endpoint, you change the balance in your own ledger, and you answer with the new balance. No funds ever leave your database.
Call flow
- Launch: your backend asks SSG for a game URL with a player ID and session token.
- Bet: for each round SSG calls debit with a unique txId. You check funds, write the ledger row and return the new balance.
- Win: SSG calls credit with the payout (which can be zero) for the same round.
- Failure: if a call times out SSG retries with the same txId, and after the retry limit it sends rollback.
Callback methods (illustrative)
| Method | Purpose | Key fields | Idempotent |
|---|---|---|---|
balance | Return the current player balance. | playerId, currency | Yes (read only) |
debit | Place a bet: subtract the amount. | playerId, txId, roundId, gameId, amount, currency | By txId |
credit | Settle a win: add the amount. | playerId, txId, roundId, amount, currency | By txId |
rollback | Cancel an earlier debit or credit after an error. | txId, refTxId | By txId |
Example debit request
{
"method": "debit",
"playerId": "p_839201",
"txId": "tx_20261007_000184",
"roundId": "r_77f3a1",
"gameId": "slots_fruit_01",
"currency": "MYR",
"amount": "2.50",
"ts": 1791338577,
"sign": "hex(HMAC-SHA256(secret, canonical))"
}Example response
{
"status": "OK",
"txId": "tx_20261007_000184",
"balance": "97.50",
"currency": "MYR"
}
// errors: INSUFFICIENT_FUNDS, PLAYER_NOT_FOUND,
// DUPLICATE_TX (return original result), INTERNAL_ERRORRules your wallet service must follow
- Idempotency
- A repeated debit or credit with the same txId must return the original result and must not move money again. Enforce it with a unique index on txId.
- Atomic ledger write
- Check balance, insert the ledger row and update the balance in one database transaction, so two concurrent bets can never overdraw.
- Rollback before debit
- A rollback can arrive for a txId you never saw because the original debit timed out. Store a tombstone so a late debit with that txId is rejected.
- Latency budget
- Aim for a p99 below 500 ms including network. Keep the callback path to one indexed read and one write, and keep reporting queries off it.
- Money format
- Treat amounts as decimal strings or integer minor units. Never use floating point, and validate currency against the player account.
- Bonuses and free spins
- A free spin is a debit of 0 followed by a credit of the win. Keep promotional balances separate from cash balance in your ledger.
- Security
- Verify an HMAC-SHA256 signature over the canonical request, reject stale timestamps, allowlist SSG source IPs, and require TLS 1.2 or higher.
- Reconciliation
- Compare daily round reports from SSG with your ledger by roundId. Differences point to missed callbacks or rollbacks.
Transfer wallet
In the transfer wallet model the provider keeps a game balance for each player. Your backend moves funds in before play and out afterwards. During play there are no callbacks to your system, so you only need outbound REST calls.
Call flow
- Transfer in: your backend calls transferIn with a unique txId and the amount. The result is PENDING or SUCCESS.
- Play: launch the game. All bets and wins change the provider-side balance with no callbacks to you.
- Transfer out: when the player leaves, call transferOut for the full balance and credit it back to your own ledger on SUCCESS.
- Unknown outcome: if a transfer call times out, query getTransferStatus with the same txId before doing anything else.
API methods (illustrative)
| Method | Purpose | Key fields | Idempotent |
|---|---|---|---|
transferIn | Move funds from your wallet into the player game balance. | playerId, txId, amount, currency | By txId |
transferOut | Move funds from the game balance back to your wallet. | playerId, txId, amount | all | By txId |
getBalance | Read the player game balance. | playerId | Yes (read only) |
getTransferStatus | Return PENDING, SUCCESS or FAILED for a txId. | txId | Yes (read only) |
Rules your backend must follow
- One txId per intent
- Generate the txId before the first call and reuse it for every retry. Never create a new txId until the status of the previous one is known.
- Debit your ledger first
- For transfer in, reserve the amount in your ledger before calling SSG, then confirm or release it when the status is final.
- Sweep stranded balances
- Run a job that finds players with a game balance and no active session, then transfers it out. This covers players who close the browser mid-session.
- Wagering and reports
- Because you see no bets live, calculate turnover, bonus wagering and risk limits from round reports pulled from SSG, not from callbacks.
- Reconciliation
- Match every transfer in and out against SSG records by txId, and alert on any PENDING older than your timeout.
- Security
- Sign requests with HMAC-SHA256, call only over TLS 1.2 or higher, keep API keys in a secret store, and restrict which of your servers may call SSG.
Failure scenarios
| Scenario | Single wallet | Transfer wallet |
|---|---|---|
| Network timeout | During a bet SSG retries the same txId, then sends rollback after the retry limit. You must be idempotent. | Only transfers are affected. Query getTransferStatus with the same txId, then act. |
| Your system is down | Players cannot start or continue rounds. Open rounds are rolled back. | Players keep playing with their existing game balance. New transfers are blocked. |
| Duplicate request | Return the stored response for that txId and change nothing. | Return the stored result for that txId and change nothing. |
| Player disconnects mid-round | The round finishes at the provider and the credit is sent as normal. | The round finishes and funds stay in the game balance until a transfer out or the sweep job. |
| Balance mismatch | Usually a missed callback or rollback. Found by comparing round reports by roundId. | Usually a stranded or pending transfer. Found by comparing transfers by txId. |
Which one should you choose
Choose single wallet if
- You already run a real-time wallet or ledger service.
- You need one balance across sportsbook, casino and promotions.
- You need live bet data for risk, bonus wagering or responsible-gaming limits.
- Your team can run a low-latency service with high availability.
Choose transfer wallet if
- You want to launch quickly with the least engineering.
- You do not have a real-time wallet service yet.
- You prefer outbound calls only, with no public callback to secure.
- Short stranded-balance windows are acceptable and you can run a sweep job.
Many operators start on transfer wallet to go live, then move to single wallet once their own wallet service is ready. Ask us how the switch is staged.
Integration checklist
- Unique index on txId and idempotent handlers for every money-moving call
- HMAC signature check, timestamp tolerance and IP allowlist
- Decimal-safe amounts and currency validation
- Timeout, retry and rollback tests in the sandbox, including a late retry
- Daily reconciliation job by roundId (single) or txId (transfer)
- Monitoring and alerts: callback latency, error rate, pending transfers, stranded balances
Talk to an integration engineer
We can walk your engineers through the sandbox and help you choose the model that fits your platform. Integration is guaranteed in under seven days.
Email sales Chat on Telegram Back to Product API
sales@ssggaming.com