Skip to content

POST /betwin

Beexar → Operator

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.


POST {betwin_url}

HeaderValue
Content-Typeapplication/json
X-REQUEST-SIGNHMAC-SHA256 signature of request body
FieldTypeRequiredDescription
account_idstringYesPlayer account identifier
currencystringYesCurrency code — standard ("USD", "EUR", "BTC") or custom ("CUSTOM_GOLD")
game_idstringYesGame identifier (slug)
round_idstringYesGame round identifier (generated by Beexar)
finishedbooleanNoIf true, the round is complete — no /finish call will follow
transactionsarrayYesList of bet/win transactions (min 1)
session_idstringNoSession identifier (UUID). Always sent, but operators are not required to use it

Each item in the transactions array:

FieldTypeRequiredDescription
id_providerstringYesUnique transaction identifier (generated by Beexar, used for idempotency)
typestringYes"bet" or "win"
amountstringYesTransaction amount as decimal string (must be > 0)

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"
}

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" }
]
}

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" }
]
}

FieldTypeRequiredDescription
round_idstringYesRound identifier on operator side
balancestringYesPlayer balance after all transactions
transactionsarrayYesResults for each transaction (same order as request)

Each transaction result:

FieldTypeRequiredDescription
id_providerstringYesTransaction identifier from request (echo back)
idstringYesTransaction 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" }
]
}

Errors use the Twirp format with an api_code in the meta field:

HTTP StatusTwirp Codeapi_codeDescription
400invalid_argument100Insufficient funds
400invalid_argument105Bet limit exceeded
400invalid_argument106Win limit exceeded
400invalid_argument155Action was already rolled back (tombstoned)
400invalid_argument403Invalid or missing signature
500internal500Internal 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"
}
}

Terminal window
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" }
]
}'

  • 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_provider has already been processed, return the original response — do NOT process the transaction again
  • Tombstone check: If an id_provider was already rolled back (tombstone exists), respond with HTTP 400 and api_code 155
  • Amounts: Always positive, never zero
  • finished flag: When true, the round is complete. No /finish call will be sent. When false or absent, more BetWin requests may follow, and a /finish call will close the round
  • Multiple requests per round: In multi-step games (slots with free spins/bonus), a single round_id may span multiple BetWin requests with different id_provider values
  • 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 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: true in the first (and only) BetWin request
  • Crash: finished: true in the final BetWin (cashout or loss)
  • Slots: finished: false during free spins, finished: true in the last action, or /finish sent separately
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