Appearance
CHANGELOG
日期 | 版本 | Changelog |
---|---|---|
2024-04-27 | 1.0.0 | 初版 |
2024-06-17 | 1.0.1 | 1. /open/seamless/launch 接口新增 ret_lobby_btn 参数2. /balance/get 接口新增 game_id 参数 |
2024-06-26 | 1.0.2 | 1. /open/seamless/create 接口移除 brd 参数 |
2024-07-02 | 1.0.3 | 1. /order/transfer 接口新增 room_kind 参数 |
2024-07-15 | 1.1.0 | 1. /order/transfer 中 action 新增 3 (代表下注撤销)2. 游戏链接支持第三方脚本参数配置 3. 新增 /open/seamless/evict 接口 |
全局接口说明
金额参数
OP 和 2J服务器之间接口交互中涉及到的金额参数都以厘为单位,数据类型为int64。
1元 = 1000厘
1分 = 10厘
接口签名
OP 和 2J 服务器之间每个请求 querystring 中都必须携带参数,参照如下案例:
/seamless/launch?mch=108&ts=1710230433000&sign=f764e34bb223966caf66d88e8e1c817f
Query 参数说明:
- mch 是 2J分配给接入OP的标识id(通常为三位id)
- ts 时间戳, milisecond
- sign, sign的生成规则为MD5(httpjsonbody+ts+key), OP 接入前需要向 2J 申请一个 key
计算sign的示例代码如下:
Python
python
import hashlib
def compute_md5(jsonbody, ts_str, key):
m = hashlib.md5()
m.update(jsonbody.encode('utf-8'))
m.update(ts_str.encode('utf-8'))
m.update(key.encode('utf-8'))
return m.hexdigest()
# 假如调用url最终为: /open/seamless/create?mch=xxx&ts=1718675696497&sign=your_sign
jsonbody = '''{"brd": "wl", "op_id": "60095050427", "user_info": {"cnt": "ph", "gender": 0, "lan": "en", "nickname": "60095050427"}}'''
ts_str = "1718675696497"
key = "example_key"
your_sign = compute_md5(jsonbody, ts_str, key)
# cbc16eea6ad1af1f63955d24b314e13a
print(your_sign)
Go
go
import "crypto/md5"
func ComputeMd5(dataStr []byte, key []byte) string {
h := md5.New()
h.Write(dataStr)
if len(key) > 0 {
h.Write(key)
}
return fmt.Sprintf("%x", h.Sum(nil))
}
body := `{"brd": "wl", "op_id": "60095050427", "user_info": {"cnt": "ph", "gender": 0, "lan": "en", "nickname": "60095050427"}}`
ts := "1718675696497"
key := "example_key"
part1 := []byte(body + ts)
part2 := []byte(key)
// cbc16eea6ad1af1f63955d24b314e13a
your_sign := ComputeMd5(part1, part2)
响应结构体
json
content-type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常, 非0表示异常
"msg": "", // 错误提示
"timestamp": 1709716095516
},
"data": xxx
}
2J 提供接口
POST /open/seamless/create 用户注册
用于在 2J 服务器上注册用户信息。
json
content-type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"user_info": {
"nickname": "player01", // op 玩家昵称。注意:不支持 emoji 特殊字符
"gender": 0, // 0-unknow, 1-famale, 2-male
"cnt": "ph", // 默认国家
"lan": "en" // 默认语言
}
}
Response:
json
content-type: application/json
{
"header": {
"code": 0,
"trace_id": "9cd0bfd22447bf607d20a3c2ac4e304a",
"msg": "",
"timestamp": 1710310573038
}// 通用响应header
}
POST /open/seamless/launch 登录游戏
获取游戏链接接口。
json
content-type: application/json
{
"op_id": "xxx-xxx-aaa", // 必填。op侧用户的唯一标识
"balance": 666, // 必填。op用户余额
"game_id": 65005, // 必填。游戏id
"lang": "en-US",
"backlink": "http://xxxxx.com?a=ss", // 返回 OP 地址
"cur": "$", // 可选。货币符号
"device_type": 2, // 可选。玩家客户端类型 1: h5, 2: android, 3: ios
"device_id": "AD19939", // 可选。玩家客户端设备唯一id
"ret_lobby_btn": false, // 可选。是否显示返回大厅按钮
}
参数说明:
- game_id 详细清单可参考这里
- lang 参考:https://zh.wikipedia.org/wiki/ISO_639-1
Response:
json
content-type: application/json
{
"header": {
"code": 0,
"trace_id": "9cd0bfd22447bf607d20a3c2ac4e304a",
"msg": "",
"timestamp": 1710310573038
},
"url": "http://abc.zzz?brd=default&chn=&lang=en-US&launch=blackjack&mch=108&opid=demo10087&token=6defed39fd6a4e98add31a4e1ead5172&version=1"
}
POST /open/seamless/evict 踢出用户
提供给 OP 用于踢出用户, 如果玩家在游戏中,会被强制退出游戏。
json
content-type: application/json
{
"op_id": "xxx-xxx-aaa", // 必填。op侧用户的唯一标识
}
Response:
json
content-type: application/json
{
"header": {
"code": 0,
"trace_id": "9cd0bfd22447bf607d20a3c2ac4e304a",
"msg": "",
"timestamp": 1710310573038
},
"game_info": {
"game_id": 1006, // 游戏id
"join_at": 1720686368, // 加入时间
"leave_at": 1720686368, // 离开时间
}
}
OP 需要提供的接口
POST /balance/get 查询用户余额接口
json
content-type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"game_id": 1006, // 游戏ID,表示是从哪个游戏中请求过来的,可选
}
Response:
json
content-type: application/json
{
"header": {
"code": 103, // 错误编码,0表示正常, 非0表示异常
"msg": "user not exist",
"timestamp":1709716095516,
},
"result":
{
"op_id": "111444", // op侧用户的唯一标识
"availableAmount": 998, // op用户当前可用余额
},
}
POST /order/transfer 用户下注/结算
用于OP用户下注和派彩,至少一次的调用,OP需要保持该接口的 幂等。
下注撤销发生在用户下注时,2J 调用 OP 的接口失败 (超时,异常错误) 时,2J 会调用此接口并指定 action=3 表示撤销下注。
注意⚠️:投注撤销
的请求参数中,amount
为正数,值等于之前的下注金额(负数)的绝对值;action
为 3
。 其余参数和下注请求一致(包括 trans_no
和 draw_id
)。
json
content-type: application/json
{
"action":1, // 1:下注,2:派彩, 3:下注撤销
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"order":
{
"trans_no":"101156966-1170920125564673-1006-2-1726-1709201163-0",//本次变更唯一凭证
"draw_id":"1006-2-1726-1709201163-0", // 牌局唯一标识
"game_id": 1006, // 游戏ID
"amount": -5000, // 金额变动
"room_kind": 1, //房间场次
"extra_business": // 可选。不同游戏额外的业务数据
{
"win_crash_bet": 1000, // 在fishdom中每轮结算周期内输赢为负的累计金额
"total_bet": 5000, // 退出fishdom时本次下注金额
"total_award": 0, // 退出fishdom时本次总派彩金额
}
}
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
action | int | 请求行为 | 1: 下注 , 2: 奖励, 3: 下注撤销 |
op_id | string | OP 的玩家id | |
order | object | 订单结构体 | |
order.trans_no | string | 订单唯一凭证,可以此做幂等操作 | |
order.draw_id | string | 牌局唯一标识 | |
order.game_id | int | 游戏id | |
order.amount | int64 | 金额 | |
order.extra_business | object | 不同游戏额外的业务数据 | 可选参数 |
fishdom中额外的业务数据说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
extra_business.win_crash_bet | int | 在fishdom中每轮结算周期内输赢为负的累计金额 | |
extra_business.total_bet | int | 退出fishdom时本次下注金额 | |
extra_business.total_award | int | 退出fishdom时本次总派彩金额 | |
Response: |
json
// content-type: application/json
{
"header": {
"code": "0", // 错误编码,0表示正常, 非0表示异常
"msg": "",
"timestamp":1709716095516,
},
"result":
{
"op_id": "111444", // required op侧用户的唯一标识
"availableAmount": 998, // required op用户当前可用余额
},
}
POST /member/profile 用户信息查询
说明:用于即时获取用户信息
json
content-type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
op_id | string | OP 的玩家id |
Response:
json
content-type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常, 非0表示异常
"msg": "",
"timestamp":1709716095516,
},
"result":
{
"nickname": "player01", // op 玩家昵称 required
"gender": 1 , // op 玩家性别 0-unknown, 1-famale, 2-male
}
}