Developer documentationHTTPS · Seamless wallet
EXCHANGE INTEGRATION

Your lobby.
Your wallet. One iframe.

Launch the exchange from your backend, embed it in your website, and keep control of every player balance through authenticated wallet callbacks.

API BASEhttps://api.betapidata.online
Server authentication

Merchant ID, API key and approved source IP.

Single-use launch

Consume each launch URL within five minutes.

Live exchange

Shared server feed delivers odds through WebSocket.

01 / PREPARE

Configure your merchant

Request merchant activation with your backend's public outbound IP, player website hostname, HTTPS lobby URL, wallet callback URL, and account currency. Test and production are configured per merchant.

  1. Store your merchant ID, API key and callback signing secret in a server-side secret store.
  2. Provide a public HTTPS callback with a valid certificate. Redirects and private-network callback targets are rejected.
  3. Approve both the actual backend IP and the player-site hostname. The X-Origin-Domain header does not replace IP verification.
  4. Choose one currency for the merchant. Every launch and wallet event must use that currency.
  5. Complete test placement, duplicate delivery, refund and settlement checks before production activation.
Player identity

Send your stable player reference in username. It is isolated under your merchant internally, so another merchant may use the same reference. Do not add our internal prefixes.

02 / LAUNCH

Create a launch session

POST/api/v1/launch.php

Call this endpoint from your backend after authenticating the player. Request and response bodies are JSON.

HeaderValue
Content-Typeapplication/json
X-Merchant-IdYour assigned merchant code
X-Api-KeyYour private merchant API key
X-Origin-DomainYour approved player hostname, e.g. merchant.example
JSON fieldRequirement
usernameStable player reference; 1–100 letters, digits or _ . @ -
request_idFresh unique request reference; 8–100 letters, digits, _ or -
currency_codeUppercase currency matching your merchant, such as BDT, USD or EUR
Backend request · PHP
<?php
$body = json_encode([
    'username' => $authenticatedPlayerReference,
    'request_id' => bin2hex(random_bytes(16)),
    'currency_code' => 'BDT',
], JSON_THROW_ON_ERROR);
$ch = curl_init('https://api.betapidata.online/api/v1/launch.php');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_CONNECTTIMEOUT => 5,
    CURLOPT_TIMEOUT => 20,
    CURLOPT_SSL_VERIFYPEER => true,
    CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'X-Merchant-Id: ' . getenv('EXCHANGE_MERCHANT_ID'),
        'X-Api-Key: ' . getenv('EXCHANGE_API_KEY'),
        'X-Origin-Domain: merchant.example',
    ],
]);
$raw = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($raw === false || $http !== 200) {
    throw new RuntimeException('Unable to launch the exchange.');
}
$result = json_decode($raw, true, 64, JSON_THROW_ON_ERROR);
$launchUrl = $result['launch_url'];

Successful response

{
  "success": true,
  "error": "",
  "launch_url": "https://api.betapidata.online/launch.php?token=ONE_TIME_TOKEN",
  "expires_in": 300,
  "currency_code": "BDT",
  "merchant_mode": "test"
}

The service checks your wallet balance through the configured callback before creating the launch. Lobby destination and branding come from merchant configuration, not an arbitrary browser-supplied URL.

03 / EMBED

Open the exchange

Return only the successful launch URL from your own authenticated backend to your frontend. Place it inside an iframe over your website content, with your own close control.

<iframe
  title="Sports exchange"
  src="LAUNCH_URL_FROM_YOUR_BACKEND"
  allow="fullscreen; autoplay"
  referrerpolicy="no-referrer"
  style="width:100%;height:100dvh;border:0"
></iframe>

Only approved merchant websites can embed the exchange. HTTPS and cookies are required. Some browsers restrict cross-site cookies; verify the embedded flow on your supported mobile and desktop browsers before enabling production.

Navigation and branding

The exchange logo returns to the exchange index within the iframe. An available configured logo is shown as an image; otherwise the configured brand name and icon are displayed. Merchant lobby navigation uses the approved lobby URL.

The launch token is single-use. A new launch for the same merchant and player replaces the previous session. The resulting player session lasts up to eight hours, subject to revocation or merchant suspension.

04 / WALLET

Implement the seamless wallet

We send HTTPS JSON requests to your configured wallet callback. Always authenticate the signature, verify the currency and locate the player using your own stable reference. Return HTTP 200 and the resulting available balance for a successful event.

Wallet changes follow the market portfolio’s worst-case exposure. A debit can differ from the new bet’s stake because earlier selections in the same market can offset its risk.

Callback headers

