Skip to content

全局接口说明

CHANGELOG

查阅 API 更新日志

错误码定义

查阅 错误码说明

金额参数

OP 和 2J服务器之间接口交互中涉及到的金额参数都以厘为单位,数据类型为int64。

1元 = 1000厘
1分 = 10厘

游戏类型

游戏分为Slots、百人类、对战类、捕鱼类、休闲类,不同类型对应不同游戏ID范围,适用不同的下注和派彩接口,具体如下:

游戏类型游戏ID范围适用下注/结算接口
Slots1000~1999/order/transfer
百人类2000~2999/order/batch_transfer
对战类3000~3999/order/batch_transfer
捕鱼类4000~4999/order/transfer
休闲类6000~6999/order/transfer

接口签名

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, // 可选。是否显示返回大厅按钮
    "full_screen": 1, // 可选。控制在使用浏览器情况下,是否自动进入全屏 1: 不进入全屏 2: 自动进入全屏,该参数未传由2j服务器控制是否自动进入全屏
}

参数说明:

  1. game_id 详细清单可参考这里
  2. lang 参考:https://zh.wikipedia.org/wiki/ISO_639-1
  3. backlink: 控制游戏中退出游戏按钮执行的逻辑
    • 如果传 about:blank 或者为空 触发代码: window.close()
    • 如果传链接 触发代码: window.location.href=backlink
    • 如果是用Iframe的方式打开游戏,可以使用设置backlink参数为脚本的方式使用,例如:javascript:window.parent.postMessage({ type: 'exit_customer_page'}, '*'), 这样会触发父页面的onmessage事件,然后父页面可以根据type参数做相应的处理。

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 用于踢出用户, 如果玩家在游戏中,会被强制退出游戏。

注意:这里玩家被踢出后,会收到一个弹窗通知告知玩家被踢出,但如果 OP 在调用 /open/seamless/launch 时没有提供 backlink 参数,会导致玩家无法返回 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 为正数,值等于之前的下注金额(负数)的绝对值;action3。 其余参数和下注请求一致(包括 trans_nodraw_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, // 在捕鱼类中每轮结算周期内输赢为负的累计金额
           "total_bet": 5000, // 退出捕鱼类时本次下注金额
           "total_award": 0, // 退出捕鱼类时本次总派彩金额
       }
   }
}

参数说明:

参数类型说明备注
actionint请求行为1: 下注 , 2: 奖励, 3: 下注撤销
op_idstringOP 的玩家id
orderobject订单结构体
order.trans_nostring订单唯一凭证,可以此做幂等操作
order.draw_idstring牌局唯一标识
order.game_idint游戏id
order.amountint64金额变动捕鱼类游戏下注时是预扣值,并非玩家实际下注
order.extra_businessobject不同游戏额外的业务数据捕鱼类游戏结算时玩家的实际下注和奖励在该字段体现

捕鱼类游戏中额外的业务数据说明:

参数类型说明备注
extra_business.win_crash_betint在捕鱼类游戏中每轮结算周期内输赢为负的累计金额
extra_business.total_betint退出捕鱼类游戏时本次实际下注金额
extra_business.total_awardint退出捕鱼类游戏时本次实际派彩金额
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 /order/batch_transfer 用户批量下注/结算

该接口适用于百人类和对战类游戏:用于OP多个用户下注和派彩,至少一次的调用,OP需要保持该接口的 幂等

下注撤销发生在用户下注时,2J 调用 OP 的接口失败 (超时,异常错误) 时,2J 会调用此接口并指定 action=3 表示撤销下注。

注意⚠️:投注撤销 的请求参数中,amount 为正数,值等于之前的下注金额(负数)的绝对值;action3。 其余参数和下注请求一致(包括 trans_nodraw_id)。

json
content-type: application/json
{
   "action": 1, // 1:下注,2:派彩,3:下注撤销
   "trans_no": "101156966-1170920125564673-1006-2-1726-1709201163-0",//本次变更唯一凭证
   "draw_id": "1006-2-1726-1709201163-0", // 牌局唯一标识
   "game_id": 1006, // 游戏ID
   "room_kind": 0, // 房间类型
   "orders": [
       {
       "trans_no": "101156966-1170920125564673-1006-2-1726-1709201163-0",
       "op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
       "amount": -5000, // 金额变动
       "extra_business": {"total_bet":6000,"total_award":1000},
       },
       {
       "trans_no": "101156966-1170920125564673-1006-2-1726-1709201163-0",
       "op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
       "amount": -5000, // 金额变动
       "extra_business": {"total_bet":6000,"total_award":1000},
       }
   ]
}

参数说明:

参数类型说明备注
actionint请求行为1: 下注 , 2: 奖励, 3: 下注撤销
trans_nostring本次订单的唯一标识
draw_idstring牌局唯一标识
game_idint游戏ID
room_kindint房间类型
ordersobject订单结构体
order.trans_nostring订单唯一凭证,可以此做幂等操作
order.op_idstringop用户唯一标识
order.amountint64金额变动并非玩家的真实下注和奖励
order.extra_businessobject不同游戏额外的业务数据包含本局玩家实际的下注和奖励等业务信息

注意⚠️order.amount为流水记录,并非实际下注和派彩,对于对战类和输金可能超过下注金额的百人类游戏,order.amount额外包含了预扣金额和预扣返还金额。

预扣:处理玩家快速下注和未知输赢金额时的余额不足问题时,提前质押玩家部分余额的行为,对局结束后即会返还,目前捕鱼类、对战类、百人类,均会使用预扣。

比如:游戏Mythical Animals,玩家下注100$,下注时order.amount则是-1300$,本局结束玩家额外再输掉了300$,奖励时order.amount则是900$。

百人类和对战类游戏中额外的业务数据说明:

参数类型说明
extra_business.total_betint玩家在本局游戏里的实际下注
extra_business.total_awardint玩家在本局游戏里的实际奖励

Response:

json
// content-type: application/json
{
    "header": {
        "code": 0, // 错误编码,0表示正常, 非0表示异常
        "msg": "not allowed bet",
        "reason":"not allowed bet",
    },
    "result": 
    {
        "data":[
            {
                "code": 0, // 错误编码,0表示正常, 非0表示异常
                "op_id": "111444", // required op侧用户的唯一标识
                "availableAmount": 998, // required op用户当前可用余额   
            },
            {
                "code": 0, // 错误编码,0表示正常, 非0表示异常
                "op_id": "111445", // required op侧用户的唯一标识
                "availableAmount": 998, // required op用户当前可用余额   
            }
        ]  
    }
}

POST /member/profile 用户信息查询

说明:用于即时获取用户信息

json
content-type: application/json
{
    "op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
}

参数说明:

参数类型说明备注
op_idstringOP 的玩家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
    }
}

POST /order/business 业务数据推送

说明:该接口为非必需接口,用于将一些游戏的业务信息即时的推送到OP侧,比如捕鱼类游戏玩家的开火和击杀数据。

json
content-type: application/json
{
    "game_id": 4001, // 游戏ID
    "room_kind": 1, //  场次编号
    "businesses":Object // 不同游戏自身的业务数据
}

参数说明:

参数类型说明备注
game_idint游戏ID
room_kindint场次编号
businessesObject游戏的业务数据Fishdom

Response:

json
content-type: application/json
{
    "header": {
        "code": 0, // 错误编码,0表示正常, 非0表示异常
        "msg": "",
        "timestamp":1709716095516,
    }
}

2J Game Inc.