Appearance
第八章 投注校验完整流程
8.1 校验链路总览
投注请求在进入系统后,先获取用户钱包币种,确定限额查询的币种维度,再按以下顺序逐级校验(8步),任一步失败即拒绝。所有限额值从该币种的配置表中查询,不做汇率换算。
| 步骤 | 校验内容 | 数据来源 | 默认限额参考(CNY,等级1让球组) |
|---|---|---|---|
| 前置 | 获取用户钱包币种,确定限额查询的币种维度 | 用户钱包 | — |
| 1 | 有效单注区间校验(用户单注区间 与 单注限额取交集) | 用户限额 + 联赛限额单注限额 | 10 至 20,000(取交集后) |
| 2 | 用户单玩法货量校验 | 用户限额面板 | 50,000 |
| 3 | 用户单比赛货量校验 | 用户限额面板 | 100,000 |
| 4 | 联赛限额→玩法分组单用户货量校验 | 联赛限额面板 | 50,000(让球组) |
| 5 | 联赛限额→单比赛单用户货量校验(若开关开启) | 联赛限额面板 | 100,000(开关默认开启) |
| 6 | 玩法全局货量校验(BetTypeId级,跨赛事合计) | 玩法限额面板 | BT1:500,000 |
| 7 | 联赛限额→玩法分组货量校验 | 联赛限额面板 | 300,000(让球组) |
| 8 | 联赛限额→单场最大货量校验(若开关开启) | 联赛限额面板 | 1,000,000(开关默认开启) |
以上默认值均为风控管理配置。完整默认值见第二章(联赛限额)、第三章(用户限额)、第四章(玩法限额)。步骤5受单比赛单用户最大货量开关控制,开关关闭时跳过该步骤(详见第二章 2.8.1 节)。步骤8受单场最大货量开关控制,开关关闭时跳过该步骤(详见第二章 2.8 节)。
关键原则:有效限额 = 所有维度限额中的最小值。即:某笔投注能否通过,由它在每个维度上是否超限决定——任一维度超限即拒绝。
8.2 校验顺序设计原理
8步校验从细粒度到粗粒度分为三个区段:
| 区段 | 步骤 | 校验对象 | 说明 |
|---|---|---|---|
| 用户级校验 | 1、2、3 | 单用户行为 | 成本最低,仅查一条用户记录即可判定,优先排除 |
| 联赛限额用户维度 | 4、5 | 单用户在联赛限额内的行为 | 需关联联赛等级配置,查询该用户在该场某分组的累计货量 |
| 容量级校验 | 6、7、8 | 全局与场次容量 | 需聚合所有用户货量,计算成本最高,放在最后 |
这样设计的好处:绝大多数被拒绝的投注在步骤1至3即被过滤,无需执行高成本的聚合计算。
8.3 各步骤详解
步骤1:有效单注区间校验
校验条件:投注金额A必须在有效单注区间内。
有效单注区间由用户限额面板的单注区间与联赛限额面板的单注限额取交集:
- 有效 min = 用户单注区间 min 与 玩法分组单注限额 min 取较大值
- 有效 max = 用户单注区间 max 与 玩法分组单注限额 max 取较小值
- 若有效 min > 有效 max,则该用户在该玩法分组下无法投注
拒绝原因:投注金额低于有效单注最小值 / 投注金额超出有效单注最大值 / 无有效投注区间
数据来源:用户限额面板(默认值为 10 至 20,000,风控管理配置)加 联赛限额面板单注限额(按等级和分组不同,详见第二章 2.6 节)
步骤2:用户单玩法货量校验
校验条件:用户U在赛事M中玩法BT_X已投注额 + 本次金额A ≤ 用户单玩法最大货量
拒绝原因:超出用户单玩法限额
数据来源:用户限额面板(默认值为 50,000,风控管理配置)
说明:此处"单玩法"指单个BetTypeId,非玩法分组。例如用户在BT6和BT158各投注30,000,步骤2分别校验,均不超50,000。
步骤3:用户单比赛货量校验
校验条件:用户U在赛事M所有玩法已投注额 + 本次金额A ≤ 用户单比赛最大货量
拒绝原因:超出用户单比赛限额
数据来源:用户限额面板(默认值为 100,000,风控管理配置)
步骤4:联赛限额→玩法分组单用户货量校验
校验条件:用户U在赛事M中玩法分组G已投注额 + 本次金额A ≤ 联赛等级N下分组G单用户最大货量
拒绝原因:超出分组单用户限额
数据来源:联赛限额面板(默认值按等级和分组不同,等级1让球组默认值为 50,000,风控管理配置。详见第二章 2.5 节)
与步骤2的区别:步骤2按单个BetTypeId统计(用户限额面板,全局统一值),步骤4按玩法分组统计(联赛限额面板,分等级分组独立值)。一个分组内包含多个BetTypeId,因此步骤4的累计额通常≥步骤2的累计额。
步骤5:联赛限额→单比赛单用户货量校验
前置条件:该联赛等级的单比赛单用户最大货量开关为开启状态(默认开启,风控管理配置)。若开关关闭,跳过此步骤。
校验条件:用户U在赛事M所有玩法已投注额 + 本次金额A ≤ 联赛等级N下单比赛单用户最大货量
拒绝原因:超出单比赛单用户限额
数据来源:联赛限额面板(默认值按等级不同,等级1默认值为 100,000,风控管理配置。详见第二章 2.1.1 节)
与步骤3的区别:步骤3是用户限额面板的全局设置(所有赛事统一),步骤5是联赛限额面板的分等级设置。等级1默认值均为100,000,但低级别联赛等级更低——例如等级10单比赛单用户默认值为 5,000,此时步骤3(100,000)通过但步骤5(5,000)拒绝。
开关关闭时的影响:步骤5被跳过,用户在单场比赛的总投注额无赛事级用户限额。此时用户维度仅受步骤4(玩法分组单用户货量)约束。详见第二章 2.8.1 节。
步骤6:玩法全局货量校验
校验条件:BT_X在所有赛事合计已接受货量 + 本次金额A ≤ BT_X全局最大货量
拒绝原因:超出BT_X玩法全局限额
数据来源:玩法限额面板(默认值按BetTypeId不同,如BT1默认值为 500,000,BT6默认值为 100,000,风控管理配置。详见第四章)
说明:这是唯一的跨赛事维度校验。其余7步均为单场或单用户维度。
步骤7:联赛限额→玩法分组货量校验
校验条件:赛事M中玩法分组G已接受货量 + 本次金额A ≤ 联赛等级N下分组G最大货量
拒绝原因:超出分组最大货量
数据来源:联赛限额面板(默认值按等级和分组不同,等级1让球组默认值为 300,000,风控管理配置。详见第二章 2.4 节)
与步骤6的区别:步骤6按单个BetTypeId跨赛事合计(玩法限额面板),步骤7按玩法分组单场合计(联赛限额面板)。两层独立校验,投注必须同时满足。
步骤8:联赛限额→单场最大货量校验(受开关控制)
前置条件:该联赛等级的单场最大货量开关为开启状态(默认开启,风控管理配置)。若开关关闭,跳过此步骤直接接受投注。
校验条件:赛事M全场已接受货量 + 本次金额A ≤ 联赛等级N下单场最大货量
拒绝原因:超出单场最大货量
数据来源:联赛限额面板(默认值按等级不同,等级1默认值为 1,000,000,风控管理配置。详见第二章 2.1.1 节)
开关关闭时的影响:步骤8被跳过,赛事级总货量无硬上限。此时风险仅受步骤7(玩法分组货量)和步骤5(单比赛单用户货量)约束。详见第二章 2.8 节。
8.4 串关投注校验差异
串关投注在上述8步流程之前,还需通过串关限额的额外校验(场数、投注区间、N串关限额),详见第五章。串关投注通过串关限额校验后,每一场仍需分别通过上述8步单关流程中的全部校验。
复式串关跟随最高串关场数限额,详见第五章。
8.5 投注通过后的异步处理
投注被接受后,系统异步执行两项任务:
异步处理不阻塞投注接受流程,确保投注响应延迟不受影响。
8.6 拒绝响应规范
C端用户提示:投注被拒绝时,C端统一显示"投注失败"并退还投注额,不暴露具体拒绝原因。
操盘端返回字段:系统在内部记录以下信息,供操盘手在后台查看:
| 返回字段 | 说明 | 示例 |
|---|---|---|
| 拒绝步骤 | 命中的具体校验步骤编号 | 步骤4 |
| 拒绝维度 | 命中的具体校验层 | 联赛限额→特殊组单用户货量 |
| 限额值 | 该维度的配置限额 | 15,000 |
| 已用额度 | 该维度已接受的货量 | 12,000 |
| 本次尝试 | 本次投注金额 | 5,000 |
| 该维度剩余 | 限额值 - 已用额度 | 3,000 |
8.7 多维度交叉校验场景示例
以下场景使用统一的比赛和配置参数,展示不同维度成为瓶颈时的处理逻辑。
统一参数:
比赛:英超 曼城 vs 利物浦(联赛等级1)
玩法:BT6 波胆(属特殊组,Main EventGroupType)
用户:张三
配置限额(所有均为默认值,风控管理配置):
用户单注区间 = 10 至 20,000(用户限额面板)
等级1特殊组单注限额 = 10 至 5,000(联赛限额面板)
有效单注区间 = 10 至 5,000(单注限额 max 5,000 比 用户单注 max 20,000 更严格)
用户单玩法限额 = 50,000(用户限额面板)
用户单比赛限额 = 100,000(用户限额面板)
等级1特殊组单用户最大货量 = 15,000(联赛限额面板)
等级1单比赛单用户最大货量 = 100,000(联赛限额面板)
BT6玩法全局限额 = 100,000(玩法限额面板)
等级1特殊组最大货量 = 80,000(联赛限额面板)
等级1单场最大货量 = 1,000,000(联赛限额面板)8.7.1 场景一:单注限额拦截(步骤1命中)
投注金额超出有效单注区间最大值——操盘手最常见的低级别联赛/冷门玩法拦截场景。
本次投注金额 = 8,000
步骤1:有效单注区间校验
有效区间 = 10 至 5,000
8,000 > 5,000(有效 max)
结论:拒绝——超出有效单注最大值(单注限额 5,000 生效)
(串行校验终止,不再执行后续步骤)8.7.2 场景二:分组单用户超限(步骤4命中)
用户在特殊组内多个玩法分散投注,单个BetTypeId未超限但分组合计超限。
当前已用额度:
张三该场BT6已投注 = 5,000
张三该场特殊组所有玩法已投注 = 12,000(含BT6的5,000 + BT158的4,000 + BT62的3,000)
张三该场所有玩法已投注 = 60,000
本次投注金额 = 5,000
步骤1:有效单注区间
5,000 ≤ 5,000(有效 max)且 5,000 ≥ 10(有效 min)
结论:通过
步骤2:用户单玩法
张三该场BT6已投注 + 本次 = 5,000 + 5,000 = 10,000
10,000 ≤ 50,000(用户单玩法限额)
结论:通过
步骤3:用户单比赛
张三该场所有玩法已投注 + 本次 = 60,000 + 5,000 = 65,000
65,000 ≤ 100,000(用户单比赛限额)
结论:通过
步骤4:分组单用户货量
张三该场特殊组已投注 + 本次 = 12,000 + 5,000 = 17,000
17,000 > 15,000(等级1特殊组单用户最大货量)
结论:拒绝——超出分组单用户限额
(串行校验终止,不再执行后续步骤)
特殊组还能接受(用户维度)= 15,000 - 12,000 = 3,0008.7.3 场景三:玩法全局超限(步骤6命中)
单个玩法在所有赛事合计已接近全局上限——跨赛事维度的限额触发。
当前已用额度:
张三该场BT6已投注 = 3,000
张三该场特殊组所有玩法已投注 = 8,000
张三该场所有玩法已投注 = 50,000
BT6全局已接受(所有赛事合计) = 97,000
该场特殊组已接受 = 50,000
该场全场已接受 = 600,000
本次投注金额 = 5,000
步骤1:有效单注区间 → 5,000 在 10 至 5,000 内 → 通过
步骤2:用户单玩法 → 3,000 + 5,000 = 8,000 ≤ 50,000 → 通过
步骤3:用户单比赛 → 50,000 + 5,000 = 55,000 ≤ 100,000 → 通过
步骤4:分组单用户 → 8,000 + 5,000 = 13,000 ≤ 15,000 → 通过
步骤5:单比赛单用户 → 50,000 + 5,000 = 55,000 ≤ 100,000 → 通过
步骤6:玩法全局货量
BT6全局已接受 + 本次 = 97,000 + 5,000 = 102,000
102,000 > 100,000(BT6全局限额)
结论:拒绝——超出BT6玩法全局限额
BT6还能接受 = 100,000 - 97,000 = 3,0008.7.4 场景四:分组容量超限(步骤7命中)
单场比赛某一分组接近容量上限。
当前已用额度:
张三该场BT6已投注 = 2,000
张三该场特殊组所有玩法已投注 = 6,000
张三该场所有玩法已投注 = 40,000
BT6全局已接受(所有赛事合计) = 60,000
该场特殊组已接受 = 77,000
该场全场已接受 = 600,000
本次投注金额 = 5,000
步骤1至5:全部通过(分组单用户 6,000 + 5,000 = 11,000 ≤ 15,000)
步骤6:玩法全局 → 60,000 + 5,000 = 65,000 ≤ 100,000 → 通过
步骤7:分组货量
该场特殊组已接受 + 本次 = 77,000 + 5,000 = 82,000
82,000 > 80,000(等级1特殊组最大货量)
结论:拒绝——超出分组最大货量
特殊组还能接受 = 80,000 - 77,000 = 3,0008.7.5 场景五:全部通过
所有8步均在限额范围内。
当前已用额度:
张三该场BT6已投注 = 2,000
张三该场特殊组所有玩法已投注 = 6,000
张三该场所有玩法已投注 = 40,000
BT6全局已接受(所有赛事合计) = 60,000
该场特殊组已接受 = 50,000
该场全场已接受 = 600,000
本次投注金额 = 3,000
步骤1:有效单注区间
3,000 ≥ 10 且 3,000 ≤ 5,000
结论:通过
步骤2:用户单玩法
BT6已投注 + 本次 = 2,000 + 3,000 = 5,000
5,000 ≤ 50,000
结论:通过
步骤3:用户单比赛
所有玩法已投注 + 本次 = 40,000 + 3,000 = 43,000
43,000 ≤ 100,000
结论:通过
步骤4:分组单用户
特殊组已投注 + 本次 = 6,000 + 3,000 = 9,000
9,000 ≤ 15,000
结论:通过
步骤5:单比赛单用户
所有玩法已投注 + 本次 = 40,000 + 3,000 = 43,000
43,000 ≤ 100,000
结论:通过
步骤6:玩法全局
BT6全局 + 本次 = 60,000 + 3,000 = 63,000
63,000 ≤ 100,000
结论:通过
步骤7:分组货量
特殊组已接受 + 本次 = 50,000 + 3,000 = 53,000
53,000 ≤ 80,000
结论:通过
步骤8:单场最大货量
全场已接受 + 本次 = 600,000 + 3,000 = 603,000
603,000 ≤ 1,000,000
结论:通过
最终结论:投注接受,更新各维度货量
触发异步:风险敞口计算 + 告警检测8.7.6 场景六:多维度同时紧张(步骤4首先命中)
极端场景——多个维度同时超限,但串行校验只命中第一个即终止。
当前已用额度:
张三该场BT6已投注 = 4,000
张三该场特殊组所有玩法已投注 = 13,000
张三该场所有玩法已投注 = 95,000
BT6全局已接受(所有赛事合计) = 98,000
该场特殊组已接受 = 78,000
该场全场已接受 = 998,000
本次投注金额 = 5,000
步骤1:有效单注区间 → 5,000 ≤ 5,000 → 通过
步骤2:用户单玩法 → 4,000 + 5,000 = 9,000 ≤ 50,000 → 通过
步骤3:用户单比赛 → 95,000 + 5,000 = 100,000 ≤ 100,000 → 通过(刚好踩线)
步骤4:分组单用户
13,000 + 5,000 = 18,000
18,000 > 15,000
结论:拒绝——超出分组单用户限额(第一个命中,串行终止)
实际同时超限但未被执行到的步骤:
步骤6:BT6全局 98,000 + 5,000 = 103,000 > 100,000(会超限)
步骤7:特殊组 78,000 + 5,000 = 83,000 > 80,000(会超限)
步骤8:全场 998,000 + 5,000 = 1,003,000 > 1,000,000(会超限)