签名过期了,再签多少次都没用。你的代理在循环,是因为每次重试都在重复使用同一张过期的"支票"。
这种"扣款成功但凭证不被接受"的循环,通常卡在三个地方。我们按顺序来查,找到卡住的那个环节。
步骤 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 美元。每轮循环都在花钱验证,而钱不会自己回来。
验证收尾
完成上述检查和修复后,跑一次完整的单次支付测试。
核验渠道: 让代理在调试模式下执行一次付费请求。观察日志,应该看到:
首次请求收到
402 Payment Required。代理生成一个新签名(注意
validBefore是未来的时间)。重试请求带着
PAYMENT-SIGNATURE头发出。最终收到
200 OK和想要的数据,而不是又一个402。



