Skip to content

Seamless Wallet API

The Wallet API is the primary integration point between your casino and the Velo RGS. Your server must implement these endpoints so the RGS can debit bets, credit wins, and query balances in real time.

Authentication & Signing

All requests are signed with HMAC-SHA256. The RGS sends these headers on every call:

HeaderDescription
X-Api-KeyYour operator API key
X-SignHMAC-SHA256(request_body, API_SECRET)
X-Game-IdGame identifier (e.g., velo_btc_5min)
Content-Typeapplication/json

TIP

Verify the X-Sign header on every incoming request to ensure it originated from the Velo RGS. Reject any request with an invalid signature.

Endpoints

POST /wallet/authenticate

Validate a player's session token and return their profile. Called when a player opens the game.

Request Body:

json
{
  "token": "player-session-jwt-or-token",
  "game_id": "velo_btc_5min"
}

Response:

json
{
  "player_id": "player_abc123",
  "username": "JohnDoe",
  "currency": "USD",
  "balance": 1500.00,
  "session_token": "session_xyz789"
}

The session_token returned here will be included in all subsequent debit/credit/rollback requests, allowing you to validate the session is still active.


POST /wallet/debit

Debit the player's balance for a bet placement.

Request Body:

json
{
  "player_id": "player_abc123",
  "transaction_id": "550e8400-e29b-41d4-a716-446655440001",
  "round_id": "184721",
  "game_id": "velo_btc_5min",
  "amount": 100.00,
  "currency": "USD",
  "session_token": "session_xyz789"
}

Response (success):

json
{
  "transaction_id": "550e8400-e29b-41d4-a716-446655440001",
  "balance": 1400.00
}

Idempotency

If you receive a duplicate transaction_id, return the original success response without debiting again. The RGS uses the bet UUID as the idempotency key.


POST /wallet/credit

Credit the player's balance for a win or early cashout.

Request Body:

json
{
  "player_id": "player_abc123",
  "transaction_id": "550e8400-e29b-41d4-a716-446655440002",
  "ref_transaction_id": "550e8400-e29b-41d4-a716-446655440001",
  "round_id": "184721",
  "game_id": "velo_btc_5min",
  "amount": 182.00,
  "currency": "USD",
  "reason": "settle",
  "is_round_finished": true,
  "session_token": "session_xyz789"
}
FieldTypeDescription
ref_transaction_idstringLinks back to the original debit (bet)
reasonstring"settle" (round ended) or "cashout" (early exit)
is_round_finishedbooleantrue = no more transactions for this round. false = round still active (cashout)

Response:

json
{
  "transaction_id": "550e8400-e29b-41d4-a716-446655440002",
  "balance": 1582.00
}

Zero-Win Credits

When a player loses, the RGS sends a credit with amount: 0.00 to explicitly close the bet on your side. This ensures every debit has a matching credit for clean reconciliation.


POST /wallet/rollback

Reverse a debit that failed to complete (e.g., bet insertion error, oracle failure).

Request Body:

json
{
  "player_id": "player_abc123",
  "transaction_id": "550e8400-e29b-41d4-a716-446655440003",
  "ref_transaction_id": "550e8400-e29b-41d4-a716-446655440001",
  "round_id": "184721",
  "amount": 100.00,
  "currency": "USD",
  "reason": "bet_insert_failure",
  "session_token": "session_xyz789"
}
Rollback ReasonDescription
oracle_failurePrice oracle was unavailable during settlement
bet_insert_failureBet was debited but failed to record in game state
round_voidedRound cancelled due to price divergence or system error

Response:

json
{
  "transaction_id": "550e8400-e29b-41d4-a716-446655440003",
  "balance": 1500.00
}

POST /wallet/balance

Returns the player's current balance. Called periodically for balance display.

Request Body:

json
{
  "player_id": "player_abc123",
  "game_id": "velo_btc_5min"
}

Response:

json
{
  "balance": 1500.00
}

Transaction Flow

A complete round lifecycle produces this sequence of wallet calls:

1. Player opens game
   → POST /wallet/authenticate

2. Player places bet ($100 on UP)
   → POST /wallet/debit (amount: 100.00)

3a. Player wins (round settles UP)
    → POST /wallet/credit (amount: 182.00, reason: "settle", is_round_finished: true)

3b. Player loses (round settles DOWN)
    → POST /wallet/credit (amount: 0.00, reason: "settle", is_round_finished: true)

3c. Player cashes out early
    → POST /wallet/credit (amount: 145.00, reason: "cashout", is_round_finished: false)

Early Cashout

When is_round_finished: false, the round is still running for other players. Your accounting system should keep the round open until it receives a credit with is_round_finished: true.

Error Codes

Your wallet API should return structured error responses for failures:

json
{
  "error_code": "INSUFFICIENT_FUNDS",
  "message": "Player balance is insufficient for this bet"
}
Error CodeHTTP StatusDescription
INSUFFICIENT_FUNDS400Player cannot afford the bet
PLAYER_NOT_FOUND400Unknown player ID
PLAYER_BLOCKED400Player account is suspended or blocked
SESSION_EXPIRED400Session token is no longer valid
DUPLICATE_TRANSACTION400Transaction already processed (return original result)
BET_LIMIT_EXCEEDED400Bet exceeds configured limits

Retry Behavior

The RGS retries on 5xx errors with exponential backoff (200ms → 400ms → 800ms, max 3 attempts). 4xx errors are never retried — the RGS reads your error_code and handles it gracefully.

Security Checklist

  • [ ] Verify X-Sign HMAC on every request
  • [ ] Store API_SECRET securely (env variables, vault)
  • [ ] Use HTTPS (TLS 1.2+) for all endpoints
  • [ ] Implement idempotency on transaction_id
  • [ ] Validate session_token on debit/credit/rollback
  • [ ] Set reasonable response timeout (< 2 seconds)

B2B Integration Documentation