Seamless Wallet 模式
在这种模式下,需要 OP 给 2J 提供一些接口,以便 2J 能够实时获取 OP 玩家的余额信息,并完成下注、派彩等操作。
交互流程参见 流程概览。
2J 侧提供的接口
接口名称 | 描述 | 路径 |
---|---|---|
通用接口 | 2J 提供的通用场景下的接口 | |
用户余额变化通知 | 通知 2J 更新用户余额 | /open2j/w/seamless/balance_change |
1. 用户余额变化通知
Method: POST
URI:: /open2j/w/seamless/balance_change
Description: 通知 2J 用户余额变动值,近实时更新用户在 2J 游戏中的余额。
Request Body:
Content-Type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"changed_amount": 123, // 余额变动值:正值代表增加,负值代表减少, required
"trans_no": "xxxxxxxx" // 变动的唯一标识,required
}
参数说明:
参数 | 类型 | 描述 | 是否必填 | 取值范围 |
---|---|---|---|---|
op_id | string | OP 的玩家id | 是 | |
changed_amount | int | 余额变动值 | 是 | [-9,223,372,036,854,775,808, 9,223,372,036,854,775,807] |
trans_no | string | 变动的唯一标识 | 是 | 长度限制 6-64 |
Response Body:
Content-Type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常, 非0表示异常
"msg": "",
"timestamp":1709716095516,
}
}
OP 侧提供的接口
OP 需要提供以下接口给 2J 使用,接口的超时时间为 5 秒,超时后 2J 会认为接口调用失败。
接口名称 | 描述 | 路径 | 必须 |
---|---|---|---|
查询用户余额接口 | 查询用户余额 | /balance/get | 是 |
用户信息查询 | 用户信息查询 | /member/profile | 是 |
用户下注/结算 | 用户下注/结算 | /order/transfer | 否,取决于接入游戏 |
用户批量下注/结算 | 用户批量下注/结算 | /order/batch_transfer | 否,取决于接入游戏 |
业务数据推送 | 业务数据推送 | /order/business | 否 |
关于 /order/transfer
和 /order/batch_transfer
的选择,不同游戏ID范围对应不同不同类型的游戏,适用不同的下注和派彩接口,具体如下:
游戏ID范围 | 适用下注/结算接口 |
---|---|
1000~1999 | /order/transfer |
2000~2999 | /order/batch_transfer |
3000~3999 | /order/batch_transfer |
4000~4999 | /order/transfer |
6000~6999 | /order/transfer |
1. 查询用户余额接口 /balance/get
Method: POST
URI: /balance/get
Description: 查询用户余额
Request Body:
Content-Type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"game_id": 1006, // 游戏ID,表示是从哪个游戏中请求过来的,可选
}
Response Body:
Content-Type: application/json
{
"header": {
"code": 103, // 错误编码,0表示正常, 非0表示异常
"msg": "user not exist",
"timestamp":1709716095516,
},
"result": {
"op_id": "111444", // op侧用户的唯一标识
"availableAmount": 998, // op用户当前可用余额
},
}
2. 用户信息查询 /member/profile
Method: POST
URI: /member/profile
Description: 用于即时获取用户信息
Request Body:
Content-Type: application/json
{
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
op_id | string | OP 的玩家id |
Response Body:
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
}
}
3. 用户下注/结算 /order/transfer
Method: POST
URI: /order/transfer
Description: 用于单人游戏下注和派彩,适用于slots、休闲和捕鱼类游戏。
该接口适用于单人游戏:用于OP用户下注和派彩,至少一次的调用,OP需要保持该接口的 幂等。
派彩重试:当调用派彩时出现网络错误或者返回的http code不等200时,2J会尝试多次调用该接口。
下注撤销发生在用户下注时,2J 调用 OP 的接口失败 (超时,异常错误) 时,2J 会调用此接口并指定 action=3 表示撤销下注。
请注意,重试派彩或者撤销下注时,如果OP方已经成功处理,那么需要返回正常的结果,即header.code=0,请不要返回错误。
注意⚠️:投注撤销
的请求参数中,amount
为正数,值等于之前的下注金额(负数)的绝对值;action
为 3
。 其余参数和下注请求一致(包括 trans_no
和 draw_id
)。
Request Body:
Content-Type: application/json
{
"action":1, // 1:下注,2:派彩, 3:下注撤销
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"timestamp": 1709201163, // 时间戳(秒) 本笔订单的创建时间
"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": 1000, // 退出捕鱼类时本次击杀获得金额,非本次游戏的实际赢利金额,该值仅为示例
"award_type": 0, // 奖励类型 0-普通,1-freegame,2-bonus
"base_amount": 12000, // 触发局除JP之外的总奖励
"free_amount": 0, // feature内的总赢奖,排除触发局和JP的奖励
"bonus_amount": 0, // feature内的总赢奖,排除触发局和JP奖励
"jackpot_amount": 0, // 统计单局游戏的所有JP总赢奖(包括std,featurre中的JP)
"extra_spins": 0, // 一局游戏中额外出现了多少次免费游戏
"is_buy": false // 这局游戏是否是购买获取
}
}
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
action | int | 请求行为 | 1: 下注 , 2: 奖励, 3: 下注撤销 |
op_id | string | OP 的玩家id | |
timestamp | int64 | 订单的创建时间 | |
order | object | 订单结构体 | |
order.trans_no | string | 订单唯一凭证,用该字段做幂等操作 | 如果收到完全相同的重复请求时, 一定要使用该字段做好幂等处理 |
order.draw_id | string | 牌局唯一标识 | |
order.game_id | int | 游戏id | |
order.amount | int64 | 金额变动 | 捕鱼类游戏下注时是预扣值,并非玩家实际下注 |
order.extra_business | object | 不同游戏额外的业务数据 | 捕鱼类游戏结算时玩家的实际下注和奖励在该字段体现 |
2J会不定期的更新extra_business信息,在接入时请注意对extra_business的兼容适配处理
注意⚠️:在捕鱼类游戏里金额变动同样以amount参数为准,extra_business仅仅只是本次游戏的统计数据, 捕鱼类游戏中额外的业务数据说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
extra_business.win_crash_bet | int | 在捕鱼类游戏中每轮结算周期内输赢为负的累计金额 | |
extra_business.total_bet | int | 退出捕鱼类游戏时本次的总开火金额 | |
extra_business.total_award | int | 退出捕鱼类游戏时本次击杀鱼得到的总奖励金额(该值非本次游戏的实际赢利金额) |
slots类游戏中额外的业务数据说明(如果不需要以下列表信息,slots类游戏请忽略extra_business字段):
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
extra_business.award_type | int | 奖励类型 | 0-普通,1-freegame,2-bonus |
extra_business.base_amount | int | 触发局除JP之外的总奖励 | |
extra_business.free_amount | int | feature内的总赢奖,排除触发局和JP的奖励 | |
extra_business.bonus_amount | int | feature内的总赢奖,排除触发局和JP奖励 | |
extra_business.jackpot_amount | int | 统计单局游戏的所有JP总赢奖(包括std,featurre中的JP) | |
extra_business.extra_spins | int | 一局游戏中额外出现了多少次免费游戏 | |
extra_business.is_buy | bool | 这局游戏是否是购买获取 |
Response Body:
Content-Type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常, 非0表示异常
"msg": "",
"timestamp":1709716095516,
},
"result":
{
"op_id": "111444", // required op侧用户的唯一标识
"availableAmount": 998, // required op用户当前可用余额
},
}
4. 用户批量下注/结算 /order/batch_transfer
Method: POST
URI: /order/batch_transfer
Description: 用于多人游戏下注和派彩
该接口适用于百人类和对战类游戏:用于OP多个用户下注和派彩,至少一次的调用,OP需要保持该接口的 幂等。
派彩重试:当调用派彩时出现网络错误或者返回的http code不等200时,2J会尝试多次调用该接口。
下注撤销发生在用户下注时,2J 调用 OP 的接口失败 (超时,异常错误) 时,2J 会调用此接口并指定 action=3 表示撤销下注。
请注意,重试派彩或者撤销下注时,如果OP方已经成功处理,那么需要返回正常的结果,即header.code=0,请不要返回错误。
注意⚠️:投注撤销
的请求参数中,amount
为正数,值等于之前的下注金额(负数)的绝对值;action
为 3
。 其余参数和下注请求一致(包括 trans_no
和 draw_id
)。
分批次调用:当一局有超过100人下注时,下注和派彩会分成多次并发的请求,每一个请求里包含最多100个下注或者派彩事务。
Request Body:
Content-Type: application/json
{
"action": 1, // 1:下注,2:派彩,3:下注撤销
"trans_no": "xxxxx-001",//本次调用请求唯一凭证
"draw_id": "1006-2-1726-1709201163", // 牌局唯一标识
"game_id": 1006, // 游戏ID
"room_kind": 0, // 房间类型
"timestamp":1709201163, // 时间戳(秒) 本笔订单的创建时间
"orders": [
{
"trans_no": "xxxxxxx-002", // 用户本次金额变更的唯一凭证,全局唯一
"op_id": "xxx-xxx-aaa", // op侧用户的唯一标识, required
"amount": -5000, // 金额变动
"extra_business": {"total_bet":6000,"total_award":1000},
},
{
"trans_no": "xxxxxxx-003", // 用户本次金额变更的唯一凭证,全局唯一
"op_id": "xxx-xxx-bbb", // op侧用户的唯一标识, required
"amount": 5000, // 金额变动
"extra_business": {"total_bet":1000,"total_award":5000},
}
]
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
action | int | 请求行为 | 1: 下注 , 2: 奖励, 3: 下注撤销 |
trans_no | string | 本次订单的唯一标识 | |
draw_id | string | 牌局唯一标识 | |
game_id | int | 游戏ID | |
room_kind | int | 房间类型 | |
timestamp | int64 | 本笔订单的创建时间 | |
orders | object | 订单结构体 | |
order.trans_no | string | 订单唯一凭证,用该字段做幂等操作 | 使用该字段做好幂等处理 |
order.op_id | string | op用户唯一标识 | |
order.amount | int64 | 金额变动 | 并非玩家的真实下注和奖励 |
order.extra_business | object | 不同游戏额外的业务数据 | 包含本局玩家实际的下注和奖励等业务信息 |
注意⚠️:order.amount为流水记录,并非实际下注和派彩,对于对战类和输金可能超过下注金额的百人类游戏,order.amount额外包含了预扣金额和预扣返还金额。
预扣:处理玩家快速下注和未知输赢金额时的余额不足问题时,提前质押玩家部分余额的行为,对局结束后即会返还,目前捕鱼类、对战类、百人类,均会使用预扣。
比如:游戏Mythical Animals,玩家下注100$,下注时order.amount则是-1300$,本局结束玩家额外再输掉了300$,奖励时order.amount则是900$。
有效下注:百人类游戏中,玩家下注时,根据不同游戏规则,计算出有效下注,该值会在结算请求中体现。 比如:百人游戏龙虎斗,玩家在龙区域下注100,同时在虎区域下注100,两个区域为对压区域,故有效下注为0。
2J会不定期的更新extra_business信息,在接入时请注意对extra_business的兼容适配处理
百人类和对战类游戏中额外的业务数据说明:
参数 | 类型 | 说明 |
---|---|---|
extra_business.total_bet | int | 玩家在本局游戏里的实际下注 |
extra_business.total_award | int | 玩家在本局游戏里的实际奖励 |
extra_business.valid_bet | int | 百人类游戏玩家的有效下注,该字段目前只有百人类游戏有效 |
Response Body:
Content-Type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常,除非所有用户都失败,才可以设置为非0(或者只要保证data里的code正确,这里的code可以一直为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用户当前可用余额
}
]
}
}
注意⚠️:header.code只有所有用户都失败时才可以设置为非0,如果将其设置成非0,2J会认为本次请求里的用户全部失败。
5. 业务数据推送 /order/business
Method: POST
URI: /order/business
Description: 该接口为非必需接口,用于将一些游戏的业务信息即时的推送到OP侧,比如捕鱼类游戏玩家的开火和击杀数据。
Request Body:
Content-Type: application/json
{
"game_id": 4001, // 游戏ID
"room_kind": 1, // 场次编号
"businesses":Object // 不同游戏自身的业务数据
}
参数说明:
参数 | 类型 | 说明 | 备注 |
---|---|---|---|
game_id | int | 游戏ID | |
room_kind | int | 场次编号 | |
businesses | Object | 游戏的业务数据 | Fishdom |
Response Body:
Content-Type: application/json
{
"header": {
"code": 0, // 错误编码,0表示正常, 非0表示异常
"msg": "",
"timestamp":1709716095516,
}
}