Integration acceptance
Follow the quickstart, then execute this matrix with your own callback backend and issued sandbox configuration. Use independent test player/session, bet and transaction IDs. Record status, verified outcome and ledger effect for each case. Never use real-money wallets for simulated callbacks.
Tests in your implementation
Automate checks around your actual HTTP handlers and wallet storage. Use the same request/response shapes as the endpoint reference, with test-only players, sessions and balances.
- Check request and response signatures against independently calculated canonical strings. Alter raw bytes, request IDs and timestamps to prove invalid requests fail.
- Verify bet, gross win, zero win and cancel with exact decimal arithmetic.
- Send identical callbacks concurrently. Assert one ledger mutation and the same stored result, including after a backend restart or a lost HTTP response.
- Reuse a transaction ID with a changed amount, bet or endpoint and assert rejection.
- Verify insufficient funds, ownership mismatches, precision boundaries and payout caps without an unintended wallet change.
Then repeat the applicable cases through Moonshot sandbox gameplay and your public HTTPS callback backend. Local handler tests alone do not validate deployed credentials, connectivity, browser behavior or provider-to-wallet delivery.
Sandbox matrix
| Test | Expected result |
|---|---|
| Valid launch | Signed HTTP 200; echoed slug/key, provider operator UUID and allowed HTTPS game URL; game loads in iframe. |
| Wrong secret, missing header, stale clock, altered raw bytes | Authentication failure; no trusted session or wallet change. |
| Invalid player UUID or missing launch field | Authenticated signed 400 validation error. |
| Unknown/disabled game or currency | Launch fails; no invented successful session. Current downstream failures can surface as signed 503. |
| Launch timeout/503 | Treat as unknown; next explicit attempt uses a fresh key and partner session. No automatic same-key replay. |
| Bet → win | One debit and one gross credit; compare exact balances with your ledger. |
| Bet → cancel on a different bet | One debit and one refund of exactly the original stake. |
| Bet → zero win | Signed success, unchanged post-bet balance; bet is settled and cannot also be refunded. |
| Insufficient funds | Signed HTTP 200, statusCode: 5100, unchanged balance and no accepted bet. |
| Callback with wrong player/session/game/currency | Signed rejection; no balance change. |
| Sequential and concurrent duplicates of all three callbacks | Original response data and operator transaction ID; exactly one ledger mutation. |
| Same transaction ID with changed amount, bet or endpoint | Signed conflict, no second operation. |
| New transaction ID for the same already-funded bet | Reject duplicate funding; transaction-level idempotency alone is insufficient. |
| Win/cancel for an unknown or rejected bet | Signed conflict; no credit. |
| Refund amount mismatch, second final settlement, cap overflow | Signed rejection; original ledger remains consistent. |
| Session expires after bet acceptance | Legitimate late win/cancel resolves using the original accepted bet. |
| Commit succeeds but response is lost | Retry original ID/payload; replay original stored success, no second mutation. |
| Restart or multiple backend instances | Durable idempotency and wallet locking still prevent duplicate mutations. |
| Signed HTTP 5xx or timeout before commit | No unrecorded wallet mutation; retry retains transaction/payload with fresh attempt headers. |
| Unsigned response, wrong request ID/status signature or HTML from proxy | Untrusted result; reconcile, do not accept balance or success. |
| Minimum/maximum stake and currency precision boundaries | Exact allowed values succeed; outside values reject without debit. |
| Desktop/mobile iframe, rotation, audio and fullscreen | Usable layout and successful player interactions with normal browser security. |
Freeplays, when enabled
Verify capabilities and issuance, signed state lookup by the original key, repeated creation, changed-key-payload conflict, unique external reference and future expiry. Confirm lowercase statuses and normalized decimal values.
Test one eligible use, concurrent attempts to consume the last play, duplicate callbacks, zero-payout loss, gross payout destination, coefficient/per-play/package caps, expiry, package cancellation and late settlement of an accepted usage. Verify that neither freeplay bet nor cancel changes the regular wallet and that a replay does not consume or restore a play twice. Exercise your promotion ledger separately from ordinary stake debits and refunds.
Retry behavior
The current callback client defaults to a 1,500 ms timeout and one immediate retry after a transport timeout/network failure or a verified HTTP 5xx. These settings can differ by environment. Blackjack transaction callbacks currently disable this immediate retry. Persist results and support later reconciliation regardless of the immediate retry count.
Signed HTTP 4xx and HTTP 200 business rejections are not retried by this HTTP policy. An invalid response signature is also not treated as a retryable server error. A retry retains the body and transaction ID and changes the request UUID, timestamp and signature. Do not depend on retries always arriving.
Production handoff
- Confirm completed sandbox evidence with both technical teams.
- Supply the production callback URL, allowed embedding/game origins, enabled game/currency matrix, precision, limits and RTP. Use separate production credentials.
- Verify HTTPS routing, raw-body preservation, clocks, response signing and wallet storage. Set callback latency below the confirmed timeout and monitor failures.
- Agree how to reconcile unknown transactions and contact support during launch.
- Complete an agreed controlled end-to-end launch and inspect both ledgers before
broad traffic. A successful
/launchalone does not validate wallet settlement.