游戏服务类平台的技术评审,通常会花大量时间讨论派单算法、匹配效率、音视频链路,而把合规部分留给一份文档。等到上线前才发现:年龄校验只做在注册环节、账号凭据散落在业务库里、资金结算靠财务每月手工对账。这三件事都是结构性问题,越晚改代价越大。
本文不谈业务该不该做,只谈如果要做,工程上怎么把三条边界落到代码和数据里:年龄核验怎么分层、凭据边界画在哪里、资金怎么做到不落地。

图 5:年龄核验的分层结构——注册态、风险场景、准入侧各自承担不同职责
一、年龄核验:把"一次校验"改成"分层决策"
只做注册时的一次性校验,等于假设"注册主体 = 实际操作者"。这个假设在家庭共享设备的场景里几乎必然失效。更稳的结构是把核验拆成三层,每层职责不同、触发条件不同、失败处置也不同。
| 层 | 触发时机 | 校验内容 | 失败处置 |
|---|---|---|---|
| 注册层 | 首次注册、绑定手机号 | 手机号三要素、身份证二要素 | 拒绝注册,记录原因码 |
| 会话层 | 登录、换设备、跨地域、深夜时段 | 活体检测、设备指纹比对 | 降权登录:可浏览,不可交易 |
| 准入层 | 首次接单、提现、大额订单 | 活体检测 + 人工抽检 | 冻结该动作,转人工复核 |
三层的关键差别在失败处置的粒度。注册层失败是"进不来",会话层失败应当允许"进得来但做不了",准入层失败要能精确到"某一个动作被冻结"。如果三层都写成同一个布尔值,风控就没有调节余地——要么全放,要么全封。
工程上建议把核验结果建模成一张独立的核验记录表,而不是挂在用户表上的几个字段:
| 字段 | 含义 | 设计要点 |
|---|---|---|
| verify_id | 核验流水号 | 全局唯一,作为后续审计主键 |
| scene | 触发场景(注册 / 登录 / 接单 / 提现) | 枚举值,便于按场景统计失败率 |
| result | 核验结论 | 只存结论,不存原始生物特征 |
| channel | 核验渠道 | 不同渠道的可信级别不同,要能区分 |
| ts | 核验时间 | 与时区无关的时间戳 |
原始人脸图像不落库,是这套设计里一条硬约束:核验完成后立即销毁原图,仅保留结论、时间、渠道与流水号;确需留存的,走独立加密存储、独立权限与到期清理。这样既满足可追溯,也把泄露面收窄到可管理范围。
二、凭据边界:为什么不该设计账号代管
有些业务形态天然要求"拿到用户的游戏账号"。这里必须先做一个判断:账号凭据一旦进入系统,它就从"用户资产"变成了"平台负债"。
理由有三条,都是工程层面的:
- 凭据的不可撤销性。 支付凭据可以换卡、可以挂失;游戏账号的密码一旦交出,用户很难确认对方是否已彻底清除。系统无法向用户证明"我们没有留"。
- 凭据的横向扩散。 登录态、二次验证、设备绑定往往是一组凭据。为了"能用",实现方容易把整组凭据都存下来,存储面随之扩大到包含二次验证信息。
- 审计不可闭合。 即便只存加密后的凭据,也无法证明某次异常登录不是来自内部。日志能证明"谁调用了接口",不能证明"谁看了密钥"。
结论是:凭据托管不该出现在数据模型里。 与其事后加审计,不如让这类字段从一开始就不存在——数据库没有这张表,就不需要为它设计加密、轮换、访问控制与泄露演练。
可替代的形态是把服务做成"同局协作"而不是"代替操作":语音/画面同步、战术指令下发、战绩与数据复盘。这些形态不触碰他人账号凭据,工程复杂度也显著低于凭据托管。
三、资金不落地:指令流、幂等与回滚
资金链路的起点决策,不是选哪个接口,而是确认平台的账户在整个链路里的位置。合规结构里,平台只下发规则、收取佣金,不承接本金;用户支付的资金直接进入服务方的独立收款账户,由持牌机构按指令清分。
把这个结构落成状态机,比写成一段说明更有效:
| 状态 | 进入条件 | 可执行动作 | 异常出口 |
|---|---|---|---|
| 待支付 | 订单创建 | 发起支付 | 超时关闭 |
| 已支付待履约 | 支付成功回调 | 开始服务、计时 | 全额退款 |
| 履约中 | 服务方接单 | 计时、进度上报 | 争议冻结 |
| 待分账 | 验收通过 | 下发分账指令 | 分账失败重试 |
| 已分账 | 分账成功回调 | 完结、开票 | 退款回滚 |
| 已回滚 | 退款成功 | 冲抵后续结算 | —— |
三个必须写进接口契约的约束:
一是幂等键。 分账、退款、提现三个动作都要有业务幂等键,且要落到唯一索引上,不能只靠代码里的"先查再写"——并发下这个模式会漏。幂等键建议用「业务单号 + 动作类型」,重试时返回同一结果。
二是金额单位与精度。 全链路用整数分存储,禁止浮点。分账比例按基点(万分之一)存,避免 0.1 + 0.2 这类问题在资金场景里出现。
三是回滚的可达性。 退款发生时,已分出去的资金要能被追回或从后续结算中冲抵。这要求分账记录保留"原订单号 → 分账批次 → 接收方"的完整链路,而不是只留一条成功日志。没有这条链路,退款只能靠人工,人工就会出错。
| 反模式 | 表现 | 后果 |
|---|---|---|
| 平台归集后二次划付 | 资金先进平台账户,扣除后再转出 | 形成资金沉淀,属无证清算,渠道可能被关停 |
| 比例超限后线下补差 | 线上分一部分,剩余走私户转账 | 形成双账本,无票支出与流水异常同时出现 |
| 分账一次性调用无状态 | 调完即完,不记录批次 | 退款无法回滚,对账无从核对 |
| 提现无冷却与二次校验 | 到账即提,提现无风控 | 盗号后资金即时流出,追回概率极低 |
四、申诉与仲裁:把证据链当成功能做
游戏服务类订单的争议率高,且争议内容高度主观——"服务有没有按要求完成"。这类争议不可能靠规则自动判定,只能靠证据。
可落地的做法是把证据采集做成流程的一部分,而不是出事后再去找:
| 证据类型 | 采集时机 | 存储要求 |
|---|---|---|
| 订单操作日志 | 每次状态迁移 | 追加写入,不可修改,含操作者与设备 |
| 履约过程记录 | 服务开始、进度上报、结束 | 带时间戳,按订单归档 |
| 沟通记录 | 订单内会话 | 与订单绑定,独立于用户可删除的聊天 |
| 核验记录 | 每次活体与实名校验 | 以流水号关联,保留结论不保留原图 |
| 处置记录 | 每次冻结、降权、解封 | 含处置人、依据、期限,可追溯 |
日志的不可篡改比日志的完整性更重要。 一个可被业务代码随意覆盖的日志表,在争议场景里没有证明力。常见做法是追加写 + 定期哈希链快照,至少能让"事后修改"被发现。
五、小结
三条边界的工程落点可以概括成三句话:
- 年龄核验分层,把"能不能用"和"能不能做某个动作"分开,核验结果独立成表、原始生物特征不落库。
- 凭据边界前置,让账号代管这类字段在数据模型里不存在,用同局协作类形态替代代替操作。
- 资金不落地,平台只下发规则与收取佣金,指令有幂等键、金额用整数分、分账有状态且可回滚。
这三件事的共同点是:做的时点在项目早期,代价很小;在项目后期,代价是重写。