Loading IA-Cafรฉ
Getting your data ready

๐Ÿ“Š Quick Overview

๐Ÿ†

13 Platforms

All major supported Nigerian betting platforms in one endpoint

๐Ÿ›ก๏ธ

Verify First

Confirm customer name before any wallet deduction

๐Ÿ’ฐ

โ‚ฆ100 โ€“ โ‚ฆ100,000

Flexible funding amount per transaction

๐Ÿ””

Webhook Updates

Track final status reliably with transaction webhooks

๐Ÿ’ฐ Commission & Charges

Field Meaning Example
amount The full amount the betting account will receive โ‚ฆ1,000
discount Your savings / commission on the transaction โ‚ฆ15.00
amount_charged The actual amount deducted from your wallet โ‚ฆ985.00
Betting account credited The user still receives the full requested funding amount โ‚ฆ1,000
How discount works: If the user funds โ‚ฆ1,000 and the platform discount is 1.5%, the betting account receives โ‚ฆ1,000 but your wallet is charged only โ‚ฆ985. The โ‚ฆ15 difference is your margin.
Important: Discount rates are configured server-side by IA-Cafรฉ admin. If no rate is configured, the discount may be 0%. Contact support if you need the current rate per platform.

๐Ÿ”„ How It Works

1

Verify Account

Call POST /devapi/v1/verify-customer with the betting account ID and betting platform. The API checks if the account exists and returns the account holder name. No wallet charge happens in this step.

2

Confirm With User

Show the returned customer name to the user before charging. Example: โ€œFund Bet9ja for John Doe โ€” โ‚ฆ1,000?โ€ This helps prevent wrong-account funding.

3

Fund Betting Wallet

After the user confirms, call POST /devapi/v1/betting with a unique request_id, account ID, platform and amount.

โœ“

Track Final Status

Listen for webhook event transaction.status_changed. If status is completed-api, the funding succeeded. If status is refunded-api, the wallet has been restored.

Best Practice: Always verify first, always show the verified customer name to the user, and never retry a transaction that returns processing until your webhook confirms the final result.

๐ŸŽฏ Supported Betting Platforms

Platform service_id Also Accepted As
1xBet1xBet1xbet
BangBetBangBetbangbet
Bet9jaBet9jabet9ja
BetKingBetKingbetking
BetLandBetLandbetland
BetLionBetLionbetlion
BetWayBetWaybetway
CloudBetCloudBetcloudbet
LiveScoreBetLiveScoreBetlivescorebet
MerryBetMerryBetmerrybet
NaijaBetNaijaBetnaijabet
NairaBetNairaBetnairabet
SupaBetSupaBetsupabet
Case-insensitive: Bet9ja, bet9ja and BET9JA are treated the same.

๐Ÿ—‚๏ธ All Endpoints

Method Endpoint Auth Description
POST /devapi/v1/verify-customer Required Verify betting account and return customer name
POST /devapi/v1/betting Required Fund betting account after verification / confirmation

๐Ÿ” Step 1 โ€” POST /verify-customer

Verify a betting account before funding it. This confirms the account exists on the selected platform and returns the customer name. No wallet charge is made during verification.

POST /devapi/v1/verify-customer

Request Body

Field Type Required Accepted Aliases Description
customer_id string Yes account_id, user_id The betting account ID or username from the user's betting app profile
service_id string Yes provider, platform The betting platform to verify against
cURL
curl -X POST "https://iacafe.com.ng/devapi/v1/verify-customer" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "12345678",
    "service_id": "Bet9ja"
  }'
