Skip to main content
x402 是基于 HTTP 402 状态码的开放支付协议:服务端对未付费的请求返回 402 challenge,付款方(通常是 AI Agent)用链上稳定币授权签名重试请求,完成支付后获得资源。Waffo 把 x402 封装为标准收单能力——订单、Webhook、对账与你现有的 Waffo 集成完全一致,链上校验与结算由 Waffo 完成。 本页面向两类读者:商户开发者(选择集成模式、调用 Waffo API、判定资源放行)为主;AI Agent 开发者可重点阅读 402 challenge 结构与 PAYMENT-SIGNATURE 提交方式,Agent 侧交互不需要商户 API Key。

两种集成模式

模式一:商户自持 402

你的服务端自己充当 x402 server:向 Agent 返回 402 challenge、接收签名,再通过 order/create 把签名转交 Waffo 结算。适合希望 Agent 全程停留在自己 API 上、愿意实现 x402 协议细节的商户。

模式二:Waffo 托管 402

你只创建订单,把 Waffo 返回的托管地址交给 Agent;402 challenge、签名接收与结算全部由 Waffo 收银台完成。适合不想实现 x402 协议细节、快速上线的商户。
两种模式共用同一个 order/create 接口,区分方式只有一个:请求的 x402Info带不带 paymentSignatureHeader——带签名走模式一,不带走模式二。

前提条件

x402 收单需要先通过 Waffo 对接团队完成两项开通:
  1. 商户合同开通 CRYPTO / USDC 支付产品
  2. Waffo 侧配置你的链上收款参数
未完成配置时,wallet/inquiryorder/create 返回错误码 A0010(商户合同不允许此操作)。

当前支持范围

