# Dicey Fun Third-Party Integration Guide (Based on Existing Project APIs)

## 1. Basic Information

- provider: `Dicey Fun`
- provider_code: `DF`
- game_type: `slot`
- game_list: `["dafuwen"]`
- provider_logo: ``
- Lobby URL (reference): `https://dice-v3-lobby.h55555game.top`
- Admin console URL: `https://dice-v3.h55555game.top/`
- agent_token: `[View in admin console menu: System Management -> User Management -> Agent ID]`
- agent_id: `5ef059938ba799aaa845e1c2e8a762bd`

## 2. API Domain and Protocol

- Protocol: `HTTP/HTTPS` (Production is recommended to use `HTTPS`)
- Base URL: `https://{your-domain}` (Provided by the deployment party)
- Content-Type: `application/json`
- Charset: `UTF-8`

### 2.1 Calling Conventions (Recommended for Third Parties)

- `/api/v1/authToken` uses `GET + Query parameters`
- Other `/api/v1/*` endpoints use `POST + JSON Body` (In this project the route is `Route::any`, but third parties are recommended to standardize on `POST`)
- Unified headers:
  - `Content-Type: application/json`
  - `Accept: application/json`
  - `api-key: {api_key}` (**Required for ALL `/api/v1/*` endpoints**, must match `API_KEY` in server `.env`)
  - `auth-token: {authtoken}` (Required for all endpoints except `/api/v1/authToken`)
- `api-key` may be supplied in any of the following ways (read in priority order, first non-empty wins):
  1. HTTP header `api-key` (**recommended**)
  2. Query string `api_key` (or `api-key`)
  3. Body form/JSON field `api_key` (or `api-key`)
- All time-related parameters use Unix timestamps (seconds)
- Recommended timeouts: connect timeout `3s`, read timeout `10s`
- Production recommendation: add caller IP whitelist and retry backoff (to avoid burst retry storms)

---

## 3. Common Response Format

All endpoints return the following structure:

```json
{
  "code": 200,
  "message": "success",
  "data": {}
}
```

Notes:

- `code=200` indicates success
- Failures typically return: `400/401/402/403/404/422/500`

Common error codes:

- `400` Invalid parameters
- `401` Missing `api-key`, `auth-token` or `token`
- `402` Token invalid or expired
- `403` Invalid `api-key`, signature or authentication failed
- `404` Resource not found
- `422` Business error (e.g., insufficient balance)
- `500` Server exception

---

## 4. Authentication Flow (Platform Level)

Two layers of platform-level credentials:

- **`api-key`**: Required for ALL `/api/v1/*` endpoints, must match `API_KEY` in server `.env`. May be sent in header, query, or body (see §2.1).
- **`auth-token`**: Required for business endpoints (i.e., everything except `/api/v1/authToken`); obtained from `/api/v1/authToken`.

Before calling any `/api/v1/*` endpoint, obtain an `auth-token` first.

### 4.1 Get auth-token

- Path: `GET /api/v1/authToken`
- Header:
  - `api-key: {api_key}` (Required, must match `API_KEY` in server `.env`)
- Auth parameters (Query):
  - `agent_id`: Agent identifier (merchant identifier)
  - `secret`: Shared secret agreed by both parties
  - `time`: Unix timestamp (seconds)
  - `signature`: Signature

Signature rule:

```text
signature = md5(agent_id + secret + time)
```

Signature example (source string and result):

```text
agent_id = 9f86d081884c7d659a2feaa0c55ad015
secret   = xF75oK91TQj13s0UmNIr1NBWMWGfflNO
time     = 1713753600
sign_src = 9f86d081884c7d659a2feaa0c55ad015xF75oK91TQj13s0UmNIr1NBWMWGfflNO1713753600
signature= md5(sign_src)
```

PHP signature example:

```php
$agentId = '9f86d081884c7d659a2feaa0c55ad015';
$secret = 'xF75oK91TQj13s0UmNIr1NBWMWGfflNO';
$time = (string) time();
$signature = md5($agentId . $secret . $time);
```

JavaScript signature example (Node.js):

```javascript
const crypto = require('crypto');

const agentId = '9f86d081884c7d659a2feaa0c55ad015';
const secret = 'xF75oK91TQj13s0UmNIr1NBWMWGfflNO';
const time = Math.floor(Date.now() / 1000).toString();
const signature = crypto.createHash('md5').update(agentId + secret + time).digest('hex');
```

Server-side validation logic (key points):

- Missing `api-key` => fail (`401`); `api-key` not equal to `.env` `API_KEY` => fail (`403`)
- Missing any of `agent_id/secret/time/signature` => fail (`400`)
- `secret` mismatch => fail (`403`)
- `time` outside tolerance window => fail (`403`, default tolerance `300s`)
- `signature` mismatch => fail (`403`)
- If validated, the server issues `authtoken`; subsequent requests must include it in the `auth-token` header (and still carry `api-key`)

