提供方超时、拒绝与不支持的路由:三种不同的结果

先在免费沙盒中跑通流程,再准备生产接入。

统计选择在本站复用,可随时关闭;账号关联另行同意。

提供方超时、拒绝与不支持的路由:三种不同的结果

身份入驻流程中的某一步调用了验证提供方,却没有拿到清晰的答复。可能是调用超时,可能是提供方返回了拒绝,也可能是所请求的路由根本不受支持。常见的捷径是把这三种情况统统当作“失败”,要么直接拒绝用户,要么直接放行。本文主张:应当由你的应用,而不是提供方或编排层,持有一张决策表,把这几种结果明确区分开来。文中会说明如何用合成夹具来核对这张表,以及这个夹具能证明什么、不能证明什么。本文不涉及任何自动切换提供方的做法,夹具也不会授予任何真实权限。

curl https://gridzen.ai/console/api/quickstart/trial \
  -H 'Content-Type: application/json' \
  -d '{"task": "identity_onboarding", "scenario": "success"}'

接入指南

问题所在,以及由你负责的决策

设想一个卖家入驻服务,必须先拿到身份结果,才能开启付款功能。现在有三次调用以三种不同方式出了问题。第一次调用因为提供方不可用而始终没有完成。第二次调用完成了,提供方返回 Declined。第三次调用请求了该路由并不提供的能力,例如想通过电话检查发送 OTP。如果用同一个处理器把三种情况都映射为拒绝,那么每当提供方宕机,诚实的用户都会被拦下;如果都映射为放行,一次故障就会悄无声息地变成批准。GridZen 的指南对此说得很明确:提供方不可用属于运行故障,而不是低风险信号。当提供方不可用时,当前的 Twilio 适配器会通过 API 返回 503。alpha 版本不会把这种故障静默地转换为放行。你需要决定的是:针对每一种结果,你的工作流下一步该做什么。审核队列、挂起处理,或者经过明确批准的备用方案,都必须由调用方的工作流自行实现。

由调用方持有的决策表(设计建议)

以下内容是建议的应用设计,并非 GridZen 已经实现的行为。表中每一行都应写明结果类别、依据的证据、记录下来的 HTTP 状态,以及下一步动作。技术故障:检查未能完成,例如超时、响应格式错误、缺少凭据或返回 503。这类结果并不构成关于这个人的任何证据。下一步:挂起工作流;仅在上游操作和你的工作流都允许时才进行有限次数的重试,之后转入人工审核。负面证据:提供方已经完成检查,并返回了明确的结论,例如 Declined 或信息不匹配。下一步:按照你的拒绝政策处理,保证记录可以解释清楚,不要为了得到不同的答案而反复重试。证据不足:政策所需的某个信号缺失,例如结果为 unknown。下一步:转入审核,或者交给你现有的流程步骤。不支持的路由:这项能力从一开始就没有向任何提供方请求过。下一步:改用你已为该任务单独授权的其他提供方。HTTP 状态必须与决策结果分开记录。503 没有成功的决策响应,绝不能记录为拒绝或放行。此外,这张表中没有任何一行会自行把请求转交给另一个提供方。只有当某人针对该任务和这批数据明确批准了备用方案时,备用方案才是可以接受的。

假设场景与夹具的预期输出

假设某个团队把这张决策表套用到可下载的四分支电话示例和身份夹具上。这里用的是本地示例,它不同于匿名的三场景 HTTP 试用,两者是不同的东西。电话示例的四个分支可以并排展示各个结果类别。每个分支都会返回 mode synthetic_fixture、otp_sent false 和 live_line_type_available false。normal 分支返回 state simulated、valid true、line_type mobile,以及 next continue_customer_policy。unknown 分支返回 state unknown、valid null、line_type null,以及 next review_or_existing_otp,这属于证据不足。provider_failure 分支返回 state unknown、valid null、line_type null,以及 next bounded_retry_then_review,这属于技术故障。尽管它的 state 字段与 unknown 分支相同,但下一步动作并不一样,因此你的决策表必须依据原因来区分,而不能只看 state 字段。otp 分支返回 state unsupported、valid null,以及 next customer_otp_provider,这属于不支持的路由,而且不会发送任何消息。在身份夹具中,批准之后收到的合成 Declined 更正会返回 status declined、permission_granted false 和 grant_count 1。这是负面证据,应当记录为拒绝,而不是提供方故障。