Response โ€” Verified Successfully
{
  "success": true,
  "code": "success",
  "message": "Bet9ja customer verified",
  "service_type": "betting",
  "service_id": "Bet9ja",
  "service_name": "Bet9ja",
  "data": {
    "customer_id": "12345678",
    "customer_name": "John Doe",
    "customer_address": null,
    "customer_phone": null,
    "extra": {}
  }
}
Response โ€” Customer Not Found
{
  "success": false,
  "error": {
    "code": "customer_not_found",
    "message": "Betting account ID not found. Please check and retry."
  },
  "customer_id": "12345678",
  "service_id": "Bet9ja",
  "hint": "Double-check your betting account ID. It is usually found in your betting app profile."
}
Do not fund if verify fails: If verification returns customer_not_found, stop there and ask the user to check the account ID in their betting app.
Recommended confirmation message: Show the returned name to the user like this: โ€œFund Bet9ja for John Doe โ€” โ‚ฆ1,000?โ€

๐Ÿ’ธ Step 2 โ€” POST /betting

Fund a betting account after successful verification and user confirmation. Use a unique request_id for every transaction.

POST /devapi/v1/betting

Request Body

Field Type Required Aliases Description
request_id string Yes requestId, ref Your unique transaction reference. Maximum 50 characters. Must not be reused.
customer_id string Yes customerId, user_id, account_id, betting_id The betting account ID or username to fund. Minimum 3 characters.
service_id string Yes serviceId, provider, platform The betting platform to fund
amount number Yes amt Funding amount in Naira. Minimum โ‚ฆ100, maximum โ‚ฆ100,000.
skip_verify boolean Optional โ€” Set to true only if you already verified separately. Not recommended for normal use.
About request_id: This must be unique per transaction. If you reuse an old value, the API will return 409 duplicate_transaction and the new request will not be processed.
cURL
curl -X POST "https://iacafe.com.ng/devapi/v1/betting" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "request_id": "bet_20240101_abc123",
    "customer_id": "12345678",
    "service_id": "Bet9ja",
    "amount": 1000
  }'
JavaScript (fetch)
const response = await fetch('https://iacafe.com.ng/devapi/v1/betting', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    request_id: 'bet_20240101_abc123',
    customer_id: '12345678',
    service_id: 'Bet9ja',
    amount: 1000
  })
});

const data = await response.json();
console.log(data);
Response โ€” Success
{
  "success": true,
  "status": "completed",
  "message": "ORDER COMPLETED",
  "data": {
    "order_id": 12349,
    "customer_id": "12345678",
    "customer_name": "John Doe",
    "betting_platform": "Bet9ja",
    "amount": 1000,
    "amount_charged": "985.00",
    "discount": "15.00",
    "initial_balance": "5000.00",
    "final_balance": "4015.00",
    "request_id": "bet_20240101_abc123"
  }
}
Response โ€” Processing / Pending
{
  "success": true,
  "status": "processing",
  "message": "Transaction is being processed",
  "data": {
    "order_id": 12349,
    "customer_id": "12345678",
    "betting_platform": "Bet9ja",
    "amount": 1000,
    "amount_charged": "985.00",
    "request_id": "bet_20240101_abc123",
    "note": "You will be notified via webhook once confirmed. Do NOT retry."
  }
}
Response โ€” Provider Failed
{
  "success": false,
  "error": {
    "code": "provider_failed",
    "message": "Provider declined the transaction"
  },
  "order_id": 12349,
  "request_id": "bet_20240101_abc123",
  "refunded": true,
  "hint": "Check your betting account ID and try again"
}

๐Ÿ”” Webhook Events

Betting transactions emit the same webhook events as other IA-Cafรฉ services. Webhooks are the most reliable way to track the final outcome.

transaction.created

Payload
{
  "event": "transaction.created",
  "order_id": 12349,
  "request_id": "bet_20240101_abc123",
  "category": "betting",
  "service_id": "Bet9ja",
  "product_name": "Betting",
  "customer_id": "12345678",
  "amount": 1000,
  "amount_charged": 985,
  "discount": 15,
  "balance_before": 5000,
  "balance_after": 4015,
  "timestamp": "2024-01-01T00:00:00.000Z"
}

transaction.status_changed