Anti-replay and time sync recommendations:

- Caller server must enable NTP time synchronization
- `time` should be the current seconds timestamp at request time; do not reuse old values
- If you see “Timestamp expired or invalid”, first check server clock drift

Success response example:

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "authtoken": "xxx.yyy.zzz"
  }
}
```

For subsequent calls to `/api/v1/*`, include the following headers:

```text
api-key: {api_key}
auth-token: {authtoken}
```

### 4.2 Full Call Chain (Recommended)

1. Compute `signature = md5(agent_id + secret + time)`
2. Call `GET /api/v1/authToken` (Header `api-key`) to obtain `authtoken`
3. Add headers `api-key: {api_key}` and `auth-token: {authtoken}`
4. Call business endpoints (e.g., `getPlayerInfo`, `setPlayerWallet`, `getGameUrl`, `getPlayerGameRecord`, `getPlayerWalletRecord`, `getPlayerTicketRecord`)
5. If `402` is returned, re-fetch `authtoken` and retry once

---

## 5. Game APIs

All endpoints below require headers `api-key` + `auth-token` (`api-key` may also be sent via query/body, see §2.1).

## 5.1 Get Game List (Supported)

- Path: `POST /api/v1/getGameList`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters:
  - `lang` (optional): `zh`/`en`, default `zh`
- Response notes:
  - Reads enabled games (`status=1`) from the `dice_game` table
  - Currently returns only one game by default: `dafuwen`
  - Returns `game_name` in Chinese/English according to `lang`
  - Fields are desensitized: sensitive configs (e.g., `sensitive_config_json`) will not be returned

Response fields (`data.game_list[]`):

- `provider`: Provider name
- `provider_code`: Provider code
- `game_code`: Game code
- `game_key`: Unique game key
- `game_type`: Game type
- `logo`: Game logo URL
- `game_url`: Game URL
- `hall_url`: Lobby URL
- `status`: Status (`1` enabled)
- `sort`: Sort value
- `game_name`: Game name (Chinese/English based on `lang`)

Success example (`lang=zh`):

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "game_list": [
      {
        "provider": "Dicey Fun",
        "provider_code": "DF",
        "game_code": "dafuwen",
        "game_key": "dafuwen",
        "game_type": "slot",
        "logo": "",
        "game_url": "https://dice-v3-game.h55555game.top/",
        "hall_url": "https://dice-v3-game.h55555game.top/",
        "status": 1,
        "sort": 1,
        "game_name": "大富翁"
      }
    ]
  }
}
```

Success example (`lang=en`):

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "game_list": [
      {
        "provider": "Dicey Fun",
        "provider_code": "DF",
        "game_code": "dafuwen",
        "game_key": "dafuwen",
        "game_type": "slot",
        "logo": "",
        "game_url": "https://dice-v3-game.h55555game.top/",
        "hall_url": "https://dice-v3-game.h55555game.top/",
        "status": 1,
        "sort": 1,
        "game_name": "Dafuweng"
      }
    ]
  }
}
```

## 5.2 Get Game Hall Info (Supported, Desensitized)

- Path: `POST /api/v1/getGameHall`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters:
  - `lang` (optional): `zh`/`en`, default `zh`
- Response notes:
  - Returns lobby URL `hall_url`
  - Returns game list (from `dice_game`)
  - Does not return sensitive information fields

Response fields:

- `data.provider`: Provider name
- `data.provider_code`: Provider code
- `data.hall_url`: Lobby URL
- `data.game_list`: Game list (same structure as `/api/v1/getGameList`)

Success example:

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "provider": "Dicey Fun",
    "provider_code": "DF",
    "hall_url": "https://dice-v3-game.h55555game.top/",
    "game_list": [
      {
        "provider": "Dicey Fun",
        "provider_code": "DF",
        "game_code": "dafuwen",
        "game_key": "dafuwen",
        "game_type": "slot",
        "logo": "",
        "game_url": "https://dice-v3-game.h55555game.top/",
        "hall_url": "https://dice-v3-game.h55555game.top/",
        "status": 1,
        "sort": 1,
        "game_name": "大富翁"
      }
    ]
  }
}
```

Success example (`lang=en`):

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "provider": "Dicey Fun",
    "provider_code": "DF",
    "hall_url": "https://dice-v3-game.h55555game.top/",
    "game_list": [
      {
        "provider": "Dicey Fun",
        "provider_code": "DF",
        "game_code": "dafuwen",
        "game_key": "dafuwen",
        "game_type": "slot",
        "logo": "",
        "game_url": "https://dice-v3-game.h55555game.top/",
        "hall_url": "https://dice-v3-game.h55555game.top/",
        "status": 1,
        "sort": 1,
        "game_name": "Dafuweng"
      }
    ]
  }
}
```

## 5.3 Get Game URL (Supported)

- Path: `POST /api/v1/getGameUrl`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters:
  - `username` (required): Player username (auto-created if not exists)
  - `time` (optional): if omitted, server uses current timestamp
  - `lang` (optional): `zh`/`en`, default `zh`

Success example:

```json
{
  "code": 200,
  "message": "success",
  "data": {
    "url": "https://{game-domain}/?token=...&lang=zh"
  }
}
```

### 5.4 Lobby URL (Recommendation for This Project)

This project uses `getGameUrl` as the primary entry method, and `game_list` currently contains only `dafuwen`.

- If the third party needs a standalone lobby URL, use your configured value: `[to be filled]`
- If the third party can jump directly into the game, call `getGameUrl` directly

### 5.5 Game List API (Current Project Status)

An independent endpoint is provided: `POST /api/v1/getGameList`, supporting both Chinese and English, with data from the `dice_game` table.

## 5.6 Get Player Game Records (Supported)

- Path: `POST /api/v1/getPlayerGameRecord`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters:
  - `username` (optional): Player username; if omitted, **no player filter** is applied (returns matching rows from the database—use with care)
  - `start_create_time` (optional), `end_create_time` (optional): Filter on `create_time`. Queries are **restricted to the rolling 7-day window ending at server “now”**, and the span between the two bounds **must not exceed 7 days**. If both are omitted, the server defaults to that full 7-day window. If `end_create_time` is after “now”, it is truncated to “now”. Invalid ranges return a parameter error.
  - `limit` (optional): Maximum number of rows to return, default `20`; if less than `1` or greater than `2000`, it is treated as `20`
- Response notes:
  - On success, `data` is an **array** (ordered by `id` descending, at most `limit` rows). Each item is a `dice_play_record` row plus `dice_player`: `{ id, username, phone }` (or `null` if the player cannot be resolved)
  - If `username` is provided but the player does not exist: `data` is an empty array `[]`

Main fields (same as table columns, partial list): `id`, `player_id`, `admin_id`, `lottery_config_id`, `lottery_type`, `ante`, `paid_amount`, `is_win`, `win_coin`, `super_win_coin`, `reward_win_coin`, `use_coins`, `direction`, `reward_tier`, `lottery_id`, `start_index`, `target_index`, `roll_array`, `roll_number`, `lottery_name`, `status`, `create_time`, `update_time`, etc.

---

## 6. Game Management Admin (Added)

This update introduces a game management table and menu to centrally manage basic game information.

### 6.1 Database Table

- Table creation SQL: `server/db/dice_game.sql`
- Table name: `dice_game`
- Key fields:
  - `logo`: Game logo
  - `game_url`: Game URL
  - `hall_url`: Lobby URL
  - `game_code`: Game code
  - `game_key`: Unique game key
  - `status`: Status (1 enabled / 0 disabled)
  - `game_type`: Game type
  - `merchant_config_json`: Merchant-visible extensions
  - `sensitive_config_json`: Sensitive configuration (not returned by hall APIs)

### 6.2 Menu and Permissions

- Menu SQL: `server/db/dice_game_menu.sql`
- Menu path: `/dice/game/index`
- Permission identifiers:
  - `dice:game:index:index`
  - `dice:game:index:read`
  - `dice:game:index:save`
  - `dice:game:index:update`
  - `dice:game:index:destroy`

---

## 7. Wallet APIs

All endpoints below require headers `api-key` + `auth-token` (`api-key` may also be sent via query/body, see §2.1).

### 7.1 Query Balance (Supported)

Method 1 (recommended): `POST /api/v1/getPlayerInfo`

- Request parameters:
  - `username` (required)
- Balance field:
  - `data.coin`

### 7.2 Credit In / Credit Out (Supported)

Endpoint: `POST /api/v1/setPlayerWallet`

- Request parameters:
  - `username` (required)
  - `coin` (required)
    - `coin > 0`: Credit in (deposit)
    - `coin < 0`: Credit out (withdraw)
    - `coin = 0`: Invalid

On success, returns a `wallet record` including balances before/after transfer.

### 7.3 Get Lobby URL (Wallet-side)

If the integrator’s wallet flow requires “return lobby URL after transfer”, call the following after `setPlayerWallet`:

- `POST /api/v1/getGameUrl`

### 7.4 Get Player Wallet Records (Supported)

- Path: `POST /api/v1/getPlayerWalletRecord`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters:
  - `username` (optional): Player username; if omitted, **no player filter** is applied
  - `start_create_time`, `end_create_time` (optional): Same as `getPlayerGameRecord`, applied to `create_time`
  - `limit` (optional): Same rules as `getPlayerGameRecord`
- Response notes:
  - On success, `data` is an array of `dice_player_wallet_record` rows with related `dice_player` (`id`, `username`, `phone`)
  - If `username` is provided but the player does not exist: `data` is an empty array `[]`

`type` meaning: `0` deposit, `1` withdraw, `2` purchase draw chances (consistent with how records are written in business logic).

### 7.5 Get Player Ticket Acquisition Records (Supported)

- Path: `POST /api/v1/getPlayerTicketRecord`
- Header:
  - `api-key: {api_key}`
  - `auth-token: {authtoken}`
- Body parameters: Same as **7.4** (`username`, `start_create_time`, `end_create_time`, `limit`)
- Response notes:
  - On success, `data` is a list of `dice_player_ticket_record` rows with related `dice_player`
  - If `username` is provided but the player does not exist: `data` is an empty array `[]`

Main fields (partial list): `id`, `player_id`, `admin_id`, `use_coins`, `ante`, `total_ticket_count`, `paid_ticket_count`, `free_ticket_count`, `remark`, `create_time`, `update_time`, etc.

---

## 8. Merchant (Agent) Configurable Fields

It is recommended to configure the following fields in the integration parameter table:

- `provider`: `Dicey Fun`
- `provider_code`: `DF`
- `agent_id`: `5ef059938ba799aaa845e1c2e8a762bd`
- `secret`: Signature secret (shared by both parties, maps to server `.env` `API_AUTH_TOKEN_SECRET`)
- `api_key`: The `api-key` required by every `/api/v1/*` request (maps to server `.env` `API_KEY`)
- `agent_token`: `[to be filled by us]` (if an additional business-layer token is needed)
- `game_url`: Game frontend domain/URL
- `lobby_url`: Lobby URL (optional)
- `lang`: Default language (`zh`/`en`)
- `callback_url`: Business callback URL (for future extension)
- `ip_whitelist`: Caller IP whitelist (recommended)

---

## 9. Admin Console Information

- Admin console URL: `https://dice-v3.h55555game.top/`
- Username: `zhuguan`
- Password: `qwer1234`

---

## 10. Integration Sequence (Recommended)

1. Platform assigns `agent_id`, `secret` and `api_key`
2. Third party calls `/api/v1/authToken` (with header `api-key`) to obtain `authtoken`
3. Third party calls `/api/v1/getGameHall` or `/api/v1/getGameList` to obtain lobby/game info
4. Third party calls `/api/v1/getPlayerInfo` (optional, check user and balance)
5. Third party calls `/api/v1/setPlayerWallet` to credit in (if applicable)
6. Third party calls `/api/v1/getGameUrl` to get the game URL and redirect
7. After the session, call `/api/v1/setPlayerWallet` to credit out (if applicable)
8. (Optional) Reconciliation or support: call `/api/v1/getPlayerWalletRecord`, `/api/v1/getPlayerGameRecord`, `/api/v1/getPlayerTicketRecord` to pull history

---

## 11. Postman / cURL Examples

### 11.1 Get auth-token

```bash
curl --location --request GET 'https://{your-domain}/api/v1/authToken?agent_id={agent_id}&secret={secret}&time={time}&signature={signature}' \
--header 'api-key: {api_key}'
```

During integration testing, it is recommended to print the following values locally before sending the request to ease troubleshooting:

- `agent_id`
- `time`
- `sign_src` (concatenated source string before hashing)
- `signature`
- Final request URL

### 11.2 Get Game URL

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getGameUrl' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001",
  "lang":"zh"
}'
```

### 11.3 Get Game List (Chinese)

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getGameList' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "lang":"zh"
}'
```

### 11.4 Get Game List (English)

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getGameList' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "lang":"en"
}'
```

### 11.5 Get Game Hall (Chinese)

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getGameHall' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "lang":"zh"
}'
```

### 11.6 Credit In

```bash
curl --location --request POST 'https://{your-domain}/api/v1/setPlayerWallet' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001",
  "coin":100
}'
```

### 11.7 Query Balance

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getPlayerInfo' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001"
}'
```

### 11.8 Get Player Game Records

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getPlayerGameRecord' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001",
  "limit":20
}'
```

### 11.9 Get Player Wallet Records

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getPlayerWalletRecord' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001",
  "limit":20
}'
```

### 11.10 Get Player Ticket Records

```bash
curl --location --request POST 'https://{your-domain}/api/v1/getPlayerTicketRecord' \
--header 'Content-Type: application/json' \
--header 'api-key: {api_key}' \
--header 'auth-token: {authtoken}' \
--data-raw '{
  "username":"test_player_001",
  "limit":20
}'
```
