Skip to content

Wallet API Specification

This section defines the RESTful API that the Operator must implement to handle wallet transactions from Game Provider.

Overview

Game Provider follows a standard server-to-server integration model. The Game Provider platform sends HTTP POST requests to your (the Operator's) backend to authorize players, place bets, and settle wins.

  • Protocol: HTTP/1.1 or HTTP/2
  • Format: JSON
  • Requests: Initiated by Game Provider -> Operator

Data Types & Currency

All monetary values in this API are integers represented in millis (1/1000th of the main currency unit).

  • Formula: Amount in Millis = Amount in Unit * 1000
  • Example: 5.44 USD -> 5440 (millis)
  • Example: 1.00 EUR -> 1000 (millis)

[!CAUTION] Do not use floating point numbers. Always send integers.

Idempotency (Best Practice)

Network failures can occasionally cause Game Provider to send the same request multiple times (e.g., a timeout occurs before we receive your response).

To prevent double-charging or double-crediting players, your Wallet API MUST implement idempotency.

  • Idempotency Key: Use the provider_tx_id field in the request body.
  • Logic:
    1. Check if a transaction with this provider_tx_id already exists in your system.
    2. If it exists, return the original response immediately (do not process the balance change again).
    3. If it does not exist, process the transaction and save the result.

[!TIP] This is critical for BET (Withdraw) and WIN (Deposit) endpoints to ensure player balances remain accurate even during network instability.

Security

Every request from Game Provider includes the following headers for security verification:

Header Description
X-Public-Key Your assigned public key. Use this to identify the tenant.
X-Signature HMAC SHA256 signature of the request body using your Secret Key.

[!IMPORTANT] You MUST verify the X-Signature on every request. Compute the HMAC SHA256 of the raw request body using your Secret Key and compare it with the header value.

View Code Samples for Signature Validation (Java, C#, Go, Python)

Attributes & Metadata

In addition to the standard financial fields, Game Provider may send additional context in the attributes array. This data is useful for auditing, reporting, and responsible gaming checks on the Operator side.

Attribute Type Description
coefficient String The winning multiplier for the round (e.g., "1.50").
bonus String Flag or amount related to bonus balance usage or promotional eligibility.
createDate String ISO 8601 timestamp of when the event occurred in the game engine.

Each entry in the array is an object with name and value properties:

"attributes": [
  {"name": "coefficient", "value": "1.50"},
  {"name": "bonus", "value": "freebet"},
  {"name": "createDate", "value": "2024-12-24T14:30:00Z"}
]

Endpoints

1. Authentication Check

Verifies the player's session and retrieves their balance.

  • URL: {WALLET_BASE_URL}/auth
  • Method: POST

Request Payload

{
  "user_token": "player123",
  "session_token": "sess-abc-123",
  "platform": "mobile",
  "currency": "USD"
}

Response Payload

{
  "code": 200,
  "message": "OK",
  "data": {
    "user_id": "player123",
    "username": "Player One",
    "balance": 10000000,
    "currency": "USD",
    "maxbet": 5000000
  }
}

2. Withdraw (Bet)

Deducts funds from the player's wallet.

  • URL: {WALLET_BASE_URL}/withdraw
  • Method: POST

Request Payload

{
  "currency": "USD",
  "amount": 5440,
  "provider": "Game Provider",
  "provider_tx_id": "tx-1001",
  "game": "chicken-race",
  "action": "BET",
  "action_id": "round-555",
  "session_token": "sess-abc-123",
  "platform": "mobile",
  "user_id": "player123",
  "attributes": [
    {"name": "createDate", "value": "2024-12-24T14:30:00Z"}
  ]
}

Response Payload

{
  "code": 200,
  "message": "Success",
  "data": {
    "user_id": "player123",
    "operator_tx_id": "op-tx-999",
    "provider_tx_id": "tx-1001",
    "new_balance": 10000000,
    "currency": "USD"
  }
}

3. Deposit (Win)

Adds funds to the player's wallet.

  • URL: {WALLET_BASE_URL}/deposit
  • Method: POST

Request Payload

{
  "currency": "USD",
  "amount": 1000,
  "provider": "Game Provider",
  "provider_tx_id": "tx-1002",
  "withdraw_provider_tx_id": "tx-1001",
  "game": "chicken-race",
  "action": "WIN",
  "action_id": "round-555",
  "session_token": "sess-abc-123",
  "platform": "mobile",
  "user_id": "player123",
  "attributes": [
    {"name": "coefficient", "value": "1.50"},
    {"name": "createDate", "value": "2024-12-24T14:35:00Z"}
  ]
}

Response Payload

{
  "code": 200,
  "message": "Success",
  "data": {
    "user_id": "player123",
    "operator_tx_id": "op-tx-1000",
    "provider_tx_id": "tx-1002",
    "new_balance": 10500,
    "currency": "USD"
  }
}

4. Get Balance

Retrieves the current balance of the player.

  • URL: {WALLET_BASE_URL}/balance
  • Method: POST

Request Payload

{
  "user_id": "player123",
  "session_token": "sess-abc-123"
}

Response Payload

{
  "currency": "USD",
  "amount": 10500
}

5. Action Types

The action field in Withdraw and Deposit requests indicates the nature of the transaction.

Action API Description
BET Withdraw Standard real-money bet.
WIN Deposit Standard real-money win.
FREE_BET Withdraw Bet using a gift/bonus. Amount should be 0.
FREE_BET_WIN Deposit Win resulting from a free bet.

For FREE_BET actions, you should verify the player is eligible but do not deduct funds from their main balance.

Example: Free Bet Request

When a player uses a free bet, the action is set to FREE_BET, the amount is 0, and the bonus attribute is included.

{
  "currency": "USD",
  "amount": 0,
  "provider": "Game Provider",
  "provider_tx_id": "tx-2001",
  "game": "chicken-race",
  "action": "FREE_BET",
  "action_id": "round-999",
  "session_token": "sess-xyz-789",
  "platform": "desktop",
  "user_id": "player123",
  "attributes": [
    {"name": "bonus", "value": "freebet"},
    {"name": "createDate", "value": "2024-12-24T15:00:00Z"}
  ]
}

Error Codes

Code Description
200 Success
400 Bad Request / Validation Error
401 Unauthorized (Invalid Signature or Token)
402 Insufficient Funds
500 Internal Server Error