Sandbox — test everything risk-free
Isolated environment with mock seamless wallet, real HMAC, failure injection and self-service reset. Validate your integration before going to production.
What's included
Isolated tenant
Dedicated sandbox operator, unlimited fake balance, data fully separated from production. Zero impact on real GGR.
Mock seamless wallet
authenticate, balance, debit, credit, rollback and query endpoints — identical protocol to production (PG Soft-style).
Real HMAC
SHA-256 signature identical to production. Validate your client before going live.
Failure injection
Configure latency, 5xx, timeout and insufficient balance via query string. Test retry, idempotency and rollback.
Self-service reset
Clear users, balances and transactions anytime via endpoint. Ideal for CI pipelines.
Docs + examples
cURL, Node/Python snippets, Postman collection and p50/p95/p99 metrics dashboard.
Sandbox Credentials
Duas chaves — uma pra abrir sessão (launch token) e uma pra assinar chamadas da Seamless Wallet. Confira o prefixo dos 12 primeiros caracteres pra garantir que colou o valor certo do seu lado.
IGAMING_API_TOKEN_SANDBOXBearer token pra abrir sessão no sandbox. Copie do painel do operador.
SANDBOX_WALLET_HMAC_SECRETAssina x-signature (HMAC-SHA256) nas chamadas /debit /credit /rollback.
Get started in 5 steps
Follow this guide to go from zero to a fully working seamless-wallet integration in minutes.
- 1
Request sandbox access
Ask for a sandbox tenant. You will receive a token prefixed with sk_sandbox_ and an HMAC secret. Store the secret safely — it is only shown once.
- 2
Configure your backend
Set SANDBOX_BASE_URL, SANDBOX_TOKEN and SANDBOX_HMAC_SECRET as environment variables in your wallet backend. Never commit them to git.
- 3
Sign every request
For every POST call, compute hex(hmac_sha256(raw_body, SANDBOX_HMAC_SECRET)) and send it as x-signature. Also send an x-idempotency-key so retries do not double-debit.
- 4
Run the scenarios
Exercise authenticate, balance, debit, credit and rollback. Then inject failures (err_rate, timeout_rate) to make sure your retry/rollback path works.
- 5
Promote to production
When all scenarios pass, request production credentials. The same code works — you only swap the base URL, token and HMAC secret.
Available endpoints
Same contract as production API. Just point your base URL to sandbox.
Routes
/authenticateValidates player session token
/balanceGets current balance
/debitDebits a bet (idempotent)
/creditCredits a win (idempotent)
/rollbackReverses a transaction by idempotency key
/queryQueries a transaction's status
/statsAggregated sandbox metrics
/resetResets mock state
https://sandbox.i-gaming.co/api/public/v1/sandbox/walletExample — bet debit
curl -X POST https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit \
-H "content-type: application/json" \
-H "x-signature: <hmac_sha256(body, SANDBOX_WALLET_HMAC_SECRET)>" \
-H "x-idempotency-key: round_123" \
-d '{"user_id":"demo_1","amount":100,"currency":"BRL","round_id":"r_1"}'Sign the raw body with HMAC SHA-256 using your SANDBOX_HMAC_SECRET. Send x-idempotency-key to ensure idempotency.
HMAC signing — step by step
Every request is authenticated with an HMAC-SHA256 signature over the raw request body. Follow these rules to avoid signature errors.
- Sign the RAW body bytes — not a pretty-printed or re-serialized version. If you parse and re-stringify JSON, whitespace changes and the signature breaks.
- Algorithm is HMAC-SHA256. Output is lowercase hex, 64 characters. No base64, no prefix.
- Send the signature in the x-signature header. Also send content-type: application/json.
- Send a unique x-idempotency-key per logical operation. Reusing the key returns the same response — safe to retry.
- Server tolerates ±5 minutes of clock skew. Make sure your servers are on NTP.
- Verify the response signature (x-signature header on our reply) to defend against MITM.
Node.js example
import { createHmac } from "crypto";
const body = JSON.stringify({ user_id: "demo_1", amount: 100, currency: "BRL", round_id: "r_1" });
const signature = createHmac("sha256", process.env.SANDBOX_WALLET_HMAC_SECRET!).update(body).digest("hex");
await fetch("https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit", {
method: "POST",
headers: {
"content-type": "application/json",
"x-signature": signature,
"x-idempotency-key": "round_123",
},
body,
});Python example
import hmac, hashlib, json, os, requests
body = json.dumps({"user_id":"demo_1","amount":100,"currency":"BRL","round_id":"r_1"}, separators=(",",":"))
sig = hmac.new(os.environ["SANDBOX_WALLET_HMAC_SECRET"].encode(), body.encode(), hashlib.sha256).hexdigest()
requests.post(
"https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit",
data=body,
headers={
"content-type": "application/json",
"x-signature": sig,
"x-idempotency-key": "round_123",
},
)PHP example
<?php
$body = json_encode(["user_id"=>"demo_1","amount"=>100,"currency"=>"BRL","round_id"=>"r_1"]);
$sig = hash_hmac("sha256", $body, getenv("SANDBOX_WALLET_HMAC_SECRET"));
$ch = curl_init("https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"content-type: application/json",
"x-signature: $sig",
"x-idempotency-key: round_123",
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);Failure injection
Simulate real production scenarios by passing query string parameters.
| Parameter | Example | Effect |
|---|---|---|
lat_min | 50 | Minimum latency in ms |
lat_max | 800 | Maximum latency in ms |
err_rate | 0.1 | 5xx probability (0.0–1.0) |
timeout_rate | 0.05 | Timeout probability (0.0–1.0) |
insuff_rate | 0.02 | Insufficient balance probability |
rtp | 0.97 | Target RTP for round simulation |
Example URL with failures
https://sandbox.i-gaming.co/api/public/v1/sandbox/wallet/debit?lat_max=800&err_rate=0.1&timeout_rate=0.05
Combine parameters to test edge cases: high latency + 10% error + 5% timeout.
Test scenarios to cover
Before going live, exercise these flows in the sandbox. Each one exposes a bug class we see in production.
Happy path
authenticate → balance → debit → credit. Balance must equal initial − bet + win.
Insufficient funds
Set insuff_rate=1 and confirm your game shows a proper error instead of crashing.
Network timeout on debit
Set timeout_rate=1 on debit. Your backend must NOT credit the round — instead, retry or rollback safely.
Duplicate debit (idempotency)
Send the same debit twice with the same x-idempotency-key. Balance must be debited only once.
Rollback after win failure
Simulate a credit failure and issue a rollback. The player must not lose money.
Concurrent bets
Fire 20 parallel debits for the same user. No negative balance, no double spend.
Multi-currency
Test BRL, USD, EUR, AUD, MYR. Amounts are always integer cents in the operator currency.
Reset and replay
Call /reset between test suites to get a clean state for CI.
Go-live checklist
Tick each item before requesting production credentials.
- All POST requests signed with HMAC-SHA256 over the raw body
- Every debit/credit carries a unique x-idempotency-key
- Retry with backoff on 5xx and network timeouts (max 3 attempts)
- Rollback path implemented and tested
- Structured logs for every wallet call (request id, round id, latency, status)
- Servers on NTP within ±5 minutes
- Secrets stored in a vault, never in git or logs
- Webhook receiver verifies our response signature
- Alerts on error rate, p95 latency and rollback rate
- Currency and amount units validated (integer cents, no floats)
Frequently asked questions
Does the sandbox cost anything?
No. The sandbox is free for evaluation and integration. You only pay when you go to production.
Is there a rate limit?
The sandbox allows up to 200 requests per second per token. Contact us if you need to run larger load tests.
Is sandbox data persistent?
State is kept in memory per session. Use /reset to clear it. For long CI suites, request a persistent sandbox.
How different is production?
The API is identical. Production adds real KYC, real money, real RLS, real webhooks and real monitoring — but your integration code does not change.
Where do I get help?
Open a ticket at contato@i-gaming.co or use the chat in the operator panel. Average response time is under 2 hours on business days.
Why do I get portal_response_bad_signature?
Nine times out of ten: you re-serialized the JSON body before signing, or your secret has a leading/trailing whitespace. Sign the raw bytes and trim your secret.
Important
The sandbox is not for load-testing our production infrastructure. Use realistic volumes. Abuse may result in your token being revoked.
Ready to test?
Request sandbox access and receive credentials within 24h with token, HMAC secret and metrics dashboard link.
100% free sandbox. No credit card required.