1. Integration Overview & Architecture
The BetBita Lucky 6 Bingo platform integrates directly into your existing sportsbook or casino lobby. The game operates on the standard iGaming Seamless Wallet protocol — your platform remains the single source of truth for player identity, wallet balance, stake debits, and winnings credits.
Strict Custody & Payment Isolation
All internal payment processing, card gateways, manual bank transfers, deposits, withdrawals, and voucher funding are completely excluded and hidden from this API.Your platform maintains 100% custody of player accounts and funds. BetBita never accesses player payment credentials.
| Component | BetBita Provides | Partner Platform Provides |
|---|---|---|
| Player Identity | Tokenized game launch handler | Player ID, currency, username & session context |
| Wallet & Wagers | Synchronous HMAC-signed S2S client | 4 endpoints: /balance, /debit, /credit, /rollback |
| Payment Methods | Excluded / Omitted | 100% Partner Platform Owned (Cards, Mobile Money, Banks) |
| Game Client UI | Hosted 3D WebGL / HTML5 engine | Embedded iFrame (Web) or Native WebView (Mobile) |
| Live Draw Feed | Low-latency SignalR / WebSocket stream | Connect to stream or render embedded UI |
| Retail Counter | Thermal slip layout, barcode validation API | PC/terminal, 80mm ESC/POS printer, 2D scanner |
Competitive Digital Payout Rate
Configured for high-volume digital sportsbook and casino lobbies with 10% house retention margin and 88%–92% adaptive algorithmic target band.
Physical Betting Shop Standard
Tailored for land-based franchised betting counters and cashier desks covering physical location overheads with 15% house retention margin.
2. End-to-End Online Transaction Flow
The transaction lifecycle from player lobby launch to round settlement:
- 1. Game Launch: Partner backend calls
POST /api/v1/game/launchand receives a tokenized launch URL. - 2. Client Embedding: Partner loads the URL inside an iFrame (web) or native WebView (mobile app).
- 3. Balance Query: Game client initializes and BetBita calls Partner
POST /wallet/balanceto display current player balance. - 4. Ticket Placement: Player bets. BetBita calls
POST /wallet/debit. Partner synchronously deducts stake (or returns 402 if low balance). - 5. Live 35-Ball Draw: 35 numbers drawn continuously from 48. Real-time extraction streamed over WebSocket.
- 6. Instant Credit / Win: Winning tickets trigger
POST /wallet/creditimmediately crediting player winnings.
3. S2S Game Launch API
Your backend server requests a short-lived tokenized launch URL for authenticated players before rendering the iFrame.
Merchant Account & API Key Management
Your production and sandbox credentials (operator_id and 64-character HMAC secret_key) are issued from your Merchant Account in the BetBita Admin Console under Developer > API Credentials.
In the Admin Console, partners can configure webhook callback URLs, whitelist authorized launch IPs, test connectivity, and inspect real-time transaction logs.
| Environment | API Base URL | Game Client URL | Live Stream (WSS) |
|---|---|---|---|
| Production (Live) | https://api.betbita.com | https://bingo.betbita.com | wss://stream.betbita.com/hub/lucky6 |
| Sandbox (Staging) | https://staging-api.betbita.com | https://staging-bingo.betbita.com | wss://staging-stream.betbita.com/hub/lucky6 |
# 1. Build string to sign: timestamp + "." + raw_payload
TIMESTAMP=$(date +%s)
PAYLOAD='{"operatorId":"OP_BETWAY_ZA","playerId":"USR_987654","currency":"NAD","language":"en","mode":"mobile","returnUrl":"https://partner.com/lobby"}'
SIGNATURE=$(echo -n "${TIMESTAMP}.${PAYLOAD}" | openssl dgst -sha256 -hmac "YOUR_64_CHAR_HMAC_SECRET" | sed 's/^.* //')
# 2. Dispatch S2S POST request
curl -X POST "https://api.betbita.com/api/v1/game/launch" \
-H "Content-Type: application/json" \
-H "X-BetBita-Signature: ${SIGNATURE}" \
-H "X-BetBita-Timestamp: ${TIMESTAMP}" \
-d "${PAYLOAD}"{
"success": true,
"code": "SUCCESS",
"data": {
"launchUrl": "https://bingo.betbita.com/launch/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"sessionId": "BB-SES-20261007-009182",
"expiresInSeconds": 300
}
}Real Mode vs. Fun Mode (500 Automated Free Credits)
Like top iGaming providers (e.g. XLarge, Pragmatic, Spribe), BetBita Lucky 6 supports both Real Money and Fun / Demo Play:
Operates on your Seamless Wallet. Deducts real stakes via /wallet/debit and automatically credits real winnings via /wallet/credit.
Loads 500 automated free virtual credits into the game. Zero wallet callbacks are triggered on your server. Allows players to learn the 35-ball mechanics risk-free.
https://bingo.betbita.com/demo?currency=NAD&lang=en
Embed this URL directly in your public lobby for unauthenticated visitors. When ready to wager real money, the in-game CTA emits a BETBITA_SWITCH_TO_REAL_MODE event.
4. Client Embedding (iFrame & Native Mobile)
Embed the returned launchUrl inside a responsive web container. The client emits postMessage events so your host web application can handle exits or trigger your deposit modal.
<div class="bingo-container" style="position: relative; width: 100%; height: 850px; max-height: 100vh;">
<iframe
id="betbita-bingo-frame"
src="https://bingo.betbita.com/launch/TOKEN"
style="width: 100%; height: 100%; border: none; display: block;"
allow="fullscreen; autoplay; clipboard-write"
allowfullscreen
></iframe>
</div>
<script>
window.addEventListener("message", function(event) {
if (!event.origin.includes("betbita.com")) return;
switch(event.data.type) {
case "BETBITA_EXIT_GAME":
window.location.href = event.data.returnUrl || "/lobby";
break;
case "BETBITA_INSUFFICIENT_FUNDS":
openDepositModal();
break;
case "BETBITA_SWITCH_TO_REAL_MODE":
// Player clicked 'Play with Real Money' inside demo mode
window.location.href = "/login?redirect=/bingo";
break;
case "BETBITA_SESSION_EXPIRED":
alert("Session expired. Please log in again.");
window.location.reload();
break;
}
});
</script>• iOS: Use WKWebView with allowsInlineMediaPlayback = true.
• Android: Use WebView with javaScriptEnabled = true and domStorageEnabled = true.
5.1 /wallet/balance (Balance Query)
BetBita queries this endpoint when the game initializes, on page focus, or when the player refreshes the lobby balance.
{
"operatorId": "PARTNER001",
"playerId": "USR_987654",
"currency": "NAD",
"requestId": "REQ-BAL-100001"
}{
"success": true,
"code": "SUCCESS",
"data": {
"playerId": "USR_987654",
"currency": "NAD",
"balance": 1500.50,
"availableBalance": 1500.50
}
}5.2 /wallet/debit (Stake Deduction)
Called synchronously when the player clicks "Place Bet" in the game client. Partner backend checks balance and deducts the stake.
{
"operatorId": "PARTNER001",
"playerId": "USR_987654",
"currency": "NAD",
"amount": 20.00,
"transactionId": "TX-BET-20261007-008172",
"roundId": "DRAW-45462",
"ticketId": "0876237952",
"betType": "Standard",
"selections": "5,28,29,31,46,48",
"timestamp": "2026-10-07T10:02:15Z",
"requestId": "REQ-DEB-200002"
}{
"success": true,
"code": "SUCCESS",
"data": {
"transactionId": "TX-BET-20261007-008172",
"playerId": "USR_987654",
"currency": "NAD",
"balance": 1480.50
}
}{
"success": false,
"code": "INSUFFICIENT_FUNDS",
"message": "Player balance is insufficient."
}5.3 /wallet/credit (Win & Jackpot Credit)
Called immediately upon draw completion when the 35th ball finishes. Partner credits player wallet immediately.
{
"operatorId": "PARTNER001",
"playerId": "USR_987654",
"currency": "NAD",
"amount": 5816.73,
"transactionId": "TX-WIN-20261007-009941",
"refDebitTransactionId": "TX-BET-20261007-008172",
"roundId": "DRAW-45462",
"ticketId": "0876237952",
"isJackpotWinner": true,
"jackpotType": "Gold",
"jackpotAmount": 5816.73,
"timestamp": "2026-10-07T10:05:40Z",
"requestId": "REQ-CRE-300003"
}{
"success": true,
"code": "SUCCESS",
"data": {
"transactionId": "TX-WIN-20261007-009941",
"playerId": "USR_987654",
"currency": "NAD",
"balance": 7297.23
}
}5.4 /wallet/rollback (Refund / Void)
Called if a round is cancelled/voided by regulators, or if an unexpected network timeout occurs between bet debit and draw acceptance. Partner refunds the original stake.
{
"operatorId": "PARTNER001",
"playerId": "USR_987654",
"currency": "NAD",
"amount": 20.00,
"transactionId": "TX-RB-20261007-000101",
"originalTransactionId": "TX-BET-20261007-008172",
"roundId": "DRAW-45462",
"ticketId": "0876237952",
"reason": "ROUND_CANCELLED",
"timestamp": "2026-10-07T10:06:00Z",
"requestId": "REQ-ROL-400004"
}{
"success": true,
"code": "SUCCESS",
"data": {
"transactionId": "TX-RB-20261007-000101",
"playerId": "USR_987654",
"currency": "NAD",
"balance": 1500.50
}
}6. HMAC-SHA256 Security & Signatures
Every request from BetBita contains an X-Signature header generated using HMAC-SHA256. Partners must verify this signature to guarantee authenticity and reject requests outside a 5-minute replay window.
METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + REQUEST_ID + "\n" + SHA256(RAW_BODY)
import crypto from "crypto";
export function verifyBetBitaSignature(req, res, next) {
const secret = process.env.BETBITA_HMAC_SECRET;
const signature = req.headers["x-signature"];
const timestamp = req.headers["x-timestamp"];
const requestId = req.headers["x-request-id"];
if (!signature || !timestamp || !requestId) {
return res.status(401).json({ success: false, code: "MISSING_AUTH_HEADERS" });
}
const ageSeconds = Math.abs((Date.now() - new Date(timestamp).getTime()) / 1000);
if (ageSeconds > 300) {
return res.status(401).json({ success: false, code: "REQUEST_EXPIRED" });
}
const bodyHash = crypto.createHash("sha256").update(JSON.stringify(req.body)).digest("hex");
const canonical = req.method.toUpperCase() + "
" + req.originalUrl.split("?")[0] + "
" + timestamp + "
" + requestId + "
" + bodyHash;
const expected = crypto.createHmac("sha256", secret).update(canonical).digest("hex");
if (signature.toLowerCase() !== expected.toLowerCase()) {
return res.status(401).json({ success: false, code: "INVALID_SIGNATURE" });
}
next();
}7. Ready-to-Run Starter Mock Server
Your developers do not need to guess anything. Run this self-contained script to test all 4 callbacks with BetBita immediately:
// Run: npm init -y && npm install express body-parser
// node server.js
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
const playerBalances = { "USR_987654": 1500.00, "PLAYER12345": 850.00 };
const processedTransactions = new Map();
// 1. /wallet/balance
app.post("/wallet/balance", (req, res) => {
const { playerId, currency } = req.body;
if (!playerBalances.hasOwnProperty(playerId)) {
return res.status(404).json({ success: false, code: "PLAYER_NOT_FOUND" });
}
const balance = playerBalances[playerId];
res.json({ success: true, code: "SUCCESS", data: { playerId, currency, balance, availableBalance: balance } });
});
// 2. /wallet/debit
app.post("/wallet/debit", (req, res) => {
const { playerId, amount, transactionId, currency } = req.body;
if (processedTransactions.has(transactionId)) {
return res.json(processedTransactions.get(transactionId));
}
if (!playerBalances.hasOwnProperty(playerId)) {
return res.status(404).json({ success: false, code: "PLAYER_NOT_FOUND" });
}
if (playerBalances[playerId] < amount) {
return res.status(402).json({ success: false, code: "INSUFFICIENT_FUNDS" });
}
playerBalances[playerId] -= amount;
const result = { success: true, code: "SUCCESS", data: { transactionId, playerId, currency, balance: playerBalances[playerId] } };
processedTransactions.set(transactionId, result);
res.json(result);
});
// 3. /wallet/credit
app.post("/wallet/credit", (req, res) => {
const { playerId, amount, transactionId, currency } = req.body;
if (processedTransactions.has(transactionId)) {
return res.json(processedTransactions.get(transactionId));
}
if (!playerBalances.hasOwnProperty(playerId)) {
return res.status(404).json({ success: false, code: "PLAYER_NOT_FOUND" });
}
playerBalances[playerId] += amount;
const result = { success: true, code: "SUCCESS", data: { transactionId, playerId, currency, balance: playerBalances[playerId] } };
processedTransactions.set(transactionId, result);
res.json(result);
});
// 4. /wallet/rollback
app.post("/wallet/rollback", (req, res) => {
const { playerId, amount, transactionId, originalTransactionId, currency } = req.body;
if (processedTransactions.has(transactionId)) {
return res.json(processedTransactions.get(transactionId));
}
if (playerBalances.hasOwnProperty(playerId)) {
playerBalances[playerId] += amount;
}
const result = { success: true, code: "SUCCESS", data: { transactionId, originalTransactionId, playerId, currency, balance: playerBalances[playerId] || 0 } };
processedTransactions.set(transactionId, result);
res.json(result);
});
app.listen(4000, () => console.log("Mock Seamless Wallet Server running on http://localhost:4000"));8. Retail & Land-Based POS Integration
For physical betting shops, kiosks, and franchise networks:
Counter interface for ticket placement with thermal printer output.
https://cashier.betbita.comStandalone touch terminal for players to select numbers directly on floor.
https://terminal.betbita.comLive 3D extraction machine & multi-tier progressive jackpots for shop monitors.
https://display.betbita.com/countdownBarcode Scanner Cash Payout Flow:
- Customer hands physical ticket slip to cashier.
- Cashier scans Code-128 barcode with standard 2D scanner.
- POS queries
GET /api/v1/retail/ticket/{ticketNumber}. - Cashier clicks "Pay Out". POS calls
POST /api/v1/retail/ticket/pay/{ticketNumber}. - Ticket transitions instantly to Paid in DB to prevent double-redemptions.
9. Live WebSocket Stream (wss://)
Displays and frontend clients can subscribe directly to live ball extraction events and countdowns:
{
"event": "BALL_REVEALED",
"roundNumber": 45462,
"ballNumber": 28,
"position": 14,
"multiplier": 120,
"timestamp": "2026-10-07T10:04:12Z"
}10. Standard Error Codes & Sandbox Checklist
| HTTP | Code | Meaning | BetBita Engine Behavior |
|---|---|---|---|
| 200 | SUCCESS | Operation completed | Accepts bet / completes settlement |
| 402 | INSUFFICIENT_FUNDS | Low player balance | Rejects ticket; prompts player |
| 401 | INVALID_SIGNATURE | HMAC mismatch | Alerts integration admins |
| 409 | DUPLICATE_TRANSACTION | Already processed | Handled idempotently |
| 500 | INTERNAL_ERROR | Partner system error | Retries with exponential backoff |
Sandbox Certification Checklist (Before Production)
- ✅ Receive Sandbox credentials (OperatorID, ApiKey, HMAC_Secret).
- ✅ Expose 4 callbacks on HTTPS staging URL.
- ✅ Test balance query, successful bet debit, and insufficient funds (402).
- ✅ Test win crediting on round completion and rollback on cancellation.
- ✅ Test idempotent resend of identical transaction IDs.
- ✅ Embed responsive iFrame and verify mobile screen scaling.