产品 · Gate
贷记之前的一次调用。
一笔入金到账。在它变成某个人可提的余额之前,你的集成问一个问题,得到三个答案之一,并附上判定归类、这笔钱该进哪个池、要解除挂起需要发生什么,以及该答案所依据的一切内容的引用。这一页真正值得读的不是正常路径,而是「出问题时会怎样」那张表。
三个答案
没有第四个,也没有任何数值字段能让你自己卡一个阈值出来当第四个。
- CREDIT
- 什么都没查到,该查的全都查了,而且本次裁决的覆盖健康度是干净的。可以贷记。
- HOLD
- 先不要贷记。要么查到了需要人来看的东西,要么有东西没能查成。响应会说清是哪一种、要怎样才能解除、以及截止到什么时候。
- REJECT
- 不要贷记。响应附判定归类,以及这笔钱应当被路由到哪个池,而不是进你的通用归集地址。
CREDIT 是唯一一个要求「所有环节都正常」的裁决。这种不对称是设计本身,不是设计的副作用。
响应里有什么
- 裁决 ID
- 在记录的整个生命周期内稳定,也是若干年后取回证据包的钥匙。
- 裁决与风险等级
- 答案,以及它落在哪个等级里。是等级不是分数——见本页末尾那条约束。
- 资金池
- 这笔入金该进哪个归集池。归集动作在动钱之前会先校验池。
- 判定理由
- 归类代码。你知道它「为什么被挡」,但不知道「我们怎么算出来的」。任何来自外部来源的理由都附带指向该来源原始响应留存件的引用。
- 多源不一致标记
- 当被调用的来源互相矛盾时置位。它被摆给你看,而不是替你消解掉。
- 规则版本
- 产生这条裁决的那份确切配置。这样一条旧裁决可以按当时真正生效的规则重读,而不是按今天的规则。
- 待办动作与期限
- 要解除 HOLD 需要发生什么,以及到哪个时点会突破你自己的服务目标。
- 证据引用
- 内容寻址,指向 Evidence 页描述的那个包。
出问题时会怎样
这张表就是产品本身。下面每一条路径都解析为 HOLD。不存在任何故障组合能得出 CREDIT,没有开关能放宽它,也没有任何可用性指标的优先级高于它。
| 故障 | 结果 | 你怎么收到 |
|---|---|---|
| 某个筛查来源超时或不可用 | HOLD | 200 · SCREENING_DEGRADED |
| 你本周期的筛查预算已耗尽 | HOLD | 200 · BUDGET_EXHAUSTED |
| 某份名单的新鲜度已超过目标 | HOLD | 200 · LIST_STALE |
| 裁决无法在延迟预算内给出 | HOLD | 200 · 超时降级 |
| 与这笔入金相关的某个权限当前不可观测 | HOLD | 200 · coverage_health |
| Foreshock 不可用,或你的网络无法连到我们 | HOLD | 5xx 或无响应 · 由 SDK 转换 |
| 任何不在这张表里的情况 | HOLD | — |
默认值写在 SDK 里
我们不可达时,你的代码根本没有响应可以解释,于是「安全的行为」必须成为某一方的默认值。我们让它成为我们的默认值。客户端 SDK 开箱即把 5xx、超时和连接失败当作 HOLD,不需要配置任何东西。默认值决定了绝大多数集成实际上怎么跑;把这一条留给接入方自己实现,正是一个 fail-closed 系统悄悄变成 fail-open 的方式。
规则是配置
改一个阈值不需要发版,但也不会没人看见。
- 版本化
- 每一次改动都有版本号,每一条裁决都记下它当时跑在哪个版本上。
- 二人复核
- 规则变更需要第二个人才能生效。这由控制台强制,不靠手册约束。
- 影子模式
- 让一套候选规则跑在真实流量上但不影响任何裁决,先看清差异,再决定要不要切。
- 可审计
- 谁在什么时候改了什么、原值是什么——与裁决记录写在同一份只增不改的记录里。
资金不混池
裁决带上这笔入金该进的池,归集动作在动钱之前先校验池,周期性自检会把已归集的部分再读一遍池归属。这里要防的失败——隔离资金被扫进与干净资金同一个归集地址——事后无法撤销,所以归集前查一次,归集后再查一次。