Sandbox — Referência completa da Seamless Wallet
Documentação campo a campo dos 8 endpoints do sandbox, com exemplos de request e response, dicas de integração, erros esperados, headers obrigatórios e injeção de falhas. Se você consegue rodar contra este ambiente, sua integração vai passar em produção sem surpresa.
Base URL
https://sandbox.i-gaming.co/api/public/v1/sandbox/walletTodos os endpoints ficam sob este prefixo. É público, roda no edge global, certificado TLS válido — sem VPN, sem allowlist.
Autenticação
Cada request POST exige o header x-signature = HMAC-SHA256 do body cru, usando SANDBOX_WALLET_HMAC_SECRET. Sem assinatura ou com body alterado ⇒ 401 invalid_signature.
Idempotência
debit, credit e rollback exigem x-idempotency-key. Repita o mesmo header com o mesmo body para receber a resposta original — não duplica saldo.
Headers obrigatórios
Todo POST passa por assinatura HMAC. GET (/stats, /reset) não exige assinatura.
Headers HTTP
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| content-type ex.: application/json | string | sim | Sempre application/json. Body precisa ser JSON minificado. Se o servidor rejeitar com invalid_signature mesmo com secret certo, garanta que você está assinando o MESMO byte-for-byte do que enviou (sem re-serializar). |
| x-signature ex.: 9ef2c1...b7a4 | string (hex) | sim | HMAC-SHA256 do body cru, hexadecimal minúsculo, 64 chars. Assine ANTES de qualquer transformação do body. Se usar interceptors HTTP, assine no último passo. |
| x-idempotency-key ex.: bet_round_2026_07_14_001 | string | não | Chave única por operação financeira. Obrigatório em /debit /credit /rollback. Use o round_id + tipo (ex.: bet_r_123, win_r_123). Se falhar timeout, reenvie o MESMO header — a resposta será a original, sem duplicar. |
| x-timestamp ex.: 1783996311137 | int (unix ms) | não | Timestamp da requisição em milissegundos Unix. Opcional no sandbox, recomendado em produção. Ajuda a debugar clock skew. Se seu clock estiver > 5 min do real, a integração em produção pode rejeitar. |
Endpoints
/authenticateAbrir sessão do jogador
Valida o launch token, cria/recupera o jogador no sandbox e devolve currency + timestamp. Chame no primeiro contato do launch iframe.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/authenticateRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Identificador único do jogador na sua plataforma. Pode ser numérico ou UUID. O sandbox aceita qualquer string; guarde o mesmo user_id nas próximas chamadas. |
| token ex.: launch_token_demo | string | sim | Launch token emitido pelo seu backend. No sandbox qualquer string não vazia é aceita. Em produção, este token é validado por HMAC e tem TTL curto (5-15 min). Gere no momento do launch, não guarde em cache. |
| currency ex.: BRL | string (ISO-4217) | não | Moeda da sessão. Default BRL. Suporte: BRL, USD, EUR, ARS, MXN, AUD, MYR, PHP, VND, IDR, THB, JPY, KRW, INR e outras 30+. A moeda define a divisão em unidades menores (BRL/USD = centavos; JPY/KRW/VND = inteiro). |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| ok | boolean | sim | true = sessão criada. |
| user_id | string | sim | Ecoa o user_id recebido. |
| currency | string | sim | Moeda que o sandbox associou a este jogador. |
| ts | int (unix ms) | sim | Timestamp do servidor no momento da resposta. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/authenticate
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"user_id": "player_42",
"token": "launch_token_demo",
"currency": "BRL"
}HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"user_id": "player_42",
"currency": "BRL",
"ts": 1783996311137
}Erros possíveis
{
"ok": false,
"error": "invalid_signature"
}- Chame /authenticate uma vez por sessão. Depois use /balance pra ler saldo.
- user_id novo? O sandbox cria com saldo inicial de 10 000 (unidades menores).
- token no sandbox aceita qualquer string; em produção precisa ser HS256 válido.
/balanceConsultar saldo
Retorna o saldo atual do jogador na moeda pedida. Não altera estado.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/balanceRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Jogador cujo saldo será consultado. |
| currency ex.: BRL | string | não | Moeda do saldo. Default BRL. Se o jogador não existe ainda, o sandbox cria com saldo inicial de 10 000 (unidades menores da moeda). |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| user_id | string | sim | Jogador consultado. |
| balance | int | sim | Saldo em unidades menores (centavos p/ BRL). SEMPRE trate como inteiro. Dividir por 100 só na UI. Guardar como float é bug garantido. |
| currency | string | sim | Moeda do saldo. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/balance
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"user_id": "player_42",
"currency": "BRL"
}HTTP/1.1 200 OK
content-type: application/json
{
"user_id": "player_42",
"balance": 10000,
"currency": "BRL"
}- 10000 = R$ 100,00 (BRL usa 2 casas decimais).
- Não use /balance pra decidir se pode debitar. O /debit já valida atomicamente — usar /balance antes cria race condition.
/debitDebitar aposta
Retira amount do saldo do jogador de forma atômica. Idempotente por x-idempotency-key. Retorna insufficient_funds sem alterar saldo se não há fundos.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debitRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Jogador que vai apostar. |
| amount ex.: 100 | int (>=0) | sim | Valor da aposta em unidades menores. Sempre inteiro positivo. Amount = 0 é aceito (rodada bônus). Amount negativo é rejeitado. |
| currency ex.: BRL | string | sim | Moeda da aposta. Precisa bater com o saldo do jogador. |
| round_id ex.: round_2026_07_14_001 | string | sim | ID da rodada de jogo. Uma rodada = 1 débito + 0..N créditos + 0..1 rollback. Use o mesmo round_id no /credit e /rollback correspondentes — é como o sandbox relaciona bet ↔ win. |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| status | "ok" | "insufficient_funds" | "duplicate" | sim | Resultado da operação. |
| balance_after | int | sim | Saldo do jogador após o débito. |
| operator_tx_id | string | sim | ID interno gerado pelo sandbox pra rastrear a transação. Guarde este ID nos seus logs. Útil pra debugar reconciliação. |
| idempotency_key | string | sim | Ecoa o x-idempotency-key da chamada. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: bet_round_2026_07_14_001
{
"user_id": "player_42",
"amount": 100,
"currency": "BRL",
"round_id": "round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 9900,
"operator_tx_id": "op_a7f3c9b1",
"idempotency_key": "bet_round_2026_07_14_001"
}Erros possíveis
{
"status": "insufficient_funds",
"balance_after": 50,
"operator_tx_id": "op_...",
"idempotency_key": "bet_..."
}{
"status": "duplicate",
"balance_after": 9900,
"operator_tx_id": "op_a7f3c9b1",
"idempotency_key": "bet_round_2026_07_14_001"
}- Ao receber timeout/5xx, reenvie o MESMO x-idempotency-key. Nunca gere uma nova.
- duplicate NÃO é erro — significa que a operação original foi aplicada e você está seguro.
- Se seu jogador clica 3x em spin, o mesmo idempotency-key protege de débito duplicado.
/creditCreditar prêmio
Adiciona amount ao saldo do jogador (win, cashout, bônus). Idempotente. bet_id liga ao /debit original.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/creditRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| user_id ex.: player_42 | string | sim | Jogador que vai receber o prêmio. |
| amount ex.: 250 | int (>=0) | sim | Valor do prêmio em unidades menores. |
| currency ex.: BRL | string | sim | Moeda do prêmio. |
| bet_id ex.: bet_round_2026_07_14_001 | string | sim | x-idempotency-key do /debit que originou este prêmio. Sem bet_id o sandbox aceita (retorna ok), mas em produção você quer sempre ligar win ↔ bet pra reconciliação. |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| status | "ok" | "duplicate" | sim | Resultado. |
| balance_after | int | sim | Saldo do jogador após o crédito. |
| operator_tx_id | string | sim | ID interno do sandbox. |
| idempotency_key | string | sim | Ecoa o x-idempotency-key. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/credit
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: win_round_2026_07_14_001
{
"user_id": "player_42",
"amount": 250,
"currency": "BRL",
"bet_id": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 10150,
"operator_tx_id": "op_e2d4a8f0",
"idempotency_key": "win_round_2026_07_14_001"
}- amount = 0 é aceito (rodada sem prêmio ainda gera evento pra fechar contabilidade).
- Vários /credit no mesmo bet_id são permitidos (freespins, respins). Use idempotency-key distinta em cada.
/rollbackDesfazer operação
Reverte um /debit (devolve valor ao jogador) ou um /credit (retira valor do jogador). Só funciona uma vez por original_key.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/rollbackRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| original_key ex.: bet_round_2026_07_14_001 | string | sim | x-idempotency-key da operação original que você quer desfazer. Rollback só funciona uma vez por original_key. A segunda tentativa retorna status=already_rolled_back. |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| status | "ok" | "not_found" | "already_rolled_back" | sim | Resultado do rollback. |
| balance_after | int | sim | Saldo após o rollback (crédito revertido, débito devolvido). |
| reverted_amount | int | sim | Valor devolvido/removido. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/rollback
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: rb_bet_round_2026_07_14_001
{
"original_key": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"status": "ok",
"balance_after": 10000,
"reverted_amount": 100
}Erros possíveis
{
"status": "not_found",
"balance_after": 10000,
"reverted_amount": 0
}{
"status": "already_rolled_back",
"balance_after": 10000,
"reverted_amount": 0
}- Use rollback quando o motor de jogo confirmar que a rodada não completou (crash da RNG, timeout no client, disputa).
- Não use rollback pra reajustar prêmio — use um novo /credit ou /debit compensatório com bet_id/round_id auditáveis.
/queryConsultar operação
Busca o status de qualquer operação pela sua idempotency_key. Use pra reconciliação, auditoria e recuperação de timeouts.
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/queryRequest — body / query
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| idempotency_key ex.: bet_round_2026_07_14_001 | string | sim | Chave da operação que você quer consultar (bet, win ou rollback). Use este endpoint como reconciliação diária: liste seus rounds locais, consulte cada um, compare status/amount. |
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| found | boolean | sim | false = não existe operação com essa chave. |
| kind | "debit" | "credit" | "rollback" | não | Tipo da operação. |
| status | "ok" | "rolled_back" | não | Estado atual. |
| amount | int | não | Valor da operação. |
| user_id | string | não | Jogador afetado. |
| round_id | string | não | Rodada relacionada. |
| balance_after | int | não | Saldo do jogador logo depois da operação. |
| processed_at | ISO-8601 | não | Quando a operação foi processada no sandbox. |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/query
content-type: application/json
x-signature: <hmac-sha256(body)>
{
"idempotency_key": "bet_round_2026_07_14_001"
}HTTP/1.1 200 OK
content-type: application/json
{
"found": true,
"kind": "debit",
"status": "ok",
"amount": 100,
"user_id": "player_42",
"round_id": "round_2026_07_14_001",
"balance_after": 9900,
"processed_at": "2026-07-14T02:31:52.812Z"
}- Timeout no /debit? Chame /query com a mesma key: se found=true e status=ok, a aposta foi aplicada — não retente.
- Passe ?div_rate=1 pra forçar o sandbox devolver dados divergentes e treinar seu código de reconciliação.
/statsEstatísticas agregadas
Retorna métricas agregadas do estado atual do sandbox (útil pra dashboards de load test).
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/statsRequest — body / query
Sem parâmetros — envie apenas os headers (HMAC não é exigido em GET).
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| ok | boolean | sim | true = stats disponíveis. |
| stats.users | int | sim | Total de jogadores criados no sandbox. |
| stats.ops | int | sim | Total de operações (debit + credit + rollback). |
| stats.balance | int | sim | Soma dos saldos de todos os jogadores. |
| stats.totalDebit | int | sim | Total apostado. |
| stats.totalCredit | int | sim | Total pago em prêmios. |
| stats.rtp | float | sim | RTP observado (totalCredit / totalDebit). Use pra sanity check. Rodou 1000 apostas de R$10 e o RTP saiu 0.35? Volume baixo — não é bug do jogo, é variância. |
| now | int (unix ms) | sim | Timestamp do servidor. |
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/stats
HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"stats": {
"users": 3,
"ops": 28,
"balance": 30550,
"totalDebit": 2400,
"totalCredit": 550,
"rtp": 0.229
},
"now": 1783996311137
}- Não exige HMAC. Endpoint público de leitura.
- Rode /stats antes e depois de um teste de carga pra medir throughput e RTP.
/resetLimpar estado do sandbox
Apaga todos os jogadores, saldos e operações. Use quando quiser começar um teste do zero.
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/resetRequest — body / query
Sem parâmetros — envie apenas os headers (HMAC não é exigido em GET).
Response — 200 OK
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| ok | boolean | sim | true = estado limpo. |
| reset | boolean | sim | true = confirmação do reset. |
GET https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/reset
HTTP/1.1 200 OK
content-type: application/json
{
"ok": true,
"reset": true
}- Reset é global no sandbox — todo mundo compartilha. Combine com sua equipe antes de rodar.
- Em produção não existe /reset. Não escreva código que dependa de resetar estado.
Injeção de falhas (query string)
Adicione estes parâmetros na URL de qualquer endpoint POST para simular condições reais de produção — latência alta, 5xx, timeouts, divergências. Ideal pra testar sua camada de retry, idempotência e reconciliação.
Query parameters
| Campo | Tipo | Obrig. | Descrição & dica |
|---|---|---|---|
| lat_min ex.: 50 | int (ms) | não | Latência mínima artificial adicionada antes de responder. Combine com lat_max pra simular jitter real de rede. |
| lat_max ex.: 800 | int (ms) | não | Latência máxima artificial. O sandbox sorteia entre lat_min e lat_max. lat_max=800 aproxima de latência de emergência real. lat_max=3000 estressa timeouts. |
| err_rate ex.: 0.1 | float 0..1 | não | Probabilidade de retornar HTTP 500 injected_5xx. 0.1 = 10% das chamadas. Ideal pra validar sua camada de retry. |
| timeout_rate ex.: 0.05 | float 0..1 | não | Probabilidade da resposta demorar 10s (força o timeout do cliente). Use pra validar que seu client cancela a request e depois faz /query pra recuperar o estado real. |
| insuff_rate ex.: 0.02 | float 0..1 | não | Probabilidade de /debit retornar insufficient_funds mesmo com saldo. Simula usuário que ficou zerado entre o /balance e o /debit. Teste sua UX de erro. |
| div_rate ex.: 0.1 | float 0..1 | não | Probabilidade de /query devolver dados divergentes do estado real. Serve pra estressar sua rotina de reconciliação — o valor real está no /stats. |
| rtp ex.: 0.97 | float 0..2 | não | RTP alvo informativo (não altera resultado das operações; útil apenas em dashboards). |
POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit?lat_max=800&err_rate=0.1&timeout_rate=0.05
content-type: application/json
x-signature: <hmac-sha256(body)>
x-idempotency-key: bet_stress_001
{"user_id":"player_42","amount":100,"currency":"BRL","round_id":"r_stress_001"}Códigos de status
Todo erro estruturado vem no body como { "ok": false, "error": "..." } ou como status dentro de uma resposta 200.
| Código | Quando acontece | O que fazer |
|---|---|---|
| 200 OK | Operação processada com sucesso. | Leia o campo status do body — pode ser ok, duplicate, insufficient_funds, etc. |
| 401 invalid_signature | x-signature ausente ou HMAC não bate com o body cru. | Verifique: (a) secret correto, (b) você está assinando o body byte-a-byte do que envia, (c) hex minúsculo. |
| 404 unknown_kind | Path final não é um dos endpoints suportados. | Confira o path — case-sensitive, sem barra final. |
| 405 use POST | Endpoint que exige POST recebeu GET. | Só /stats e /reset aceitam GET. Todos os outros são POST. |
| 500 injected_5xx | Falha injetada via err_rate. | Retente com backoff exponencial. Mesmo x-idempotency-key. |
| 500 error (real) | Erro inesperado (DB, RPC). Raro. | Guarde o response body. Rode /query com a mesma idem-key pra ver se aplicou. Contate suporte. |
Pronto pra integrar?
Baixe a Postman collection com todos os endpoints já configurados e pre-request script que assina HMAC automaticamente. Rode contra o sandbox, valide sua integração, depois fale com a gente pra ir pra produção.