Status Meaning Wallet
processing-api Transaction submitted and awaiting provider confirmation โณ Held
completed-api Betting account funded successfully โœ… Deducted
refunded-api Funding failed and wallet has been restored โ†ฉ๏ธ Restored
Completed Webhook
{
  "event": "transaction.status_changed",
  "order_id": 12349,
  "request_id": "bet_20240101_abc123",
  "status": "completed-api",
  "category": "betting",
  "service_id": "Bet9ja",
  "customer_id": "12345678",
  "amount": 1000,
  "amount_charged": 985,
  "discount": 15,
  "provider": "vtu",
  "timestamp": "2024-01-01T00:00:05.000Z"
}
Refunded Webhook
{
  "event": "transaction.status_changed",
  "order_id": 12349,
  "request_id": "bet_20240101_abc123",
  "status": "refunded-api",
  "category": "betting",
  "service_id": "Bet9ja",
  "customer_id": "12345678",
  "amount": 1000,
  "amount_charged": 985,
  "refund_reason": "provider_failed",
  "refunded_amount": 985,
  "balance_before_refund": 4015,
  "balance_after_refund": 5000,
  "timestamp": "2024-01-01T00:00:08.000Z"
}

โš ๏ธ Error Codes & What They Mean

Important: A pending or timeout response does not always mean failure. If the provider response is unclear, the transaction may stay in processing while final confirmation is being checked. Do not retry while it is pending.

๐Ÿ”ด Validation Errors (Your Request)

HTTP error.code What it means How to fix
400missing_fieldsRequired field(s) not sentCheck request body and include all required fields
400invalid_service_idPlatform not recognisedUse one of the supported betting platform IDs
400invalid_amountAmount is not a valid positive numberSend a numeric value such as 1000
400below_minimum_amountAmount is less than โ‚ฆ100Use at least โ‚ฆ100
400above_maximum_amountAmount exceeds โ‚ฆ100,000Use โ‚ฆ100,000 or less
400invalid_customer_idBetting account ID is too shortUse a valid account ID or username with at least 3 characters
404customer_not_foundAccount does not exist on that platformAsk the user to check their account ID in the betting app
409duplicate_transactionrequest_id already usedGenerate a new unique request ID

๐ŸŸ  Provider / Transaction Outcome Errors

HTTP error.code What it means What to do
202provider_timeoutProvider response is unclear and transaction is being verifiedDo not retry. Wait for the webhook result.
422provider_failedProvider clearly declined the transactionWallet is refunded. Ask user to check details and retry if needed.
503provider_unavailableProvider is not configured or unavailableTry later or contact IA-Cafรฉ support

๐Ÿ”‘ Authentication & Server Errors

HTTP error.code What it means How to fix
401unauthorizedMissing or invalid API keyAdd Authorization: Bearer YOUR_API_KEY header
402insufficient_balanceNot enough wallet balanceTop up your IA-Cafรฉ wallet first
500server_errorUnexpected internal errorRetry once. If it persists, contact support with your request_id

Error Response Format

Error Response
{
  "success": false,
  "error": {
    "code": "provider_failed",
    "message": "Provider declined the transaction"
  },
  "order_id": 12349,
  "request_id": "bet_20240101_abc123",
  "refunded": true
}

๐Ÿ“Œ Important Notes

Always Verify Before Funding: Never go straight to the funding endpoint unless you already verified the customer account. Verification protects you from sending money to the wrong betting wallet.
Pending Means Wait: If the API returns processing or provider_timeout, the transaction is still being checked. Do not retry while waiting for the webhook result.
Use request_id for Idempotency: Always send your own unique request_id. Reusing an old request ID returns duplicate_transaction and prevents accidental double funding.
Wallet Behaviour: On success the wallet remains deducted. If the provider clearly fails, the wallet is refunded. If the transaction is still pending, the amount may remain held until final resolution.
Best UX: After verify succeeds, show the returned customer name and amount clearly to the user before they confirm. Example: โ€œFund BetKing for Jane Doe โ€” โ‚ฆ5,000?โ€

๐ŸŸจ Complete Flow Example (JavaScript)

JavaScript โ€” Verify + Fund Flow
const BASE = 'https://iacafe.com.ng/devapi/v1';
const API_KEY = 'YOUR_API_KEY';

