Testing
Two Ways to Test
Section titled “Two Ways to Test”Beexar provides two ways to validate your integration without involving real money:
| Tool | What it tests | Wallet callbacks |
|---|---|---|
| Demo mode | Game UI, launch flow, embedding | None — virtual balance, no wallet calls |
| Integration Test Game | Your wallet implementation against the full SoftSwiss contract | Real calls to your callback URLs |
Demo mode is launched via POST /api/v1/softswiss/launcher/demo (see Game Launch). The Integration Test Game is launched via the standard real launcher with game: "testgame" (see below).
Integration Test Game
Section titled “Integration Test Game”Beexar includes a built-in Integration Test Game that validates your wallet implementation against 30 test scenarios. 29 of them cover the full SoftSwiss wallet API contract and run together with Run all; the 30th certifies your Freespins/Finish callback and runs on its own, once you have issued freespins to the test player (see The Freespins Test).
How It Works
Section titled “How It Works”- Launch the test game via the standard launcher API
- Select which tests to run (or Run all — the 29 wallet tests; the freespins test is started on its own)
- The test game sends real wallet requests to your callback URLs
- Each test validates request/response behavior and displays pass/fail results
- You can inspect the actual HTTP request/response exchanged with your wallet
Test Categories
Section titled “Test Categories”| Category | Tests | What It Validates |
|---|---|---|
| Signature & Balance | 2 | HMAC signature validation, balance endpoint |
| Bets & Wins | 8 | Single bet, multiple bets, BetWin combined, win after finish, new params |
| No Funds | 3 | Insufficient funds (single bet, large win, two bets) |
| Idempotency | 3 | Duplicate bet, one duplicate in batch, duplicate win |
| Rollback | 6 | Normal rollback, win rollback, tombstone scenarios |
| SoftSwiss v2 Edge Cases | 7 | Win before bet, zero amount, BetWin response transactions, bonus amount, duplicate finish, rollback count |
| Freespins | 1 | Freespins/Finish: no wallet call per free spin, the win credited once, a repeated Finish answered with the original balance, a wrong signature refused, an unknown field ignored. Outside Run all — see The Freespins Test |
Running the Test Game
Section titled “Running the Test Game”BODY='{"casino_id":"your-operator-slug","game":"testgame","account":{"id":"test_player","currency":"USD"}}'SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')
curl -X POST https://gateway.beexar.com/api/v1/softswiss/launcher/real \ -H "Content-Type: application/json" \ -H "X-REQUEST-SIGN: $SIGNATURE" \ -d "$BODY"Open the returned launch_url in a browser. You will see the test game interface with checkboxes for each test.
Test Results
Section titled “Test Results”Each test run records:
- Pass/Fail status for each test
- Step-by-step execution log
- Actual HTTP request/response between Beexar and your wallet (the Operator Exchange)
- Summary badge: “Integration Ready” when every wallet test passes — the freespins test counts only once it has been run
The Freespins Test
Section titled “The Freespins Test”The freespins_finish test, in the Freespins group, certifies the operator side of freespins: a free round reaches no wallet endpoint, and the one Freespins/Finish credits what the rounds won — once, whatever repeats it. It is not part of Run all: the test game cannot give the player freespins, so you issue them first.
-
Issue freespins to the test player in the test game. Send
Freespins/Issuewithgames: ["testgame"],bet_level: 1and at most 50 spins — the test plays every one of them. The test game has a single bet level: 100 minor units of the account currency (1.00 USD, 100 JPY). Use the player and currency you launch the test game with; the issue may be sent before or after opening the game.Terminal window BODY='{"casino_id":"your-operator-slug","issue_id":"fs-test-0001","games":["testgame"],"freespins_quantity":5,"bet_level":1,"valid_until":"2026-11-20T00:00:00Z","account":{"id":"test_player","currency":"USD"}}'SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')curl -X POST https://gateway.beexar.com/api/v1/softswiss/freespins/issue \-H "Content-Type: application/json" \-H "X-REQUEST-SIGN: $SIGNATURE" \-d "$BODY" -
Run the test. In the test game, start
freespins_finishfrom the Freespins group. Its steps, and what must happen on your side:Step Your side Find the active freespins issue of this player in this game The issue from step 1 is found (with none, the test fails and says to issue one) Play a freespin that wins 2× its bet No /betwinreaches you: the balance is unchanged, the issue has one spin fewerPlay out the remaining spins The issue is played out Wait for Freespins/FinishYour endpoint answers HTTP 200 { "balance": "..." }, and the balance is the initial one plus the winSend the same Finish again HTTP 200 with the original balance; nothing is credited twice Send it with a wrong signature Refused Send it with an unknown field HTTP 200 with the original balance; the field is ignored
Every Finish exchange is shown with its request and response, as the wallet tests show theirs. The “Integration Ready” badge takes this test into account only once it has been run. An issue whose only game is the test game is marked as such: only its Finish can be re-sent, and it stays out of analytics — it does not appear under Analytics → Freespins.
Reference Wallet Implementation
Section titled “Reference Wallet Implementation”Every Beexar SDK ships a complete, correct wallet in about 250 readable lines — in Node, PHP, Go and Python. Read it, run it, or copy the parts you need. See Reference wallet.
Each one implements all four endpoints, verifies the HMAC signature over the raw
body, is idempotent on id_provider, records rollback tombstones, and answers
in the SoftSwiss Twirp error format.
The same implementations are driven by a public conformance fixture set: exact request bytes, the signature over them, the ledger before and after, and the expected response. If you are integrating without an SDK, point your own tests at those fixtures and you get the coverage the official SDKs have.
Integration Checklist
Section titled “Integration Checklist”Use this checklist to verify your integration is complete:
-
Signature validation
- All requests validated with HMAC-SHA256 (
X-REQUEST-SIGNheader) - Invalid signatures return HTTP 400 with api_code
403
- All requests validated with HMAC-SHA256 (
-
Balance endpoint
- Returns current balance as decimal string
- Handles unknown players gracefully (api_code
101)
-
BetWin endpoint
- Processes all transactions atomically (in order)
- Returns
balance,round_id, andtransactionsarray - Idempotent: duplicate
id_providerreturns original response - Insufficient funds returns HTTP 400 with api_code
100andbalancein meta - Tombstoned
id_providerreturns HTTP 400 with api_code155 - Handles
finished: trueto close the round
-
Rollback endpoint
- Reverses original transactions
- Creates tombstone if original transaction not found
- Idempotent: duplicate rollback
id_providerreturns original response - Processes rollback even with insufficient funds
-
Finish endpoint
- Acknowledges round completion with
{ "balance": "..." } - Handles duplicate finish calls idempotently
- Acknowledges round completion with
-
Error format
- All errors use Twirp format:
{ "code": "...", "msg": "...", "meta": { "api_code": "...", "api_message": "..." } } - Only HTTP 400 and 500 status codes (no 403, 409, 412)
-
balanceincluded in meta when api_code is100,105, or106
- All errors use Twirp format:
-
Freespins finish endpoint (only if you issue freespins)
- Credits
amountto the player ofissue_idand answers{ "balance": "..." } - Idempotent: a repeated Finish for the same
issue_idanswers the original balance and credits nothing - Invalid signatures return HTTP 400 with api_code
403 - Unknown fields are ignored
- Certified by the
freespins_finishtest of the Integration Test Game
- Credits
Testing Scenarios
Section titled “Testing Scenarios”Happy Path: Dice Round
Section titled “Happy Path: Dice Round”BODY='{"casino_id":"your-slug","game":"dice","account":{"id":"test_player","currency":"USD"}}'SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')
curl -X POST https://gateway.beexar.com/api/v1/softswiss/launcher/real \ -H "Content-Type: application/json" \ -H "X-REQUEST-SIGN: $SIGNATURE" \ -d "$BODY"
# Play the game in the returned launch_url# Verify wallet callbacks were received:# - POST /balance (on game load)# - POST /betwin (bet + win, finished=true)Happy Path: Crash Round
Section titled “Happy Path: Crash Round”BODY='{"casino_id":"your-slug","game":"crash","account":{"id":"test_player","currency":"USD"}}'SIGNATURE=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')
curl -X POST https://gateway.beexar.com/api/v1/softswiss/launcher/real \ -H "Content-Type: application/json" \ -H "X-REQUEST-SIGN: $SIGNATURE" \ -d "$BODY"
# Open the launch_url — join the next round, place a bet# Cash out before the crash or let it ride# Verify wallet callbacks:# - POST /betwin (bet only)# - POST /betwin (win, finished=true) — only if player cashed out# - POST /finish — only if the last BetWin did not set finished=trueError Scenarios to Test
Section titled “Error Scenarios to Test”| Scenario | Expected Behavior |
|---|---|
Return HTTP 400 with api_code 100 on BetWin |
Beexar shows “insufficient funds” to player |
| Return HTTP 500 on BetWin | Beexar retries (up to 3 times), then shows error |
| Timeout (no response) on BetWin | Beexar retries (up to 3 times), then shows error |
| Return invalid JSON | Beexar shows error to player |
Duplicate id_provider on BetWin |
Your wallet returns original response, no double processing |
| Rollback for non-existent transaction | Your wallet creates tombstone, returns 200 |