Integration
Wallet callbacks
The platform keeps no balance of its own. For every player action that touches money it calls your wallet endpoint. You implement one HTTPS endpoint that handles several method values.
Transport#
| Property | Value |
|---|---|
| URL | POST <callback URL>/<currency>, e.g. https://casino.example/wallet/UAH (currency in the path: UAH, USD, EUR, RUB) |
| Where to set the URL | Admin panel → Projects → your project → Integration (see Admin: projects) |
| Body | JSON object with sorted keys; includes api_key |
| Authentication | The project api_key in the body — compare it with your stored key |
| Time-out | 2 seconds per attempt; redirects are not followed |
| Success | HTTP 2xx with the JSON answer below. A non-2xx status counts as a failure even if the body says ok |
| Idempotency | Every bet / win carries a unique meta.transaction; a retry repeats the same id and body |
If a project has no callback URL configured, the platform uses a built-in test wallet (starting balance 10 000.00 per currency) so you can try games before your wallet is ready.
The answer#
Every method is answered with:
{"status": "ok", "balance": 988.5, "currency": "UAH"}| Field | Rule |
|---|---|
status | "ok" or "error" |
balance | The player's balance after the operation, as a JSON number (not a string) |
currency | Must equal the currency in the request path; otherwise the answer is rejected as invalid |
message | With "status":"error": a code such as INSUFFICIENT_FUNDS |
Methods#
session_info — read the balance#
Sent at game launch. Nothing is changed.
{
"method": "session_info",
"player_id": "player-123",
"session_id": "9d0c3f7e-…",
"api_key": "YOUR_API_KEY"
}Answer with the current balance. If you answer with an error or not at all, the launch fails with BALANCE_UNAVAILABLE.
bet — debit the stake#
Sent before a paid round is played. Debit amount and answer.
{
"method": "bet",
"player_id": "player-123",
"amount": 1.5,
"meta": {
"symbol": "gates-of-olympus",
"time": 1789473600,
"transaction": "6f1d0c9e-…",
"round_id": "b2a7…",
"session_id": "9d0c3f7e-…"
},
"api_key": "YOUR_API_KEY"
}amountis a positive JSON number in currency units.- Free-spin rounds are sent with
amount: 0and extra meta; accept the zero bet whenis_freespinsistrue:
"meta": {
"transaction": "…", "round_id": "…", "session_id": "…", "symbol": "…", "time": 1789473600,
"is_freespins": true,
"freespins": {"grant_id": "…", "external_id": "promo-1", "nominal_bet": 1, "remaining": 9}
}- If the balance is too low, answer
{"status":"error","message":"INSUFFICIENT_FUNDS","balance":0.5,"currency":"UAH"}. The round is rejected and nothing is played. Return this code only for a real lack of funds.
win — credit the result#
Sent when a round pays. amount is the total win of the round (positive; zero wins are not sent). The meta has the same fields as bet (symbol, time, transaction, round_id, session_id). For a free-spin round it also carries is_freespins: true and freespins: {grant_id, external_id, nominal_bet}.
{
"method": "win",
"player_id": "player-123",
"amount": 12.75,
"meta": {"symbol": "gates-of-olympus", "time": 1789473612, "transaction": "0b6e…", "round_id": "b2a7…", "session_id": "9d0c3f7e-…"},
"api_key": "YOUR_API_KEY"
}round_info — round notification (round summary)#
Informational: record it, change nothing, answer ok with the current balance. Two are sent per round, in order: start (after the debit is confirmed) and finish (after the credit is confirmed, or after the round ended without a win).
{
"method": "round_info",
"player_id": "player-123",
"status": "finish",
"round_id": "b2a7…",
"session_id": "9d0c3f7e-…",
"game_symbol": "gates-of-olympus",
"currency": "UAH",
"timestamp": 1789473615,
"bet_amount": 1.5,
"bet_type": "spin",
"bonus_buy": false,
"bonus_trigger": true,
"win_amount": 12.75,
"multiplier": 8.5,
"has_win": true,
"api_key": "YOUR_API_KEY"
}| Field | Description |
|---|---|
status | start or finish |
bet_amount | Stake of the round (nominal bet for free-spin rounds) |
bet_type | Type of bet of the round, for example spin or purchase |
bonus_buy | The round was a bonus buy |
bonus_trigger | The round triggered a bonus feature |
win_amount, multiplier, has_win | Only on finish: total win, win ÷ bet, and whether it is positive |
forced | true when the round was produced for an operator target outcome |
The finish notification is the round summary: use it for reporting; money has already moved through bet and win.
freespins_finished — free-spins grant summary#
One per finished free-spins grant. Answer in the usual format ({"status":"ok","balance":…,"currency":"…"}); it is repeated until you do.
{
"method": "freespins_finished",
"grant_id": "7b1c…",
"external_id": "promo-2026-10",
"player_id": "player-123",
"currency": "UAH",
"game": "gates-of-olympus",
"status": "used",
"total": 10,
"played": 10,
"bet": "1.00",
"total_win": "23.50",
"finished_at": "2026-10-15T12:30:00.000Z",
"api_key": "YOUR_API_KEY"
}Order of calls in a round#
bet -> (debit confirmed) -> round_info start -> [play] -> win (if > 0) -> (credit confirmed) -> round_info finishround_info finish is only delivered after round_info start was acknowledged.
Retries and failures#
| Situation | What the platform does |
|---|---|
bet answered INSUFFICIENT_FUNDS | The round is rejected; nothing is retried |
Any other error, an invalid answer, a non-2xx status or a time-out on bet / win | The operation is treated as unknown and retried later with the same transaction id and body until confirmed. The round stays pending meanwhile |
round_info not answered ok | Retried later; a partner that does not respond is skipped for a while so that it never blocks others |
freespins_finished not answered ok | Retried with growing delays: 10 s × 2<sup>attempts</sup>, at most 1 hour |
Because retries are expected, your wallet must be idempotent: remember the answer you gave for each meta.transaction and return it again for a repeat of the same request. A repeat must never debit or credit twice.
Checklist for your wallet#
- [ ] Verify
api_key; serve HTTPS only; answer within 2 seconds. - [ ] Parse
amountas a decimal; returnbalanceas a JSON number. - [ ] Echo the currency from the URL path in
currency. - [ ] Idempotency by
meta.transaction(same id, same body → same answer). - [ ] Accept
amount: 0forbetwhenmeta.is_freespinsistrue. - [ ] Answer
round_infoandfreespins_finishedwithok(status,balance,currency). - [ ] Use Test connection in the admin panel and watch API Logs while testing.