以下是当前版本的硬性边界,请按此开发,不要预设其他能力:
  • 币种:仅 USDCorderCurrency 必须为 USDC(同币种收付,不涉及换汇)
  • 网络:仅 Base(生产为 eip155:8453;沙箱为 Base Sepolia eip155:84532
  • scheme:仅 exact(按 challenge 中的金额精确结算)
  • 授权次数:EIP-3009 授权在链上单次消费——一个签名只能结算一次,不支持「一次授权、多次扣款」
  • 幂等paymentRequestId 必填;同一单重复 order/create 会返回已有订单的真实状态,不会重复结算(参见幂等机制

获取链上收款参数

模式一构造 402 challenge 前,先调用 POST /api/v1/wallet/inquiry 获取收款参数。该接口只做查询:不创建订单、不校验金额。
三个字段都来自 Waffo 配置,请原样用于构造 challenge:payTo 不能替换为你自己的钱包地址,Agent 签名中的收款地址与金额会在结算前被链上校验。

模式一:商户自持 402

你需要做四件事:
  1. wallet/inquirynetwork / asset / payTo,按定价构造 402 challenge(金额用原子单位,scheme 固定 exact)返回给 Agent
  2. 从 Agent 的重试请求头 PAYMENT-SIGNATURE 中取出签名,原样放入 order/createx402Info.paymentSignatureHeader(不要解码后重新组装)
  3. 按同步响应的 orderStatus 决定放行:PAY_SUCCESS 放行,PAY_IN_PROGRESSWebhookorder/inquiry 终态,ORDER_CLOSE 拒绝
  4. 放行时把响应中的 x402Info.x402Response 作为 PAYMENT-RESPONSE 头返回给 Agent,作为符合 x402 协议的结算回执
其余必填字段(goodsInfoorderRequestedAt 等)与普通一次性支付建单一致,以 API Reference 为准。 paymentSignatureHeader 是 base64 编码的 x402 PaymentPayload,解码后结构如下(由 Agent 侧 x402 SDK 生成,商户无需构造):
签名中 authorization.to 必须等于 wallet/inquiry 返回的 payToauthorization.value 必须等于 orderAmount 的原子单位表示(换算规则见下文「金额与小数位」)。任一不一致都会在结算前校验失败,订单进入 ORDER_CLOSE。因此你在 402 challenge 中给 Agent 的定价必须与 order/createorderAmount 一致。
x402Response 是 base64 编码的结算回执(x402 SettlementResponse),仅在 orderStatus = PAY_SUCCESS 时返回,解码后:
transaction 是链上交易 hash,可用于对账与链上核验;payer 是 Agent 的付款钱包地址。

模式二:Waffo 托管 402

你需要做三件事:
  1. order/createx402Info: { "x402Request": true }(不带签名),并带上 successRedirectUrl / failedRedirectUrl
  2. 解析响应中的 orderAction(JSON 字符串)取出 webUrl,将 Agent 302 重定向过去;之后的 402 challenge、签名接收、结算全部发生在 Waffo 收银台
  3. Webhookorder/inquiry 返回的 orderStatus 为准放行资源
Agent 访问 webUrl 收到 HTTP 402,challenge 在响应体中(x402 协议规定 challenge 位于 body,没有专门的响应头):
Agent 签名后,用与首次访问相同的 HTTP 方法重试同一 URL,把签名放在 PAYMENT-SIGNATURE 请求头(对应 x402 规范中的 X-PAYMENT),无需任何商户凭证:
结算完成后收银台以 302 将 Agent 带回你的 successRedirectUrlfailedRedirectUrl。该托管地址同时兼容浏览器访问(渲染收银台页面)与 x402 client 访问(返回协议响应)。
302 回跳只用于流程衔接,不是支付凭证。判定「已支付」只能依据 Webhook 通知或 order/inquiry 查询到的 orderStatus = PAY_SUCCESS——回跳可能伪造、可能丢失,且回跳时结算可能尚未落定。
支付成功后,Webhook 通知与 order/inquiry 响应会附带 x402Info.x402Response(字段结构与模式一相同),其余通知结构与普通订单一致,参见 Webhook 事件类型

模式对比

订单状态语义(PAY_IN_PROGRESSAUTHORIZATION_REQUIRED 等)与其他支付方式一致,参见支付生命周期

金额与小数位(两层单位)

同一笔交易中的金额有两层表示,不要混用: 换算规则:原子单位 = 金额 × 106币种与金额中 USDC 的 2 位小数指 Waffo API 层的 orderAmount;402 challenge 与 EIP-3009 签名中的金额始终是原子单位。模式一中两层金额必须对应同一数值,否则结算校验失败。

错误码

x402 复用 Waffo 既有对外错误码,msg 会说明具体原因: 完整错误码列表见错误码参考

常见问题

沙箱走 Base Sepolia 测试网(eip155:84532),USDC 合约地址为 0x036CbD53842c5426634e7929541eC2318f3dCF7e;生产走 Base 主网(eip155:8453),USDC 合约地址为 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913。两个环境的 network / asset / payTo 都以 wallet/inquiry 实际返回为准。
当前仅支持 USDC + Base 网络,orderCurrency 传其他币种会返回 A0007
不可以。x402 的 exact scheme 基于 EIP-3009 transferWithAuthorization,其 nonce 在 USDC 合约侧单次消费:签名一旦结算即作废,再次提交会在链上直接失败。订阅式、按量多次扣款不属于 x402 能力范围。
不可以。PAY_IN_PROGRESS 只表示链上处理中,最终可能成功也可能失败。只有 orderStatus = PAY_SUCCESS 才能放行资源,终态通过 Webhook 或 order/inquiry 收敛。
在响应体(JSON body)里,没有携带 challenge 的响应头。x402 交互中唯一的协议请求头是 Agent 提交签名用的 PAYMENT-SIGNATURE(对应 x402 规范的 X-PAYMENT);结算回执通过 x402Info.x402Response 字段返回,对应规范的 X-PAYMENT-RESPONSE
不是。AI 集成工具是用 AI 编码工具帮你生成 Waffo SDK 集成代码;本页是 AI Agent 作为付款方用稳定币购买你的服务。两者可以同时使用,但解决的问题不同。

延伸阅读