# 更新記錄
### 2024/12/12
- 新增取得分鐘統計資料 api
- 更新餘額功能僅接受小數點後2位
# 遊戲API
遊戲相關 API 網址請使用我方提供之 API 網址
# 安全性
## 存取憑證(token)
> **取得進入存取憑證**
每10分鐘會失效
GET
```
/token
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Operator | 字串 | O | 經營方代碼 |
| X-Key | 字串 | O | 經營方API密鑰 |
- 標頭-範例:
```json
{
"X-Operator": "op1",
"X-key": "aqA12Wsqa341"
}
```
- 請求-範例:
`http://sample.domain.com/token`
### Success 200
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 物件[] | O | 產生存取憑證 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"token": "55xBgeODPYO7q...fNwXlJTsqRU4NZ4bmKLD"
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| Forbidden | X-Operator Or X-Key 錯誤 | 403 |
| Unauthorized | 驗證未通過 | 401 |
| Bad Request | 提供資料未正確 | 400 |
| Token Expired | 密鑰無效 | 401 |
| Operator invalid | X-Operator無效 | 401 |
| Internal Server Error | 伺服器發生問題 | 500 |
| Ip location not allowed | IP位置不允許 | 403 |
---
# 進入遊戲流程
## 註冊
> **註冊新的使用者**
POST
```
/register
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶名.格式: 英數字(禁止使用特殊符號)最小長度: 5, 最大長度:64 |
| email | 字串 | X | 使用者郵箱 |
| birthday | 日期 | X | 使用者出生日期ISO-8601 格式 |
| country | 字串 | X | 國籍代碼預設Taiwan |
| fullname | 字串 | X | 使用者於遊戲中顯示之名稱(未設定以username顯示) |
| language | 字串 | X | 遊戲語言: zh-cn, zh-tw, en, vn, th (預設為商戶設定之語系)|
- 請求-範例:
```json
{
"username": "myuser123",
"country": "China",
"fullname": "My User",
"language": "zh-cn",
"email": "myuser123@test.com",
"birthdate": "1992-02-18"
}
```
- 回應-成功:
```json
HTTP/1.1 200 Created
{}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| Unauthorized | 驗證未通過 | 401 |
| Bad Request | 提供資料未正確 | 400 |
| Username is required | 用戶名稱必填 | 400 |
| Email is required | 用戶email必填 | 400 |
| Language not allowed | 未支援語系 | 400 |
| user exists | user 已存在 | 400 |
| invalid parameter | 提供參數錯誤 | 400 |
| Token Expired | 密鑰無效 | 401 |
| Internal Server Error | 伺服器發生問題 | 500 |
| InternalServerError | 伺服器發生問題 | 500 |
---
## 取得所有供應商
> **取得遊戲供應商資料列表**
GET
```
/game-providers
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| rows | 整數 | X | 回傳記錄筆數預設10 |
| page | 整數 | X | 頁數預設1 |
| sidx | 字串 | X | 排序的欄位名稱預設id |
| sord | 字串 | X | 排序樣式預設asc允許值: "asc", "desc" |
- 請求-範例:
```
http://sample.domain.com/game-providers
http://sample.domain.com/game-providers?page=2
http://sample.domain.com/game-providers?page=1&rows=10
http://sample.domain.com/game-providers?page=1&rows=10&sidx=name&sord=desc
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| gameProviders | 物件[] | 遊戲供應商列表 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"gameProviders": [
{
"id": "1",
"name": "Game Provider 1",
"code": "gp1"
},
{
"id": "2",
"name": "Game Provider 2",
"code": "gp2"
}
],
"meta": {
"totalRecords": 2,
"totalPages": 2,
"currentPage": 1,
"hasPrevious": false,
"hasNext": true
}
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| forbidden Gameprovider | 遊戲商錯誤 | 401 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 取得餘額
> **取得用戶在供應商的餘額**
GET
```
/game-providers/:providerId/balance
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商id |
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶名 |
- 請求-範例:
`http://sample.domain.com/game-providers/1/balance?username=myuser123`
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balance | 字串 | 即時餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balance": "100.00",
"status": "Enabled",
"playing": "no"
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| Missing parameter | 參數不可為空 | 403 |
| User not found | 會員不存在 | 403 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 更新餘額
> **更新用戶在供應商的餘額**
POST
```
/game-providers/:providerId/balance
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商 id |
### 參數(Body)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶名 |
| balance | 浮點數(小數後2位) | O | 被加或被減數大於0,僅支援小數後2位 |
| action | 字串 | O | 提款或取款代碼無效代碼預設成IN允許值: "IN", "OUT" |
| transferId | 字串 | O | 經營方轉賬交易單號 |
- 請求-範例:
```json
{
"username": "sampop01",
"balance": 500,
"action": "out",
"transferId": "sampleTransfercode"
}
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balance | 字串 | 最新余額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balance": "1.00"
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP Status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 400 |
| invalid parameter | 錯誤參數設定 | 403 |
| IncompleteParameter | 參數設定不完整 | 403 |
| Prohibited to transfer while game in progress | 遊戲中禁止轉入/出 | 403 |
| Missing parameter | 數值不可為空 | 403 |
| Only accepts 2 decimal places | 僅接受小數後2位 | 403 |
| User not found | 會員不存在 | 404 |
| transferId already exists | 交易單號已經存在 | 400 |
| forbidden | 遊戲商錯誤 | 500 |
| Transfer failed | 轉賬失敗 | 400 |
| InternalServerError | 內部服務器錯誤 | 500 |
| Internal Server Error | 內部服務器錯誤 | 500 |
| User balance has been blocked | 用戶餘額鎖定 | 401 |
---
## 取得遊戲列表
> **取得遊戲列表**
GET
```
/games
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| provider | 整數 | O | 遊戲供應商id |
| category | 字串 | X | 遊戲分類 |
| rows | 整數 | X | 回傳記錄筆數預設50 |
| page | 整數 | X | 頁數預設1 |
| sidx | 字串 | X | 排序的欄位名稱預設id |
| locale | 字串 | X | 篩選指定語言遊戲, 支援 zh-cn, zh-tw, en, jp, vn, th |
| sord | 字串 | X | 排序樣式預設asc允許值: "asc", "desc" |
| type | 字串 | X | 遊戲類型預設blank允許值: "desktop", "mobile" |
- 請求-範例:
```
http://sample.domain.com/games
http://sample.domain.com/games?category=slot
http://sample.domain.com/games?provider=1
http://sample.domain.com/games?page=2
http://sample.domain.com/games?page=1&rows=10
http://sample.domain.com/games?page=1&rows=10&sidx=name&sord=desc
http://sample.domain.com/games?type=desktop
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| games | 物件[] | 遊戲列表 |
- 回應-成功:
- gameType 1: slot, 2: poker, 3: lottery
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"games": [
{
"category": "slot",
"name": "天狗祭",
"providerId": 4,
"code": "tengu-festival",
"gameId": 82,
"actived": true,
"locales": [
"zh-cn",
"zh-tw",
"en",
"jp",
"vn"
],
"id": 82,
"disabled": 0,
"gameType": 1,
"isNew": false,
"isHot": false,
"url": "https://play.godeebxp.com/egames/50addb64f3e1285277a4917d71736b94/game/images/platform/zh-tw/game_icon.png"
},
{
"category": "poker",
"name": "搶莊妞妞",
"providerId": 4,
"code": "banker-bull",
"gameId": 68,
"actived": true,
"locales": [
"zh-cn",
"zh-tw",
"en",
"jp"
],
"id": 68,
"disabled": 0,
"gameType": 2,
"isNew": false,
"isHot": false,
"url": "https://play.godeebxp.com/egames/5ded8101bcdb4fa7864ca42873aac888/game/images/platform/zh-tw/game_icon.png"
}
],
"meta": {
"totalRecords": 2,
"totalPages": 2,
"currentPage": 1,
"hasPrevious": false,
"hasNext": true
}
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 取得遊戲金鑰
> **取得遊戲金鑰**
GET
```
/game-providers/:providerId/games/:gameCode/key
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商 id |
| gameCode | 字串 | O | 遊戲代號 |
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶名 |
| fullname | 字串 | X | 使用者於遊戲中顯示名稱(未設定以 username 顯示) |
- 請求-範例:
`http://sample.domain.com/game-providers/1/games/gmcde/key?username=myuser123`
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| key | 字串 | 產生的金鑰 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"key": "67a17dd934c01fffcf119...beca27acdcc233168efb1cbb3c6a74dc846"
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| Missing Parameter | 參數不可為空 | 403 |
| User not found | 會員不存在 | 401 |
| Game not found | 錯誤的遊戲代號 | 401 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 玩遊戲
> **遊戲進入點**
GET
```
/game-providers/:providerId/play
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商 id |
### 參數(Query String)
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| key | 字串 | 遊戲金鑰 |
| type | 字串 | 產生鏈接類型預設desktop允許值: "desktop", "mobile" |
| locale | 字串 | 語系預設operator經營方語系允許值: "zh-cn", "zh-tw", "en", "vn", "th"(簡,繁,英,越南文,泰文) |
- 請求-範例:
`http://sample.domain.com/game-providers/1/play?key=67a17dd934c01...4dc846`
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| url | 字串[] | 遊戲鏈接 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"url": "http://testproviderdomain.com/game/playgame?parameter=RTYUFGHJ"
}
}
```
### 錯誤
| 名稱 | 描述 |
| --- | --- |
| In maintenance | 系統維護中 | 400 |
| Forbidden | 遊戲商錯誤 |
| InternalServerError | 內部服務器錯誤 |
---
## 取得遊戲大廳
> **取得遊戲大廳的連結**
GET
```
/game-providers/:providerId/lobby
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商 id |
### 參數(Query String)
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| username | 字串 | 用戶名 |
| headless | 0 or 1 | 是否隱藏表頭, 預設否:0 |
| dark | 0 or 1 | 是否暗色風格, 預設否:0 |
- 請求-範例:
`http://sample.domain.com/game-providers/1/lobby?username=myuser123&headless=1&dark=1`
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| url | 字串[] | 遊戲大廳鏈接 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"url": "http://testproviderdomain.com/egames/lobby/game/?t=..."
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 遊戲地址query string字段說明
> **遊戲地址query string字段說明**
```
http://sample.domain.com/egames/800a4250f7a03739160a549ee65de3a5/?
t=4bea87bc4c644c82b1eee7e49ea90532&gn=vampire-hunter&l=zh-cn&ct=slot&
gt=slot3&socket_url=socket.game.bx&ts=1581908023924&view_mode=portrait& goback_url=https%3A%2F%2Fmy-goback.url%2Fpath%2Fto%2Fback
```
| Query String | Required | Description | Value |
|--------------|----------|-------------|-------|
| client_type | 必填 | 用戶端裝置類型,API 取得遊戲地址後會包含此字段,如返回值與實際用戶端不一致,請用戶端 app 修正為正確的值 | ios: ios app<br>android: android app<br>web: 桌上型電腦瀏覽器<br>wap: 手機瀏覽器<br>unknown: 未知 |
| goback_url | 選填 | wap/web 返回鏈結 | {Url string} 提供 web/wap 遊戲端點擊離開按鈕時鏈結之 url,未提供 url 遊戲將直接關閉視窗。`goback_url=disable` 時,則使⽤⽆效。 |
| uniwebview | 選填 | 是否使用 unity uniwebview 套件 | 1 如用戶端 app 使用 unity uniwebview 需接收需設置此字段,提供遊戲端正確調用開關 |
| view_mode | 必填 | 橫屏 / 豎屏 | landscape: 橫屏<br>portrait: 豎屏 |
## Web(電腦瀏覽器) 及 Wap(手機瀏覽器) 離開遊戲
> **當遊戲地址 query string 上的 client_type=wap 或 client_type=web 時,且用戶端在遊戲地址後的 query string 加上 goback_url={YOUR GO BACK URL},用戶點擊離開按鈕後遊戲會直接轉跳至 goback_url。**
>
> **若未提供 goback_url ,遊戲將直接關閉視窗。**
>
> **若 goback_url=disable 時,則關閉遊戲內"離開"按鈕功能,使返回無效。**
```
http://play-game.bx/egames/800a4250f7a03739160a549ee65de3a5/?
t=4bea87bc4c644c82b1eee7e49ea90532&gn=vampire-hunter&l=zh-cn&ct=slot&qt=slot3&socketunl=socket.game.bx&ts=1581908023924&view_mode=portrait&goback_url=https%3A%2F%2Fmygoback.url%2Fpath&2Fto%2Fback
```
## Web 及 Wap 中使用 iframe 接入 離開遊戲
> **當遊戲地址 query string 上的 client_type=wap 或 client_type=web 時,且用戶端使用 iframe接入遊戲時,在遊戲地址後的 query string 加上goback_url=javascript:window.parent.location.href="指定轉跳的地址"**
## Android 原生 APP 離開遊戲
> **當遊戲地址 query string 上的 client_type=android 及未設定 uniwebview 時會調用此方法**
>
> **使用第三方框架 WVJBWebView**
> **build.gradle/dependencie**
> 
> **註冊監聽 TwGameBack, 即可收到 TwGameBack callback**
> 
## iOS 原生APP 離開遊戲
> **當遊戲地址 query string 上的 client_type=ios 及未設定 uniwebview 時會調用此方法。**
> **實現 WKScriptMessageHandler, 可於 userContentController 接收到 message。**
> 
> **使用 configuration.userContentController 註冊監聽"TwGameBack"**
> 
## Unity - UniWebview 離開遊戲
> **當用戶端使用 Unity3D 開發並使用 UniWebview 套件,且遊戲地址query string 上包含 uniwebview=1 時會調用此方法。**
> 
## 強制踢線玩家
> 踢除正在遊戲中的指定玩家或所有玩家
DELETE
```
/play/:username
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶遊戲帳號(使用 all 為踢除全部線上玩家) |
- 請求-範例:
```
http://sample.domain.com/play/myusername
http://sample.domain.com/play/all
```
### Success 200
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success"
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| Forbidden | 遊戲商錯誤 | 403 |
| User not exists | 用戶不存在 | 404 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
# 獲取數據
## 取得大獎彩金
> **取得大獎彩金之點數**
GET
```
/jackpot
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
- 請求-範例:
```
http://sample.domain.com/jackpot
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| jp-mini | 數字(float) | 小獎彩金 |
| jp-minor | 數字(float) | 次獎彩金 |
| jp-major | 數字(float) | 大獎彩金 |
| jp-grand | 數字(float) | 巨獎彩金 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"jp-minor": 33942.5,
"jp-mini": 565856.67,
"jp-major": 547010.59,
"jp-grand": 993936.18
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| forbidden | 系統異常 | 400 |
---
## ~~取得指定分鐘範圍統計資料~~ (已廢除)
1. 可查詢的範圍為目前時間14分鐘前,最多可查詢到72小時內,例:目前時間為 2024-12-01 12:14,可查詢範圍為 2024-11-28 12:00 至 2024-12-01 11:59
GET
```
/statistics?start=2024-11-28%2012:00&end=2024-12-01%2011:59
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| start | 字串(string) | O | 開始時間(yyyy-MM-dd HH:mm) |
| end | 字串(string) | O | 結束時間(yyyy-MM-dd HH:mm) |
| game | 整數(integer) | X | 遊戲 gameId (從遊戲列表取得) |
- 請求-範例:
```
http://sample.domain.com/statistics?start=2024-11-28%2012:00&end=2024-12-01%2011:59
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| totalBet | 數字(float) | 總投注點數(小數後兩位) |
| totalWin | 數字(float) | 總贏分主數(小數後兩位) |
| totalBetCount | 數字(integer) | 總投注次數 |
| totalWinCount | 數字(integer) | 總贏分次數 |
| startTime | 字串(string) | 開始時間 |
| endTime | 字串(string) | 結束時間 |
| featureBet | 數字(float) | 總購買特色遊戲點數 |
| featureWin | 數字(float) | 總購買特色遊戲贏分 |
| featureCount | 數字(integer) | 總購買特色遊戲次數 |
| currency | 字串(string) | 使用幣別(P130: 130比1, P100: 100比1... 以此類推) |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"totalBet": 123456.78,
"totalWin": 123456.78,
"totalBetCount": 12345,
"totalWinCount": 1234,
"startTime": '2024-11-01 13:00',
"endTime": '2024-11-01 13:10',
"currency": 'TWD'
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| forbidden | 系統異常 | 400 |
| user not found | 查無用戶 | 400 |
| game not found | 查無遊戲 | 400 |
| time range too large | 時間範圍過長 | 400 |
| invalid time range | 參數的時間範圍 | 400 |
---
## 取得指定日期統計資料
> **取得指定日期統計資料**
GET
```
/statistics/:date?time=00
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| time | 數字(Integer) | X | 指定取得的第幾個小時 (例: 設定為 00 可查詢當日的 00:00 - 00:59 的資料) |
| game | 數字(Integer) | X | 遊戲 gameId (從遊戲列表取得) |
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| date | 字串 | O | 指定日期(YYYY-MM-DD) |
- 請求-範例:
```
http://sample.domain.com/statistics/2024-05-01
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| totalBet | 數字(float) | 總投注點數 |
| totalWin | 數字(float) | 總贏分主數 |
| totalBetCount | 數字(integer) | 總投注次數 |
| totalWinCount | 數字(integer) | 總贏分次數 |
| featureBet | 數字(float) | 總購買特色遊戲點數 |
| featureWin | 數字(float) | 總購買特色遊戲贏分 |
| featureCount | 數字(integer) | 總購買特色遊戲次數 |
| profit | 數字(float) | 淨利潤點數 |
| totalPlayerCount | 數字(integer) | 不重複玩家數 |
| newPlayerCount | 數字(integer) | 新註冊玩家數(不分遊戲) |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"jp-minor": 33942.5,
"jp-mini": 565856.67,
"jp-major": 547010.59,
"jp-grand": 993936.18
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| forbidden | 系統異常 | 400 |
---
## 取得未出餘額用戶名單
> **取得未出餘額用戶名單**
GET
```
/game-providers/:providerId/balance-users
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| providerId | 整數 | O | 遊戲供應商id |
- 請求-範例:
```
http://sample.domain.com/game-providers/:providerId/balance-users
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| username | 字串 | 用戶帳號 |
| amount | 數字(float) | 餘額小數點後2位 |
| status | 字串 | Enabled: 啟用中, Blocked: 鎖定中 |
| updatedAt | 數字(integer) | 最後更新時間 utc timestamp(ms) |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"users": [
{
"username": "superman",
"amount": 12345.67,
"updatedAt": 1724059573433
},
{
"username": "superwoman",
"amount": 12345.67,
"updatedAt": 1724059573433
},
...
]
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| forbidden | 系統異常 | 400 |
---
## 下注記錄
> **利用API取得注單(限3秒內僅能執行一次,查詢區間限制為五分鐘)**
POST
```
/transaction
```
### 注單查詢參數
| 參數 | 類型 | 必要 | 描述 |
| ----------------- | ---------- | ---- | ----------------------------------------------------------------------------------- |
| Operator | 字串 | O | X-Operator 經營方代碼 |
| Key | 字串 | O | X-Key 經營方API金鑰 |
| SDate | 時間與日期 | O | 格式 : YYYY-MM-DD HH:mm:ss, 時區為: 經營賬號時區(預設GTM+8) 查詢起始時間(大於等於) |
| EDate | 時間與日期 | O | 格式 : YYYY-MM-DD HH:mm:ss, 時區為: 經營賬號時區(預設GTM+8) 查詢結束時間(小於等於,時間範圍最長5分鐘) |
| Type | 字串 | X | 注單時間過濾方式 settledate(預設), bettingdate |
| Provider | 字串 | X | 遊戲供應商 |
| PlayerID | 字串 | X | 玩家賬號 |
| TransactionNumber | 字串 | X | 注單編號 |
| BetDataGameCode | 字串 | X | 指定 gameCode 返回詳情(僅限特定遊戲),同時指定多個遊戲以","分隔,例: mahjong,bubble-gum |
- 成功-回應
```json
HTTP/1.1 200 OK
[
{
"gameprovider": "p1", // 遊戲供應名稱 {String}
"membername": "user1", // 用戶名稱 {String}
"gamename": "game1", // 遊戲名稱 {String}
"bettingid": "667e6037fff4", // 注單ID {String}
"bettingcode": 1124, // 注單編號 {Integer}
"bettingdate": "1695474361", // 投注時間 {String}
"gameid": 11111, // 遊戲ID {Integer}
"gamecode": "bubble-gum", // 遊戲代碼 {String}
"roundno": "null", // 遊戲回合(部分遊戲提供) {String}
"result": "null", // 注單結果(部分遊戲提供) {String}
"bet": "null", // 投注內容(部分遊戲提供) {String}
"winloseresult": "W", // 勝負狀態(W: 勝, L: 負) {String}
"totalstake": "1.000", // 下注點數 {String}
"bettingamount": 1.000, // 打碼點數 {Float}
"validbet": "1.000", // 有效注單點數
"winloseamount": 1.000, // 勝負點數 {Float}
"balance": "null", // 投注後餘額(部分遊戲提供) {String}
"currency": "MYR", // 貨幣 {String}
"isfree": "0", // 是否為免費遊戲 0: 否, 1: 是 {String}
"isfeature": "0", // 是否為購買特色遊戲 0: 否, 1: 是 {String}
"handicap": "null", // 讓分(部分遊戲提供) {String}
"status": "close", // 狀態(close: 已結算, open: 未結算, refund: 退款, cancel: 撤單) {String}
"gamecategory": "slot", // 遊戲類別(lottery: 彩票, slot: 老虎幾, poker: 棋牌, arcade: 街機小遊戲) {String}
"settledate": "1695474361", // 結算時間(Unix timestamp second) {String}
"remark": "null", // 備註 {String}
"betdata": "json string", // 注單詳情(特定遊戲,以 jsonstring 返回) {String}, 預設值為 "null"
"replayurl": "string" // 該注單的重播連結(部份遊戲提供) {String}
}
]
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| (Operator name) must be provided | 必要入operator | 403 |
| (Operator Key) must be provided | 必要入Key | 403 |
| (Start Date) must be provided | 時間格式錯誤 | 403 |
| (End Date) must be provided | 時間格式錯誤 | 403 |
| SDate cannot be greater than EDate | SDate 大於 EDate 時間條件錯誤 | 403 |
| Transaction is no allowed for over then 5 minuntes | 抄單時間範圍不得超過5分鐘 | 403 |
| Request time limit. Try again latter. | 抄單頻率過快,預設兩次間隔不得少於3秒 | 405 |
---
## 轉賬記錄
> **利用API取得額度轉換(限3秒內僅能執行一次)**
POST > FORM-DATA
```
/transfer
```
### 查詢參數
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| Operator | 字串 | O | X-Operator 經營方代碼 |
| Key | 字串 | O | X-Key 經營方API金鑰 |
| SDate | 時間與日期 | O | 格式 : YYYY-MM-DD HH:MM:SS, 時區為 : 經營賬號時區(預設GTM+8) "查詢區間限制為十分鐘" |
| EDate | 時間與日期 | O | 格式 : YYYY-MM-DD HH:MM:SS, 時區為 : 經營賬號時區(預設GTM+8) "查詢區間限制為十分鐘" |
| Provider | 字串 | X | 遊戲供應商 |
| PlayerID | 字串 | X | 玩家賬號 |
| TransferCode | 字串 | X | 交易紀錄編號(客戶提供的備註或系統生成皆可) |
| Exact | 布林 | X | 預設TrueTrue - PlayerID 精確查詢False - PlayerID 模糊查詢允許值: "True", "False" |
- 成功-回應
```json
HTTP/1.1 200 OK
[
{
"provider": "p1",
"id": "10",
"username": "user1",
"amount": "112",
"currency": "MYR",
"actions": "IN",
"balance": "50",
"transfercode": "mytransfercode",
"createtime": "1695474361"
}
]
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| (Operator name) must be provided | 必要入operator | 403 |
| (Operator Key) must be provided | 必要入Key | 403 |
| (Start Date) must be provided | 時間格式錯誤 | 403 |
| (End Date) must be provided | 時間格式錯誤 | 403 |
---
## 單筆轉賬記錄
> **以 transferId 取得單筆交易記錄**
GET
```
/Transfer/:transferId
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 域名(Parameters)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| transferId | 字串 | O | 交易id |
- 請求-範例:
```
http://sample.domain.com/Transfer/223120810qPPlSr
```
- 成功-回應
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"provider": "p1",
"id": "10",
"username": "user1",
"amount": "112",
"currency": "TWD",
"actions": "IN",
"balance": "50",
"transfercode": "223120810qPPlSr",
"createtime": "2022-11-08T08:10:36.233Z"
}
}
```
### 錯誤
```json
HTTP/1.1 404 Not Found
{
"status": 404,
"message": "Record not found."
}
```
| 名稱 | 描述 | HTTP Status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| Transfer in progress | 交易處理中 | 403 |
| Internal Server Error | 內部服務器錯誤 | 500 |
| Record not found. | 查無相關記錄 | 404 |
---
## 取得注單下載連結
> **提供注單檔案連結,匯出 CSV 檔並壓縮成 ZIP(12分鐘後的注單,存活時間最長二小時)**
> **商戶需提出申請,才能使用此功能**
GET
```
/transaction/link
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": 200,
"message": "success",
"data": {
"list": [
{
"startTime": 1762999140000,
"endTime": 1762999199999,
"betCount": 2,
"link": "https://abc.com/1762999140000.zip"
}
]
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
## 登記注單匯出任務
> **提供登記注單下載任務,匯出完成後,在 取得注單下載連結 可取得連結**
> **商戶需提出申請,才能使用此功能**
POST
```
/transaction/link/register
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 注單查詢參數
| 參數 | 類型 | 必要 | 描述 |
| ----------------- | ---------- | ---- | ----------------------------------------------------------------------------------- |
| startTime | Timestamp(13碼) | O | 預設GTM+8 |
| endTime | Timestamp(13碼) | O | 預設GTM+8 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": 200,
"message": "success"
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
| Start time is require | 開始時間為必填 | 400 |
| End time is require | 結束時間為必填 | 400 |
| End time must be greater than start time | 結束時間必需大於開始時間 | 400 |
| Time range must not be greater than 2 hours | 時間範圍最長二小時 | 400 |
---
# 其他
## 取得所有玩家
> **取得玩家列表**
GET
```
/players
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| X-Token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"X-Token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| rows | 整數 | X | 回傳記錄筆數預設10 |
| page | 整數 | X | 頁數預設1 |
| sidx | 字串 | X | 排序的欄位名稱預設id |
| sord | 字串 | X | 排序樣式預設asc允許值: "asc", "desc" |
- 請求-範例:
```
http://sample.domain.com/players
http://sample.domain.com/players?page=2
http://sample.domain.com/players?page=1&rows=10
http://sample.domain.com/players?page=1&rows=10&sidx=name&sord=desc
```
### Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| players | 字串[] | 玩家列表 |
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"players": [
{
"id": 1,
"username": "DUMMYACCT2X",
"fullname": "DUMMY ACCT 2ND",
"email": "DUMMY.ACCT2@TEST.COM",
"country": "PHILIPPINES",
"currency": "CNY",
"birthdate": "1992-02-18T00:00:00.000Z",
"operatorId": 2,
"createdAt": "2017-06-01T21:07:05.000Z",
"updatedAt": "2017-06-01T21:07:05.000Z"
},
{
"id": 2,
"username": "DUMMYACCT3X",
"fullname": "DUMMY ACCT 3RD",
"email": "DUMMY.ACCT3@TEST.COM",
"country": "JAPAN",
"currency": "CNY",
"birthdate": "1990-05-18T00:00:00.000Z",
"operatorId": 2,
"createdAt": "2017-06-01T21:07:05.000Z",
"updatedAt": "2017-06-01T21:07:05.000Z"
}
],
"meta": {
"totalRecords": 5,
"totalPages": 2,
"currentPage": 2,
"hasPrevious": true,
"hasNext": false
}
}
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| invalid token | 無效Token | 401 |
| Forbidden | 遊戲商錯誤 | 403 |
| InternalServerError | 內部服務器錯誤 | 500 |
---
# 單一錢包 (建議使用V2版本)
此版本即將棄用,建議使用V2版本可提升執行效率
## 說明
1. 由貴方提供「單一錢包交易API」, 讓我方串接進行餘額異動。
2. 當貴方收到我方發出 API 請求時,需將 headers 中的 token 及 body 中的 data,先發送驗証請求到我方的「[驗証錢包參數](#wallet-token)」API,確認 token 及資料完整性,token 為一次性,驗証完即失效。
3. body 中的 data,解密方式為 AES 128 CBC,key 及 iv 長度皆為 16 碼,不足16位,後面補0,超過16位就取前16位。
4. 當我方呼叫貴方的 API, 如果網路出現異常(例如:Timeout),我方會重試三次,每次間隔 50 ms,此 n 次請求的 token 皆相同,可用於判斷是否重覆請求。
### 營運商需提供以下資訊
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| url | 字串 | API base url |
### AES 解密資訊
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| iv | 字串(16 碼) | O | 經營方代碼(X-Operator) |
| key | 字串(16 碼) | O | 經營方API密鑰(X-Key) |
- JavaScript 範例:
```JavaScript
const decrypt = (key, iv, str) => {
const key2 = key.slice(0, 16)
const iv2 = iv.padEnd(16, '0')
const crypted = Buffer.from(str, 'base64').toString('binary')
const decipher = crypto.createDecipheriv('aes-128-cbc', key2, iv2)
let decoded = decipher.update(crypted, 'binary', 'utf8')
decoded += decipher.final('utf8')
return decoded
}
```
- PHP 範例:
```php
function decrypt($key, $iv, $str) {
// 將 key 截取為前 16 個字符
$key2 = substr($key, 0, 16);
// 將 iv 補充為 16 個字符
$iv2 = str_pad($iv, 16, '0');
// 將 base64 字符串轉換為二進制數據
$crypted = base64_decode($str);
// 使用 openssl_decrypt 進行解密
$decoded = openssl_decrypt($crypted, 'AES-128-CBC', $key2, OPENSSL_RAW_DATA, $iv2);
// 返回解密後的字符串
return $decoded;
}
// 測試
$key = "your_key_here";
$iv = "your_iv_here";
$str = "your_encrypted_string_here";
echo decrypt($key, $iv, $str);
```
---
## 取得餘額
> **取得用戶在營運商的餘額**
GET
```
{單一錢包交易API網址}/balance
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 交易驗証憑證 |
- 標頭-範例:
```json
{
"token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| username | 字串 | O | 用戶名 |
- 請求-範例:
`https://sample.domain.com/balance?username=myuser123`
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balance | 浮點數 | 即時餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 下注扣款
> **用戶在營運商的下注扣款**
POST
```
{單一錢包交易API網址}/betting
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 下注點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 扣款前餘額 |
| balance | 浮點數 | 扣款後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 500,
"balance": 400
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 結算派獎
> **用戶在營運商的結算派獎**
> **如玩家斷線,系統有自動關單機制,請勿限制玩家離線時不可結算派獎**
POST
```
{單一錢包交易API網址}/settlement
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 贏分點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 派獎前餘額 |
| balance | 浮點數 | 派獎後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 400,
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 退款
> **用戶在營運商的退款,此為彩票類遊戲使用,如開獎異常或和局時,遊戲自行判斷退款**
> **例如:賽馬的百家樂下莊閒,開和局時,會觸發退款**
POST
```
{單一錢包交易API網址}/refund
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
- 標頭-範例:
```json
{
"token": "aqA12Wsqa341...ASDasd123asd"
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 退款點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 退款前餘額 |
| balance | 浮點數 | 退款後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 400,
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 驗証錢包參數
<a id="wallet-token"></a>
> 驗証營運商單一錢包所回傳的 token 及 data
POST
```
/wallet/authorize
```
### 參數(Query String)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | wallet token |
| data | 字串 | X | 單一錢包所傳送的資料(如 GET 不需傳 data) |
- 請求-範例:
```json
{
"token": "664ee129a697acf53d3b6e14",
"data": "aofYPahYUsANEuXfhwBjeWTUgYtIFRlw0PErKZexkVw="
}
```
### Success 200
- 回應-成功:
```json
HTTP/1.1 200 OK
{
"status": "success"
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"message": "錯誤訊息"
}
```
### 錯誤
| 名稱 | 描述 | HTTP status |
| --- | --- | --- |
| In maintenance | 系統維護中 | 400 |
| Internal Server Error | 伺服器發生問題 | 500 |
| Forbidden | 驗証錢包 token 錯誤或過期 | 403 |
---
# 單一錢包 V2
## 說明
1. 由貴方提供「單一錢包交易API」, 讓我方串接進行餘額異動。
2. 當貴方收到我方發出 API 請求時,需執行 token 的驗証,以確保資料無誤。
2.1 取出 headers 中的 timestamp,以及 body 中的 data 跟 iv 字串相接後做 md5 編碼,與 token 是否相符,範例:token === md5(iv + timestamp + data)。
2.2 timestamp 為有效期限,判斷 timestamp 未過期時,再處理此封包,範例:now() < timestamp。
3. body 中的 data,解密方式為 AES 128 CBC,key 及 iv 長度皆為 16 碼,不足16位,後面補0,超過16位就取前16位。
4. 當我方呼叫貴方的 API, 如果網路出現異常(HTTP Status code:5xx),我方會重試三次,每次間隔 50 ms,此 n 次請求的 token 皆相同,可用於判斷是否重覆請求。
5. 我方呼叫 API 的 Timeout 設定值為 10 秒,如果呼叫逾時,不會觸發重試機制。
### 營運商需提供以下資訊
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| url | 字串 | API base url |
### AES 解密資訊
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| iv | 字串(16 碼) | O | 經營方代碼(X-Operator) |
| key | 字串(16 碼) | O | 經營方API密鑰(X-Key) |
- JavaScript 範例:
```JavaScript
const decrypt = (key, iv, str) => {
const key2 = key.length > 16 ? key.slice(0, 16) : key.padEnd(16, '0')
const iv2 = iv.length > 16 ? iv.slice(0, 16) : iv.padEnd(16, '0')
const crypted = Buffer.from(str, 'base64').toString('binary')
const decipher = crypto.createDecipheriv('aes-128-cbc', key2, iv2)
let decoded = decipher.update(crypted, 'binary', 'utf8')
decoded += decipher.final('utf8')
return decoded
}
```
- PHP 範例:
```php
function decrypt($key, $iv, $str) {
$key2 = strlen($key) > 16 ? substr($key, 0, 16) : str_pad($key, 16, '0');
$iv2 = strlen($iv) > 16 ? str_pad($iv, 16, '0') : str_pad($iv, 16, '0');
// 將 base64 字符串轉換為二進制數據
$crypted = base64_decode($str);
// 使用 openssl_decrypt 進行解密
$decoded = openssl_decrypt($crypted, 'AES-128-CBC', $key2, OPENSSL_RAW_DATA, $iv2);
return $decoded;
}
```
---
## 解密範例
加密所需參數
| 參數 | 值 |
| --- | --- |
| iv | iv1 |
| key | key1 |
| timestamp | 1733797877 |
加密後參數
| 參數 | 值 |
| --- | --- |
| token | f0a7a81001350206304b370684de63b2 |
| data | Ce6M+q7tjSab7lrIvzgYd9EEM8YzvoS4IhaSxLHieebcrD15YJWfKNC2EzoJ1Yjm3AvoWtYZUMnQKqEJHyL5u9oLSHC9lILuQUj67/XO0/U= |
解密後參數
| 參數 | 值 |
| --- | --- |
| uuid | b99ad91c19004e28a37c1771c625b3c5 |
| username | username1 |
- curl 範例:
```curl
curl -X POST http://localhost/balance
-H 'Content-Type: application/json'
-H 'token: f0a7a81001350206304b370684de63b2'
-H 'timestamp: 1733797877'
-d '{"data":"Ce6M+q7tjSab7lrIvzgYd9EEM8YzvoS4IhaSxLHieebcrD15YJWfKNC2EzoJ1Yjm3AvoWtYZUMnQKqEJHyL5u9oLSHC9lILuQUj67/XO0/U="}'
```
- JavaScript 解密範例:
```JavaScript
const decryptData = async (token, timestamp, data) => {
const md5 = crypto.md5(`${iv}${timestamp}${data}`)
if (token !== md5) {
console.log('check token error')
}
const now = moment().unix()
if (now > parseInt(timestamp)) {
console.log('timestamp expried')
}
const decryptedStr = aes.decrypt(key, iv, data)
const decrypted = JSON.parse(decryptedStr)
return decrypted
}
```
---
## 取得餘額
> **取得用戶在營運商的餘額**
POST
```
{單一錢包交易API網址}/balance
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 交易驗証憑證 |
| timestamp | 整數(10碼) | O | 有效期限 |
- 標頭-範例:
```json
{
"token": "667e60419dc6d6428a99ee0e",
"timestamp": 1704070800
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| username | 字串 | O | 用戶名 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"username": "myuser123"
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balance | 浮點數 | 即時餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 下注扣款
> **用戶在營運商的下注扣款**
POST
```
{單一錢包交易API網址}/betting
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
| timestamp | 整數(10碼) | O | 有效期限 |
- 標頭-範例:
```json
{
"token": "667e60419dc6d6428a99ee0e",
"timestamp": 1704070800
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 下注點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 扣款前餘額 |
| balance | 浮點數 | 扣款後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 500,
"balance": 400
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 結算派獎
> **用戶在營運商的結算派獎**
> **如玩家斷線,系統有自動關單機制,請勿限制玩家離線時不可結算派獎**
POST
```
{單一錢包交易API網址}/settlement
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
| timestamp | 整數(10碼) | O | 有效期限 |
- 標頭-範例:
```json
{
"token": "667e60419dc6d6428a99ee0e",
"timestamp": 1704070800
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 贏分點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 派獎前餘額 |
| balance | 浮點數 | 派獎後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 400,
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```
---
## 退款
> **用戶在營運商的退款,此為彩票類遊戲使用,如開獎異常或和局時,遊戲自行判斷退款**
> **例如:賽馬的百家樂下莊閒,開和局時,會觸發退款**
POST
```
{單一錢包交易API網址}/refund
```
### 標頭(Header)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| token | 字串 | O | 產生存取憑證 |
| timestamp | 整數(10碼) | O | 有效期限 |
- 標頭-範例:
```json
{
"token": "667e60419dc6d6428a99ee0e",
"timestamp": 1704070800
}
```
### 解壓後資料(data)
| 參數 | 類型 | 必要 | 描述 |
| --- | --- | --- | --- |
| uuid | 字串 | O | 識別碼 |
| betId | 字串 | O | 注單ID |
| gameCode | 字串 | O | 遊戲代碼 |
| username | 字串 | O | 用戶名 |
| amount | 浮點數 | O | 退款點數 |
- 請求-範例:
```json
{
"uuid": "664ee129a697acf53d3b6e14",
"betId": "6661868717e794f36effc59a",
"gameCode": "climb-stairs",
"username": "myuser123",
"amount": 100
}
```
### 成功 Success 200
| 參數 | 類型 | 描述 |
| --- | --- | --- |
| balanceOld | 浮點數 | 退款前餘額 |
| balance | 浮點數 | 退款後餘額 |
- 回應-成功
```json
HTTP/1.1 200 OK
{
"status": "success",
"data": {
"balanceOld": 400,
"balance": 500
}
}
```
- 回應-失敗
```json
HTTP/1.1 200 OK
{
"status": "fail",
"data": {
"message": "錯誤訊息"
}
}
```