POST /betwin
Beexar sends this request to debit and/or credit the player balance during gameplay. All transactions in the request must be processed atomically and in order.
This single endpoint replaces separate bet and win calls — both transaction types are included in the transactions array.
Request
Section titled “Request”POST {betwin_url}
Headers
Section titled “Headers”| Header | Value |
|---|---|
Content-Type | application/json |
X-REQUEST-SIGN | HMAC-SHA256 signature of request body |
| Field | Type | Required | Description |
|---|---|---|---|
account_id | string | Yes | Player account identifier |
currency | string | Yes | Currency code — standard ("USD", "EUR", "BTC") or custom ("CUSTOM_GOLD") |
game_id | string | Yes | Game identifier (slug) |
round_id | string | Yes | Game round identifier (generated by Beexar) |
finished | boolean | No | If true, the round is complete — no /finish call will follow |
transactions | array | Yes | List of bet/win transactions (min 1) |
session_id | string | No | Session identifier (UUID). Always sent, but operators are not required to use it |
Transaction Object
Section titled “Transaction Object”Each item in the transactions array:
| Field | Type | Required | Description |
|---|---|---|---|
id_provider | string | Yes | Unique transaction identifier (generated by Beexar, used for idempotency) |
type | string | Yes | "bet" or "win" |
amount | string | Yes | Transaction amount as decimal string (must be > 0) |
Examples
Section titled “Examples”Simple Round (Dice — bet + win, finished)
Section titled “Simple Round (Dice — bet + win, finished)”A player bets 10 USD and wins 19.80 USD. The round is complete in one request:
{ "account_id": "player_123", "currency": "USD", "game_id": "dice", "round_id": "550e8400-e29b-41d4-a716-446655440000", "finished": true, "transactions": [ { "id_provider": "tx_bet_001", "type": "bet", "amount": "10.00" }, { "id_provider": "tx_win_001", "type": "win", "amount": "19.80" } ], "session_id": "7b115688-3849-490a-95bd-7c281d81c64c"}Bet Only (Slots — first spin)
Section titled “Bet Only (Slots — first spin)”A player places a bet. The round continues (free spins or bonus may follow):
{ "account_id": "player_123", "currency": "USD", "game_id": "slots", "round_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "finished": false, "transactions": [ { "id_provider": "tx_bet_002", "type": "bet", "amount": "5.00" } ]}Win Only (Slots — free spin result)
Section titled “Win Only (Slots — free spin result)”A win from a free spin within an ongoing round:
{ "account_id": "player_123", "currency": "USD", "game_id": "slots", "round_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "finished": false, "transactions": [ { "id_provider": "tx_win_002", "type": "win", "amount": "15.00" } ]}Losing Round (Plinko — bet only, finished)
Section titled “Losing Round (Plinko — bet only, finished)”A player bets and loses. No win transaction:
{ "account_id": "player_123", "currency": "EUR", "game_id": "plinko", "round_id": "deadbeef-cafe-1234-5678-abcdef012345", "finished": true, "transactions": [ { "id_provider": "tx_bet_003", "type": "bet", "amount": "2.50" } ]}Response
Section titled “Response”Success (200 OK)
Section titled “Success (200 OK)”| Field | Type | Required | Description |
|---|---|---|---|
round_id | string | Yes | Round identifier on operator side |
balance | string | Yes | Player balance after all transactions |
transactions | array | Yes | Results for each transaction (same order as request) |
Each transaction result:
| Field | Type | Required | Description |
|---|---|---|---|
id_provider | string | Yes | Transaction identifier from request (echo back) |
id | string | Yes | Transaction identifier assigned by operator |
{ "round_id": "697962ac-fd0d-4dc2-b52c-e850e40825dc", "balance": "509.80", "transactions": [ { "id_provider": "tx_bet_001", "id": "op_tx_101" }, { "id_provider": "tx_win_001", "id": "op_tx_102" } ]}Error Responses
Section titled “Error Responses”Errors use the Twirp format with an api_code in the meta field:
| HTTP Status | Twirp Code | api_code | Description |
|---|---|---|---|
| 400 | invalid_argument | 100 | Insufficient funds |
| 400 | invalid_argument | 105 | Bet limit exceeded |
| 400 | invalid_argument | 106 | Win limit exceeded |
| 400 | invalid_argument | 155 | Action was already rolled back (tombstoned) |
| 400 | invalid_argument | 403 | Invalid or missing signature |
| 500 | internal | 500 | Internal server error |
Insufficient funds error:
{ "code": "invalid_argument", "msg": "Player has not enough funds to process an action.", "meta": { "api_code": "100", "api_message": "Player has not enough funds to process an action.", "balance": "5.00" }}curl Example
Section titled “curl Example”curl -X POST https://casino.example.com/wallet/betwin \ -H "Content-Type: application/json" \ -H "X-REQUEST-SIGN: abc123def456..." \ -d '{ "account_id": "player_123", "currency": "USD", "game_id": "dice", "round_id": "550e8400-e29b-41d4-a716-446655440000", "finished": true, "transactions": [ { "id_provider": "tx_bet_001", "type": "bet", "amount": "10.00" }, { "id_provider": "tx_win_001", "type": "win", "amount": "19.80" } ] }'Behavioral Rules
Section titled “Behavioral Rules”- Atomicity: All transactions in the request must be processed atomically — either all succeed or none are applied
- Order: Transactions are processed in the order they appear in the array
- Idempotency: If an
id_providerhas already been processed, return the original response — do NOT process the transaction again - Tombstone check: If an
id_providerwas already rolled back (tombstone exists), respond with HTTP 400 and api_code155 - Amounts: Always positive, never zero
finishedflag: Whentrue, the round is complete. No/finishcall will be sent. Whenfalseor absent, more BetWin requests may follow, and a/finishcall will close the round- Multiple requests per round: In multi-step games (slots with free spins/bonus), a single
round_idmay span multiple BetWin requests with differentid_providervalues - Win before bet: In rare timing scenarios, a win request may arrive before the corresponding bet. The win must still be processed
The finished Flag
Section titled “The finished Flag”The finished flag optimizes the round lifecycle by eliminating the separate /finish call:
flowchart LR
Start(("●")) -- "BetWin finished=false" --> Active
Active -- "BetWin finished=false" --> Active
Active -- "BetWin finished=true" --> Done(("●"))
Active -- "/finish" --> Done
- Simple games (dice, plinko):
finished: truein the first (and only) BetWin request - Crash:
finished: truein the final BetWin (cashout or loss) - Slots:
finished: falseduring free spins,finished: truein the last action, or/finishsent separately
Sequence Diagram
Section titled “Sequence Diagram”sequenceDiagram
participant Beexar
participant Wallet as Operator Wallet
Note over Beexar,Wallet: Player places bet (dice)
Beexar->>Beexar: Calculate result
Beexar->>Wallet: POST /betwin (bet + win, finished=true)
alt Sufficient funds
Wallet->>Wallet: Debit bet, credit win (atomic)
Wallet-->>Beexar: 200 { balance, transactions }
Note over Beexar: Show result to player
else Insufficient funds
Wallet-->>Beexar: 400 { api_code: "100", balance }
Note over Beexar: Show error to player
end