Content-Type: application/json
X-Merchant-Id: YOUR_MERCHANT_CODE
X-Timestamp: UNIX_SECONDS
X-Signature: LOWERCASE_HEX_HMAC_SHA256
X-Idempotency-Key: STABLE_EVENT_REFERENCE
ActionWallet behavior
balanceRead the current available player balance. No debit or credit.
debitDeduct the positive increase in the market portfolio’s worst-case liability once. Refuse insufficient funds.
debit_confirmRecord confirmation of an accepted order. Informational only; do not deduct again.
creditCredit the supplied amount once when an accepted order reduces portfolio exposure, or when a confirmed rejection releases a reservation.
settlementCredit the supplied positive final amount once: released market reserve plus the market’s net result. The amount already includes the result; do not add profit again.

Balance request and response

{
  "action": "balance",
  "request_id": "launch_d07c1e9f38a44b25",
  "username": "player123",
  "currency": "BDT"
}
{ "success": true, "balance": 1000.00, "currency": "BDT" }

Order wallet event

{
  "action": "debit",
  "order_id": "12345678",
  "username": "player123",
  "amount": 10.00,
  "currency": "BDT"
}

Order events may include additional match, market, selection and settlement metadata. Use the supplied wallet amount rather than recomputing it from a displayed stake. Available balances must be finite, non-negative numbers with at most two decimal places. Never return secrets or internal database errors.

Required before activation

Confirm settlement metadata and adjustment semantics in your merchant acceptance test. A lost callback response is an uncertain outcome: retain the pending event and reconcile it before manually refunding or sending a different credit.

05 / AUTHENTICATE

Verify the original request bytes

Compute a lowercase hexadecimal HMAC-SHA256 over X-Timestamp + "." + raw_request_body with your callback secret. Compare using a constant-time function and enforce a short timestamp window. Parse JSON only after authenticating it.

Callback authentication · PHP
<?php
$raw = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$merchant = $_SERVER['HTTP_X_MERCHANT_ID'] ?? '';
$expectedMerchant = getenv('EXCHANGE_MERCHANT_ID');
$secret = getenv('EXCHANGE_CALLBACK_SECRET');
if (!is_string($raw) || strlen($raw) > 65536
    || !ctype_digit($timestamp) || abs(time() - (int)$timestamp) > 60
    || !hash_equals($expectedMerchant, $merchant)
    || !hash_equals(hash_hmac('sha256', $timestamp . '.' . $raw, $secret), $signature)) {
    http_response_code(401);
    exit;
}
$event = json_decode($raw, true, 64, JSON_THROW_ON_ERROR);
$eventKey = $_SERVER['HTTP_X_IDEMPOTENCY_KEY'] ?? '';

This snippet authenticates transport only. Your handler must then validate fields and apply the wallet change and event record together in one database transaction.

06 / CONSISTENCY

Process each wallet event once

  1. Require a valid signed merchant event. A timestamp check alone does not prevent replay.
  2. Use a unique database constraint on merchant and X-Idempotency-Key, with a stored hash of the authenticated payload.
  3. Lock the player wallet, verify funds, apply the requested change and save the complete successful response in one transaction.
  4. For a matching duplicate event, return the saved response without changing the wallet again. Reject a reused key with a different payload.
  5. Keep failed or uncertain events for reconciliation. A network timeout does not prove a wallet event failed.

Do not blindly retry launch requests with the same request_id. Duplicate launch references are rejected. If a token response is lost, request a new launch with a fresh reference; the launch balance check itself does not debit the wallet.

07 / RESPONSES

Handle errors without exposing them to players

HTTPTypical causeAction
400 / 422Invalid fields or currency mismatchCorrect the server-side request.
401Invalid merchant credentials or ended player sessionVerify credentials, or create a new player launch after authentication.
403Unapproved source IP or domainCheck the registered outbound IP and website.
409Duplicate launch request referenceUse a new launch reference.
410Used, expired or revoked launch tokenCreate a new authenticated launch.
502 / 503Wallet callback or service unavailableShow a short retry message and retain the request reference for support.

Player-facing interfaces should show a safe message such as “Unable to load. Please try again later.” Keep technical diagnostics in restricted server logs. Never put API keys, callback secrets or provider addresses in client bundles, iframe query parameters or analytics.

08 / PRODUCTION

Run the acceptance checklist

Test merchants use per-currency stake and liability limits. Production activation is an explicit merchant configuration change. A live data feed does not automatically make a test merchant a production merchant.

PLANNED / PHASE 2

Merchant billing and self-service

This release covers the authenticated exchange iframe and seamless-wallet order flow. Self-service registration, merchant dashboard, subscription packages, manual-crypto or NOWPayments top-ups, and GGR-wallet billing are planned separately and are not exposed as public endpoints in this release.

The proposed billing model includes instant or 7 / 15 / 30-day settlement, configurable minimum stock, regular or advanced merchant risk policies, and signed pending GGR carried forward before billing. Player wins must offset pending GGR rather than create an automatic merchant-wallet credit. These policies require a dedicated billing ledger and acceptance tests before activation.