身份夹具中的故障处理

身份夹具展示了如何避免让一次未完成的检查悄悄演变成某种结论。如果在截止时间之前没有收到任何决策,recover 会在本地把会话标记为已过期。当 deadline 为 60 时,输出为 status expired、permission_granted false、grant_count 0、next review_or_authorized_provider_refresh,以及 provider_polled false。recover 不会轮询任何提供方,它只会把已经超过截止时间、且状态为 pending、review 或 unknown 的会话标记为过期。无法识别的状态会被归为 unknown,而不是 declined。错误类型同样彼此区分:针对未知会话的事件会触发 BINDING_MISMATCH,读取未知会话则会触发 SESSION_NOT_FOUND。夹具事件只接受来源为 fixture 的合成回调。如果 mode 或来源不属于夹具,就会触发 PRODUCTION_SIGNATURE_VERIFIER_NOT_IMPLEMENTED,因为这里并不存在真实的签名验证器。重复事件不会改变计数,grant_count 保持为 1。任何 permission_granted 值都只是夹具在本地的记录,live_permission_changed 始终为 false,它不代表真实的业务权限。

限制:已实现与建议设计的区别

夹具已经实现的内容包括:四个电话分支、SQLite 中的会话状态、本地过期处理、事件去重,以及上文提到的各个错误名称。根据指南,alpha API 已经实现的是:当 Twilio 适配器所依赖的提供方不可用时返回 503。决策表、审核队列、重试预算,以及任何经过批准的备用方案,都属于你自己的设计。GridZen 的 alpha 版本不会转移资金,也不保证下游付款操作的幂等性。当前免费的电话路由不会请求线路类型、号码归属、可达性,也不会发送 OTP。在托管身份入驻方面,新用户完整走完托管流程这一情形仍未经过测试,而且 Approved 并不意味着无条件的权限。实时路由是否可用,需要另行确认。

验收清单

在认定决策表完成之前,请逐项核对以下清单。每一种结果类别都有单独的一行,并且写明了下一步动作。HTTP 状态与决策结果分别存放在不同的字段中。503 或超时绝不会被记录为拒绝或放行。重试次数有上限,并且只在上游操作允许时才进行。没有任何代码路径会自行切换提供方,任何备用方案都经过明确批准。测试覆盖了超时、响应格式错误、缺少凭据、提供方拒绝以及恢复这几种情况,并且结果与上文所述的夹具输出一致。已过期的会话显示 provider_polled false,并转入审核。合成权限绝不会与真实权限挂钩。每当启用新的提供方或新的政策时,都要重新审查同样的用例。等这些项目在本地全部通过后,再判断保存一个沙盒请求是否适合你的任务。

运行已检查的模拟示例

下载并解压 https://gridzen.ai/downloads/verification-delivery.zip,进入 verification_delivery,用 Python 3.10+ 运行。此本地示例不联网;独立身份实验请使用新的数据库。

python3 delivery.py identity --db /tmp/gridzen-article-fixture.sqlite

来源与范围

https://gridzen.ai/guides/provider-failures/ https://gridzen.ai/guides/current-capabilities/ 依据已检查的来源快照与本地模拟;建议的业务规则属于设计建议,不代表已证明的生产行为。内容使用 AI 辅助写作,并经过独立审稿。

另行体验三种沙盒结果 创建账号,继续项目接入

下载不等于运行成功;本地示例与在线沙盒分别测试。

接入你的应用

运行三种模拟结果 · 需要接入帮助

连接免费沙盒账号

号码基础有效性不证明持有权或送达,不提供短信验证码。业务放行由你的系统判断。