一个接入众多供应商的老虎机、真人荷官和桌面游戏的娱乐场后端,需要一个聚合层:由运营商签发的会话、经得住重试和回滚的余额回调、可能在会话之后才结束的回合,以及与每家供应商自己的报表进行的每日对账。本文讲这一层怎样划分,以及供应商集成通常在哪里出问题。
一家自建娱乐场后端、接入众多供应商的老虎机、真人荷官和桌面游戏的运营商,最终会有和供应商一样多的集成契约:不同的启动流程、不同的钱包调用、对回合是什么各有不同的理解。聚合层把它们变成一套内部契约,这样钱包、大厅、奖金、限额和报表都只需编写一次,每家供应商都去适配它们。
下文讲这一层通常怎样划分:哪些留在供应商那边、会话如何签发、余额回调如何经得住重试和回滚、回合在会话之后才结束时如何记录,以及结果如何与供应商自己的数字对账。
简短的答案是:一套内部契约,每家供应商配一个适配器。运营商签发会话;每一笔扣款、加款和回滚都携带供应商的交易 ID,作为按供应商和调用类型限定范围的幂等键;针对钱包从未见过的交易的回滚会被保存下来,因此迟到的原始交易会被拒绝;回合以状态的形式记录,而且可能在会话结束之后才结束;每家供应商自己的报表每天都与钱包账本对账。
供应商负责运行游戏:随机数生成、游戏数学、游戏客户端及其由检测实验室完成的认证。运营商保留一切涉及玩家和资金的部分:身份、余额、限额、奖金、大厅,以及监管机构或玩家争议可能要求提供的记录。聚合层位于两者之间,并且应当是唯一对接各家供应商 API 的服务端代码。
供应商以两种方式之一接入运营商的资金。在单一钱包(seamless wallet)模式下,余额留在运营商这边,每一次投注和派彩,供应商都要调用运营商的钱包。在转账钱包(transfer wallet)模式下,运营商在游戏开始前把资金转入供应商一侧持有的余额,并且只有在运营商发起请求时才把资金转回。
本文余下部分以单一钱包为前提,因为在这种模式下,每一次投注和派彩都是一次钱包调用。
游戏启动从运营商一侧开始。后端检查这名玩家此刻可否玩这款游戏,检查范围包括账户状态、自我排除、限额,以及这款游戏可否在玩家所在的司法辖区提供。随后它创建一个与玩家、游戏和币种绑定的会话,并在启动时把一个不透明令牌传给供应商。当供应商的服务器发起回调时,这个令牌标明该调用涉及的是谁的余额。
面向运营商公开发布的文档把这一点说得很直白。Hub88 的钱包 API 说明,对派彩和回滚不得校验令牌是否有效,因为它们可能在投注已经完成之后才到来。VeliGames 说明,即使会话已经过期,运营商也不得拒绝某个回合的派彩。
两台服务器之间的任何调用,都可能在对端已经把工作做完之后才超时。供应商分辨不出是扣款失败了,还是扣款的响应丢了,所以它会重复这次调用,或者取消这笔交易。钱包的职责是让这两种做法都安全。
公开的集成文档表明,这些重复调用有多执着。Hub88 的运营商钱包 API 在收不到 HTTP 200 时就把投注算作失败,生成一个回滚,并以指数退避重试这个回滚,最多 500 次。Gamomat 会把失败的请求重试两次,间隔 500 ms,然后发起回滚,并以从一秒逐步增长到 30 分钟的间隔重试它。Tom Horn Gaming 的钱包超时时间是 10 秒,超时之后会自动发送回滚。一个宕机几分钟的钱包,恢复之后面对的是排着队的重复调用和回滚,而不是一片安静。
对重复调用该怎样应答,也没有统一标准。Hub88 要求相同交易 ID 的请求不得被处理两次,并且所有重复请求得到的响应都相同;VeliGames 要求返回一个带 HTTP status 409 和 DUPLICATE_TRANSACTION 的错误;Tom Horn Gaming 为重复的参考号单独设有一个结果码。适配器按每家供应商各自的形式应答,底层的账本保持不变。
针对未知交易的回滚很容易处理错。如果钱包什么都不保存,一笔只是在传输途中被延迟的扣款会在片刻之后到达并成功,玩家就要为一笔供应商已经取消的投注付钱。先把回滚存下来,再在扣款的账户锁之下检查它,就能堵上这个缺口。
供应商在自己的文档里写明了这条规则。St8 的运营商 API 说明:当运营商收到一个取消请求,而其中的交易 ID 是运营商此前没有处理过的,就必须保存这个 ID,以防该 ID 之后被处理。当钱包从未处理过回滚所指向的那笔扣款时,Tom Horn Gaming 期望收到它自己的未知交易结果码。
回合是供应商的游戏单位,它很少恰好对应一笔交易。一次老虎机旋转通常是一笔扣款加一笔加款,有时作为一次调用发送。二十一点可能因分牌或加倍而追加扣款。真人轮盘在一个投注窗口内接收许多玩家的投注,并在结果揭晓时将它们全部结算。免费回合可能产生一连串同属一组的派彩。
玩家争议要靠回合历史来解决。每条账本分录都要记下供应商、游戏、回合、金额、变动前后的余额,以及两个时间戳(供应商的和钱包的);如果供应商的 API 提供回合详情,还要链接到供应商自己的回合详情。有了这些,关于某一次旋转中资金的疑问,就能从记录中得到解答。
这份历史至少要覆盖什么,由监管机构来规定。GLI-19 是 Gaming Laboratories International 制定的互动博彩系统标准,它要求为玩家提供游戏回溯功能,形式可以是重现,也可以是描述。英国博彩委员会(UK Gambling Commission)的远程技术标准要求:无需联系持牌方即可获取至少三个月的账户和博彩历史,经申请可获取至少 12 个月。马耳他博彩管理局(Malta Gaming Authority)的玩家保护指令让玩家可以查看自己最近六个月的博彩历史。
老虎机把负载分散在时间上,因为每个玩家都按自己的时间旋转。真人荷官桌台会让玩家同步:桌上所有人的投注都在停止投注前的几秒内到达,而所有人的派彩在结果揭晓时一起到达。一张热门桌台会为每一位投注的玩家重复这一过程。
供应商之间的差异存在于适配器中,而且适配器应当是这些差异唯一的所在之处。每个适配器负责:
内部契约保持精简:开启会话、读取余额、扣款、加款、在一次调用中扣款并加款、无投注派彩、回滚、结束回合,以及钱包可以返回的一组固定错误。这样一来,一家新供应商就是一个适配器加一套测试套件,很少需要改动钱包。
每家供应商都对每个回合保有自己的记录,并据此向运营商开票。聚合层的账本,是同一笔资金在运营商这一侧的记录。每天对两者做对账,采用每家供应商的日切时间和时区,按供应商、币种和游戏分别进行:
这些证据要保存多久,是集成的一部分。Hub88 要求每个交易 ID 在双方都至少保存四个月,以供对账之用;Gamomat 的运营商 API 则会返回某一日期范围或单个回合的对账数据。
这个问题有三类答案,它们卖的是不同的东西。聚合商和平台厂商把自家的聚合层租给运营商:一份合同、众多供应商、他们的商业条款。交钥匙平台和白标平台把这一层包含在归厂商所有的平台之内。工程公司在运营商的后端之内构建这一层,运营商自己与供应商签订合同。
无论你在和哪一类公司打交道,下面这些问题都能看出一个团队以前是否做过这件事:
只要前两个问题的回答停留在泛泛而谈,就说明边界情况要到生产环境里才会被发现。
amBrain 是一家软件开发公司,专注于交易平台、撮合引擎、实时竞价系统和娱乐场平台工程。amBrain 自 2019 年起开发软件。
在 iGaming 领域,amBrain 作为实测公布的数字是:500+ 第三方供应商集成,以及 12 家运营商已上线运行。
amBrain 有三种合作方式:整体交付、专属团队,或工程师嵌入你的团队。客户拥有产品与代码的全部所有权,amBrain 的可复用组件除外。
本文讲的是聚合层如何运作;它不是案例研究,也不点名任何客户。
所以第一个决定不是签哪些供应商。而是每家供应商都将适配到的那套内部契约——在第一个适配器出现之前,连同它的错误情形一起写下来。
带上您当前的架构和让您担心的故障场景,我们用半小时一起梳理。