# Easy API Guide — casinoapi.shop (5 minute setup)

The simplest possible way to put 16,000+ casino games on your website.
No encryption, no signature — just your **token** and 3 API calls.

## What you need

| Thing | Where to find it |
| --- | --- |
| API token | Client Panel → Settings |
| Your server IP | run `curl https://api.ipify.org` on your server, then whitelist it in Settings |
| Callback URL | your own PHP file that receives bet/win updates (step 3) |

Base URL for everything: `https://casinoapi.shop`

---

## Step 1 — Show games on your website

```
GET https://casinoapi.shop/api/public/v1/games?token=YOUR_TOKEN&limit=100&offset=0
```

Every game comes back with:

```json
{
  "game_uid": "SMILE_sweet_bonanza",
  "name": "Sweet Bonanza",
  "provider": "Pragmatic Play",
  "image_url": "https://..."
}
```

Show the image + name on your site. Save the `game_uid` — you need it to launch.

## Step 2 — Launch a game when a player clicks

From **your server** (never the browser), POST:

```json
POST https://casinoapi.shop/api/public/v1/launch

{
  "token": "YOUR_TOKEN",
  "user_id": "10001",
  "balance": 500.00,
  "game_uid": "SMILE_sweet_bonanza",
  "return": "https://your-casino.com/lobby"
}
```

Success answer:

```json
{ "code": 0, "data": { "url": "https://...", "session_id": "..." } }
```

Send the player to `data.url` (redirect or iframe). Done — the game opens.

**Ready-made file:** download `GetGameUrl.php` from Client Panel → API Documentation.
Fill in your DB connection, token and EXIT_URL — nothing else to change.

### Player check before launch (automatic)

Just before the game opens, we POST to your Callback URL:

```json
{ "event": "verify_player", "user_id": "10001", "currency_code": "BDT" }
```

Answer with the player's real balance:

```json
{ "code": 0, "balance": 500.00 }
```

- account not found → answer `404` or `{"code":1,"msg":"User not found"}` and the game will not open.
- the balance you return becomes the session start balance — all win/loss maths start from it.
- **zero balance = no bet.** If the player's balance is `0` (or less), the game does not open — launch answers `{"code":1,"msg":"Insufficient balance — this player has no funds..."}`. Top up the player account first.
- once a Callback URL is saved, this check is **required**: if your server is offline or does not answer with valid JSON, the game will NOT open (we never trust a balance we could not verify). Only accounts with no Callback URL at all use the `balance` sent in the launch call (the same zero-balance rule applies to it).

## Step 3 — Receive balance updates (callback)

When a round finishes we POST to the **Callback URL** you saved in Settings:

```json
{
  "member_account": "10001",
  "serial_number": "unique-per-money-event",
  "bet_amount": 10.00,
  "win_amount": 25.00
}
```

Your callback must do 3 things:

1. If you already saw this `callback_id` or `serial_number`, return success with the live wallet balance; do not apply money twice.
2. Otherwise apply the delta atomically: `wallet = wallet - bet_amount + win_amount`. Never set the wallet from a game/session balance field.
3. Answer `200 OK` quickly with `{ "code": 0, "balance": LIVE_BALANCE }`.

Minimal PHP callback:

```php
<?php
$data = json_decode(file_get_contents('php://input'), true);
$serial = $data['callback_id'] ?? null;
$player = $data['member_account'] ?? null;
if (!$serial || !$player) { http_response_code(400); exit; }

$pdo = new PDO('mysql:host=localhost;dbname=casino', 'user', 'pass');
$bet = (float)($data['bet_amount'] ?? 0);
$win = (float)($data['win_amount'] ?? 0);

$pdo->beginTransaction();
try {
    // api_rounds.serial must have a UNIQUE index.
    $pdo->prepare('INSERT INTO api_rounds (serial) VALUES (?)')->execute([$serial]);
    $pdo->prepare('UPDATE players SET balance = balance - ? + ? WHERE id = ?')
        ->execute([$bet, $win, $player]);
    $pdo->commit();
} catch (PDOException $e) {
    $pdo->rollBack();
    // A duplicate-key retry is already applied: acknowledge it as success.
    if ($e->getCode() !== '23000') { throw $e; }
}
$balance = (float)$pdo->query("SELECT balance FROM players WHERE id = " . $pdo->quote($player))->fetchColumn();
http_response_code(200);
echo json_encode(['code' => 0, 'balance' => $balance]);
```

## Step 4 — Balance check when the player leaves the game (optional)

```
GET https://casinoapi.shop/api/public/v1/session?token=YOUR_TOKEN&user_id=10001
```

Shows the session totals for checking only. Every bet/win was already applied
through callbacks — add nothing to the wallet on exit.

---

## If something goes wrong

| code | meaning | fix |
| --- | --- | --- |
| 401 | bad token | copy it again from Settings |
| 403 | IP not allowed | whitelist your server IP |
| 404 | game not found | use a `game_uid` from the games list |
| 1 | low credit / currency mismatch | top up credit; read the `msg` field |

## Billing in one line

You pay only GGR: `max(0, total bets − total wins) × your rate` — charged
from your credit automatically. If credit runs out, game launch stops until
you top up.
