常见问题
结算状态未知时应该怎么办?
付费请求超时或结算证据不可靠时,对账原 Agent 支付 Intent,同时避免重复付款。
停止付款重试,核对原 Intent。settlement_unknown 表示一笔已经授权的付款可能到达了 x402 结算服务,但当前响应和链上证据还不足以确认它是否已经结算。
它不表示“尚未付款”,更不允许创建替代 Intent、授权、幂等键或随机数。
何时会进入该状态
控制面签发授权后,客户签名器生成准确的付款签名,Agent SDK 再发送付费请求。以下情况可能导致结算状态未知:
- 付费请求离开 Agent 运行时后超时;
- 连接在可靠响应返回前关闭;
- 资源响应缺少结算证据,或包含无法解析的结算证据;
- 结算服务、资源服务器、RPC 服务或链暂时提供不完整或互相冲突的证据。
此时付款可能已经成功,但 Agent 没有收到资源响应。
恢复步骤
- 保存
SettlementUnknownError中的intentId和authorizationId。 - 停止该业务购买的自动付款重试,不要轮换幂等键。
- 使用
agent.getPayment(intentId)或management.payments.get(intentId)查询原 Intent。 - 订阅签名的
agent_payment.settlement.*和agent_payment.resource.*Webhook,并按事件 ID 去重。 - 在原 Intent 得到明确结果前,让业务任务保持待处理或对账状态。
- 状态超过运营时限仍然未知时,应升级人工调查,不能把告警转成自动重付。
Agent SDK 会通过错误对象提供关联标识:
import { SettlementUnknownError } from '@stableops/agent-sdk'
try {
await agent.x402Fetch(resourceUrl, {
idempotencyKey: 'research-task-284:market-report:v1',
})
} catch (error) {
if (error instanceof SettlementUnknownError) {
await saveForReconciliation({
intentId: error.intentId,
authorizationId: error.authorizationId,
})
const payment = await agent.getPayment(error.intentId)
console.error({
intentId: payment.intentId,
paymentStatus: payment.status,
resourceStatus: payment.resourceStatus,
})
}
throw error
}查询记录是安全的。换一个幂等键调用 x402Fetch 发起新购买则不安全。
状态如何得到最终结果
| 最终证据 | 支付结果 | 应用应该怎么做 |
|---|---|---|
| 授权随机数已经使用,匹配转账得到确认 | settled | 只记录一次付款;另外检查资源状态,再判断业务任务是否完成 |
| 对账证明结算已经回滚 | reverted | 记录付款失败;任何新购买都必须经过明确的运营或业务决定 |
| 执行授权和付款授权均已过期,随机数未使用,充分扫描后没有匹配转账 | expired | 可以释放已经提交的预算;后续购买必须作为新的明确尝试 |
| 链或服务商证据仍不可用 | settlement_unknown | 继续对账,并保持预算已提交状态 |
StableOps 不会仅因墙上时钟超时就释放已经提交的预算。系统必须先确认授权已经过期且未使用,也不存在待确认的匹配转账。这条保守规则可以避免第一笔付款仍可能结算时,同一笔资金又被计为可用。
支付结果与资源结果彼此独立
即使支付结算已经明确,资源结果仍可能是 unknown 或 failed:
settled加response_received表示付款和付费 HTTP 交换都有可靠证据。settled加unknown表示资金已经转移,但 Agent 可能没有收到资源。- StableOps 确认链上状态为
settled前,资源响应也可能已经返回。
资源交付问题应通过卖方的重放、支持或业务补偿流程解决。绝不能把资源缺失解释为付款没有发生。
相关内容
这篇文档怎么样?
最后更新