x402付款请求反复循环:支付凭证为何未被接受

 / 
2

签名过期了,再签多少次都没用。你的代理在循环,是因为每次重试都在重复使用同一张过期的"支票"。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

这种"扣款成功但凭证不被接受"的循环,通常卡在三个地方。我们按顺序来查,找到卡住的那个环节。

步骤 1:确认授权是否"时间已过"

这是最常见的循环陷阱。你签名的授权里有 validBefore 字段,代表它过期的精确时间。一旦超时,结算商直接拒收,不管钱包里有多少钱。

[做什么] 检查你提交的支付凭证(PAYMENT-SIGNATURE 头)里的 validBefore 时间戳,看看是不是已经过了当前时间。

[怎么做]

  • 如果你在用 x402trace 这个诊断工具,可以直接运行: x402trace explain ./x402trace.jsonl 如果看到类似 validBefore expired 97s ago 的输出,就是这个问题。它会直接告诉你过期了多久,并给出修复建议:re-sign the authorization with a later validBefore (typical: now + 300s)

  • 如果你没用 x402trace,就去查代理发出请求的日志,找出提交给结算商的完整授权 JSON,看里面的 validBefore 字段,手动对比一下当前时间。

[完成标准] validBefore 时间戳在未来,且至少有几分钟的余量。

步骤 2:确认凭证格式是否被服务端接受

你的重试循环还有一种可能:凭证里的某些字段格式不符合服务端要求,导致每次重试都被当成无效请求。

[做什么] 检查提交的支付凭证里的网络标识和金额格式。

[怎么做]

  • 使用 three.ws 这类免费诊断工具来模拟验证。你可以把失败的授权请求体发给它的 /api/x402/debug 端点,它会返回结构化的错误诊断。比如它会告诉你:

    • 你提交的是 x402Version: 1,但服务器要求的是 Version 2

    • 你把 network 写成了 "base",但服务器要求的是标准 CAIP-2 格式 "eip155:8453"

    • 你把金额写成了 "0.01",但协议要求的是原子单位的整数字符串 "10000"

[完成标准] 诊断工具返回 verdict: valid,说明凭证格式本身是服务端能接受的。

情况分支:凭证有效,但服务端不认收款方

凭证本身有效,但服务端在做最终校验时发现你和它预期的不匹配。

情况 A:收款方地址(payTo)不对

  • 表现:凭证里的 recipient 和服务器要求支付的 payTo 不一致。

  • 解决办法:确认你是在向服务端 402 响应里指定的 payTo 地址签名,而不是某个其他地址。

情况 B:你用了过时的 header 名称

  • 表现:服务端返回了 402,但你的客户端找不到支付所需的 x-payment-required 头。

  • 原因:你还在用 x402 v1 的 header 名称 x-payment-required,但服务端遵循的是 v2 标准,返回的是 payment-required

  • 解决办法:检查你的客户端代码,把读取的 header 名称改成 payment-required

高危提醒:重试循环真能烧光预算。 如果服务端对无效凭证也返回 402,你的代理会不断重复"收到 402 → 签名 → 重试"的循环。有团队的生产系统在 11 天内因这种循环损失了 47,000 美元。每轮循环都在花钱验证,而钱不会自己回来。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

验证收尾

完成上述检查和修复后,跑一次完整的单次支付测试。

核验渠道: 让代理在调试模式下执行一次付费请求。观察日志,应该看到:

  1. 首次请求收到 402 Payment Required

  2. 代理生成一个新签名(注意 validBefore 是未来的时间)。

  3. 重试请求带着 PAYMENT-SIGNATURE 头发出。

  4. 最终收到 200 OK 和想要的数据,而不是又一个 402