async function post(path, body) {
  const res = await fetch(`${BASE}${path}`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(body)
  });

  return res.json();
}

async function verifyBettingAccount(customerId, platform) {
  return post('/verify-customer', {
    customer_id: customerId,
    service_id: platform
  });
}

async function fundBettingAccount(requestId, customerId, platform, amount) {
  return post('/betting', {
    request_id: requestId,
    customer_id: customerId,
    service_id: platform,
    amount
  });
}

async function main() {
  const customerId = '12345678';
  const platform = 'Bet9ja';
  const amount = 1000;

  // Step 1: Verify account
  const verify = await verifyBettingAccount(customerId, platform);

  if (!verify.success) {
    console.error(`โŒ ${verify.error.code}: ${verify.error.message}`);
    return;
  }

  const customerName = verify.data.customer_name;
  console.log(`โœ… Verified account name: ${customerName}`);
  console.log(`Show user: Fund ${platform} for ${customerName} โ€” โ‚ฆ${amount}?`);

  // Step 2: After user confirms, fund the betting wallet
  const requestId = `bet_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
  const result = await fundBettingAccount(requestId, customerId, platform, amount);

  if (result.success && result.status === 'completed') {
    const d = result.data;
    console.log(`โœ… Funding successful for ${d.customer_name}`);
    console.log(`Amount funded: โ‚ฆ${d.amount}`);
    console.log(`Wallet charged: โ‚ฆ${d.amount_charged}`);
    console.log(`Discount: โ‚ฆ${d.discount}`);
    console.log(`Balance: โ‚ฆ${d.initial_balance} โ†’ โ‚ฆ${d.final_balance}`);
  } else if (result.success && result.status === 'processing') {
    console.log('โณ Transaction is processing. Do NOT retry. Wait for webhook confirmation.');
  } else {
    console.error(`โŒ ${result.error.code}: ${result.error.message}`);
    if (result.refunded) {
      console.log('โ†ฉ๏ธ Wallet has been refunded');
    }
  }
}

main();

๐Ÿ˜ Complete Flow Example (PHP)

PHP (cURL)
<?php

define('BASE', 'https://iacafe.com.ng/devapi/v1');
define('API_KEY', 'YOUR_API_KEY');

function apiPost($path, $body) {
    $ch = curl_init(BASE . $path);

    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($body),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . API_KEY,
            'Content-Type: application/json'
        ]
    ]);

    $res = curl_exec($ch);
    curl_close($ch);

    return json_decode($res, true);
}

// Step 1: Verify account
$verify = apiPost('/verify-customer', [
    'customer_id' => '12345678',
    'service_id'  => 'Bet9ja'
]);

if (!$verify['success']) {
    echo "โŒ {$verify['error']['code']}: {$verify['error']['message']}\n";
    exit;
}

echo "โœ… Verified customer: {$verify['data']['customer_name']}\n";
// Show user confirmation here before continuing

// Step 2: Fund account
$requestId = 'bet_' . time();
$result = apiPost('/betting', [
    'request_id'  => $requestId,
    'customer_id' => '12345678',
    'service_id'  => 'Bet9ja',
    'amount'      => 1000
]);

if (!empty($result['success']) && ($result['status'] ?? '') === 'completed') {
    $d = $result['data'];
    echo "โœ… Funded successfully for {$d['customer_name']}\n";
    echo "Amount funded: โ‚ฆ{$d['amount']}\n";
    echo "Wallet charged: โ‚ฆ{$d['amount_charged']}\n";
    echo "Balance: โ‚ฆ{$d['initial_balance']} โ†’ โ‚ฆ{$d['final_balance']}\n";
} elseif (!empty($result['success']) && ($result['status'] ?? '') === 'processing') {
    echo "โณ Processing. Do NOT retry. Wait for webhook confirmation.\n";
} else {
    echo "โŒ {$result['error']['code']}: {$result['error']['message']}\n";
    if (!empty($result['refunded'])) {
        echo "โ†ฉ๏ธ Wallet refunded\n";
    }
}

?>