API Specification v1.0Production & Sandbox Ready

BetBita Lucky 6 Bingo — Partner Developer Guide

Jump to:
Section 1

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.

ComponentBetBita ProvidesPartner Platform Provides
Player IdentityTokenized game launch handlerPlayer ID, currency, username & session context
Wallet & WagersSynchronous HMAC-signed S2S client4 endpoints: /balance, /debit, /credit, /rollback
Payment MethodsExcluded / Omitted100% Partner Platform Owned (Cards, Mobile Money, Banks)
Game Client UIHosted 3D WebGL / HTML5 engineEmbedded iFrame (Web) or Native WebView (Mobile)
Live Draw FeedLow-latency SignalR / WebSocket streamConnect to stream or render embedded UI
Retail CounterThermal slip layout, barcode validation APIPC/terminal, 80mm ESC/POS printer, 2D scanner
Online / B2B iGaming90.0% RTP

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.

Retail Shop POS85.0% RTP

Physical Betting Shop Standard

Tailored for land-based franchised betting counters and cashier desks covering physical location overheads with 15% house retention margin.

Section 2

2. End-to-End Online Transaction Flow

The transaction lifecycle from player lobby launch to round settlement:

  1. 1. Game Launch: Partner backend calls POST /api/v1/game/launch and receives a tokenized launch URL.
  2. 2. Client Embedding: Partner loads the URL inside an iFrame (web) or native WebView (mobile app).
  3. 3. Balance Query: Game client initializes and BetBita calls Partner POST /wallet/balance to display current player balance.
  4. 4. Ticket Placement: Player bets. BetBita calls POST /wallet/debit. Partner synchronously deducts stake (or returns 402 if low balance).
  5. 5. Live 35-Ball Draw: 35 numbers drawn continuously from 48. Real-time extraction streamed over WebSocket.
  6. 6. Instant Credit / Win: Winning tickets trigger POST /wallet/credit immediately crediting player winnings.
Section 3

3. S2S Game Launch API

Your backend server requests a short-lived tokenized launch URL for authenticated players before rendering the iFrame.

POST/api/v1/game/launchS2S Only
🔑

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.

Open Merchant Portal →
EnvironmentAPI Base URLGame Client URLLive Stream (WSS)
Production (Live)https://api.betbita.comhttps://bingo.betbita.comwss://stream.betbita.com/hub/lucky6
Sandbox (Staging)https://staging-api.betbita.comhttps://staging-bingo.betbita.comwss://staging-stream.betbita.com/hub/lucky6
Target:
cURL — Game Launch with HMAC-SHA256 Signature
# 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}"
Response 200 OK — Launch URL Returned
{
  "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:

Real Mode ("mode": "real")

Operates on your Seamless Wallet. Deducts real stakes via /wallet/debit and automatically credits real winnings via /wallet/credit.

Fun Mode ("mode": "demo")

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.

Guest Demo URL (No API Key Required):

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.

Section 4

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.

HTML5 Responsive iFrame + Event Listener
<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>
Native Mobile Apps:

• iOS: Use WKWebView with allowsInlineMediaPlayback = true.

• Android: Use WebView with javaScriptEnabled = true and domStorageEnabled = true.

Section 5.1

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.

POST/wallet/balanceTrigger: Launch / Refresh
Request from BetBita
{
  "operatorId": "PARTNER001",
  "playerId": "USR_987654",
  "currency": "NAD",
  "requestId": "REQ-BAL-100001"
}
Expected Partner Response 200 OK
{
  "success": true,
  "code": "SUCCESS",
  "data": {
    "playerId": "USR_987654",
    "currency": "NAD",
    "balance": 1500.50,
    "availableBalance": 1500.50
  }
}
Section 5.2

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.

POST/wallet/debitTrigger: Ticket Placed
Request from BetBita
{
  "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 (200 OK):
json
{
  "success": true,
  "code": "SUCCESS",
  "data": {
    "transactionId": "TX-BET-20261007-008172",
    "playerId": "USR_987654",
    "currency": "NAD",
    "balance": 1480.50
  }
}
Insufficient Funds (402):
json
{
  "success": false,
  "code": "INSUFFICIENT_FUNDS",
  "message": "Player balance is insufficient."
}
Section 5.3

5.3 /wallet/credit (Win & Jackpot Credit)

Called immediately upon draw completion when the 35th ball finishes. Partner credits player wallet immediately.

POST/wallet/creditTrigger: Round Settle / Win
Request from BetBita
{
  "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"
}
Expected Partner Response 200 OK
{
  "success": true,
  "code": "SUCCESS",
  "data": {
    "transactionId": "TX-WIN-20261007-009941",
    "playerId": "USR_987654",
    "currency": "NAD",
    "balance": 7297.23
  }
}
Section 5.4

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.

POST/wallet/rollbackTrigger: Cancel / Void
Request from BetBita
{
  "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"
}
Expected Partner Response 200 OK
{
  "success": true,
  "code": "SUCCESS",
  "data": {
    "transactionId": "TX-RB-20261007-000101",
    "playerId": "USR_987654",
    "currency": "NAD",
    "balance": 1500.50
  }
}
Section 6

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.

Canonical String Format:
METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + REQUEST_ID + "\n" + SHA256(RAW_BODY)
Node.js Express HMAC Middleware (Copy-Paste)
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();
}
Section 7

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:

server.js — Complete Runnable Express Mock Server
// 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"));
Section 8

8. Retail & Land-Based POS Integration

For physical betting shops, kiosks, and franchise networks:

Cashier Terminal

Counter interface for ticket placement with thermal printer output.

https://cashier.betbita.com
Self-Service Terminal

Standalone touch terminal for players to select numbers directly on floor.

https://terminal.betbita.com
Shop TV Screen

Live 3D extraction machine & multi-tier progressive jackpots for shop monitors.

https://display.betbita.com/countdown

Barcode Scanner Cash Payout Flow:

  1. Customer hands physical ticket slip to cashier.
  2. Cashier scans Code-128 barcode with standard 2D scanner.
  3. POS queries GET /api/v1/retail/ticket/{ticketNumber}.
  4. Cashier clicks "Pay Out". POS calls POST /api/v1/retail/ticket/pay/{ticketNumber}.
  5. Ticket transitions instantly to Paid in DB to prevent double-redemptions.
Section 9

9. Live WebSocket Stream (wss://)

Displays and frontend clients can subscribe directly to live ball extraction events and countdowns:

WSSwss://stream.betbita.com/hub/lucky6SignalR / WSS
Example: BALL_REVEALED Event Payload
{
  "event": "BALL_REVEALED",
  "roundNumber": 45462,
  "ballNumber": 28,
  "position": 14,
  "multiplier": 120,
  "timestamp": "2026-10-07T10:04:12Z"
}
Section 10

10. Standard Error Codes & Sandbox Checklist

HTTPCodeMeaningBetBita Engine Behavior
200SUCCESSOperation completedAccepts bet / completes settlement
402INSUFFICIENT_FUNDSLow player balanceRejects ticket; prompts player
401INVALID_SIGNATUREHMAC mismatchAlerts integration admins
409DUPLICATE_TRANSACTIONAlready processedHandled idempotently
500INTERNAL_ERRORPartner system errorRetries 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.