跳转到主要内容
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 获取收款参数。该接口只做查询:不创建订单、不校验金额。
curl -X POST https://api-sandbox.waffo.com/api/v1/wallet/inquiry \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-SIGNATURE: YOUR_RSA_SIGNATURE" \
  -d '{
    "paymentRequestId": "x402-order-10001",
    "merchantInfo": { "merchantId": "M000001" },
    "orderCurrency": "USDC"
  }'
{
  "code": "0",
  "msg": "Success",
  "data": {
    "network": "eip155:84532",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "payTo": "0xc15Ea3D0b7A29c41F8b26aD5c30F49E20e510e71"
  }
}
字段说明
networkCAIP-2 网络标识。沙箱返回 Base Sepolia eip155:84532,生产返回 Base 主网 eip155:8453
assetUSDC 代币合约地址(随环境与网络变化,生产 Base 主网为 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
payToWaffo 平台收款地址。Waffo 链上收款后按合同结算给你
三个字段都来自 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 协议的结算回执
curl -X POST https://api-sandbox.waffo.com/api/v1/order/create \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-SIGNATURE: YOUR_RSA_SIGNATURE" \
  -d '{
    "paymentRequestId": "x402-order-10001",
    "merchantOrderId": "x402-order-10001",
    "orderCurrency": "USDC",
    "orderAmount": "9.99",
    "orderDescription": "API usage credits",
    "notifyUrl": "https://merchant.example.com/webhook/waffo",
    "merchantInfo": { "merchantId": "M000001" },
    "userInfo": { "userId": "agent_7f3e", "userTerminal": "WEB" },
    "paymentInfo": { "productName": "ONE_TIME_PAYMENT", "payMethodName": "USDC" },
    "x402Info": {
      "x402Request": true,
      "paymentSignatureHeader": "eyJ4NDAyVmVyc2lvbiI6Miwic2NoZW1lIjoiZXhhY3QiLC4uLn0="
    }
  }'
{
  "code": "0",
  "msg": "Success",
  "data": {
    "paymentRequestId": "x402-order-10001",
    "merchantOrderId": "x402-order-10001",
    "acquiringOrderId": "A202607060001",
    "orderStatus": "PAY_SUCCESS",
    "x402Info": {
      "x402Request": true,
      "paymentSignatureHeader": "eyJ4NDAyVmVyc2lvbiI6Miwic2NoZW1lIjoiZXhhY3QiLC4uLn0=",
      "x402Response": "eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4Li4uIn0="
    }
  }
}
其余必填字段(goodsInfoorderRequestedAt 等)与普通一次性支付建单一致,以 API Reference 为准。 paymentSignatureHeader 是 base64 编码的 x402 PaymentPayload,解码后结构如下(由 Agent 侧 x402 SDK 生成,商户无需构造):
{
  "x402Version": 2,
  "scheme": "exact",
  "network": "eip155:84532",
  "payload": {
    "signature": "0x<65 字节 EIP-712 签名>",
    "authorization": {
      "from": "0x<Agent 钱包地址>",
      "to": "0xc15Ea3D0b7A29c41F8b26aD5c30F49E20e510e71",
      "value": "9990000",
      "validAfter": "0",
      "validBefore": "1783340000",
      "nonce": "0x<32 字节随机数(防重放,非递增)>"
    }
  }
}
签名中 authorization.to 必须等于 wallet/inquiry 返回的 payToauthorization.value 必须等于 orderAmount 的原子单位表示(换算规则见下文「金额与小数位」)。任一不一致都会在结算前校验失败,订单进入 ORDER_CLOSE。因此你在 402 challenge 中给 Agent 的定价必须与 order/createorderAmount 一致。
x402Response 是 base64 编码的结算回执(x402 SettlementResponse),仅在 orderStatus = PAY_SUCCESS 时返回,解码后:
{
  "success": true,
  "transaction": "0x8f4e2b7c9d1a4f6e8b3c5d7a9e1f2b4c6d8e0a2c4e6f8a0b2c4d6e8f0a1b3c5d",
  "network": "eip155:84532",
  "payer": "0x51E2aF03D0A5c3C7dF83Db9F4b0a2E51D8c19aC3"
}
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 为准放行资源
curl -X POST https://api-sandbox.waffo.com/api/v1/order/create \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "X-SIGNATURE: YOUR_RSA_SIGNATURE" \
  -d '{
    "paymentRequestId": "x402-order-10002",
    "merchantOrderId": "x402-order-10002",
    "orderCurrency": "USDC",
    "orderAmount": "9.99",
    "orderDescription": "API usage credits",
    "notifyUrl": "https://merchant.example.com/webhook/waffo",
    "successRedirectUrl": "https://merchant.example.com/x402/return",
    "failedRedirectUrl": "https://merchant.example.com/x402/failed",
    "merchantInfo": { "merchantId": "M000001" },
    "userInfo": { "userId": "agent_7f3e", "userTerminal": "WEB" },
    "paymentInfo": { "productName": "ONE_TIME_PAYMENT", "payMethodName": "USDC" },
    "x402Info": { "x402Request": true }
  }'
{
  "code": "0",
  "msg": "Success",
  "data": {
    "paymentRequestId": "x402-order-10002",
    "merchantOrderId": "x402-order-10002",
    "acquiringOrderId": "A202607060002",
    "orderStatus": "AUTHORIZATION_REQUIRED",
    "orderAction": "{\"actionType\":\"WEB\",\"webUrl\":\"https://cashier.waffo.com/cashier/api/v1/x402/7sKq9WfR2mXt\"}"
  }
}
Agent 访问 webUrl 收到 HTTP 402,challenge 在响应体中(x402 协议规定 challenge 位于 body,没有专门的响应头):
{
  "x402Version": 2,
  "error": "PAYMENT-SIGNATURE header is required",
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:84532",
      "maxAmountRequired": "9990000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0xc15Ea3D0b7A29c41F8b26aD5c30F49E20e510e71",
      "maxTimeoutSeconds": 600,
      "extra": { "name": "USDC", "version": "2" }
    }
  ]
}
Agent 签名后,用与首次访问相同的 HTTP 方法重试同一 URL,把签名放在 PAYMENT-SIGNATURE 请求头(对应 x402 规范中的 X-PAYMENT),无需任何商户凭证:
curl "https://cashier.waffo.com/cashier/api/v1/x402/7sKq9WfR2mXt" \
  -H "PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Miwic2NoZW1lIjoiZXhhY3QiLC4uLn0="
结算完成后收银台以 302 将 Agent 带回你的 successRedirectUrlfailedRedirectUrl。该托管地址同时兼容浏览器访问(渲染收银台页面)与 x402 client 访问(返回协议响应)。
302 回跳只用于流程衔接,不是支付凭证。判定「已支付」只能依据 Webhook 通知或 order/inquiry 查询到的 orderStatus = PAY_SUCCESS——回跳可能伪造、可能丢失,且回跳时结算可能尚未落定。
支付成功后,Webhook 通知与 order/inquiry 响应会附带 x402Info.x402Response(字段结构与模式一相同),其余通知结构与普通订单一致,参见 Webhook 事件类型

模式对比

维度模式一:商户自持 402模式二:Waffo 托管 402
谁充当 x402 server(发 402、收签名)商户服务端Waffo 收银台
是否需要实现 x402 协议细节是(构造 challenge、解析签名头)
order/create 是否带签名带(x402Info.paymentSignatureHeader不带
建单响应直接返回终态或 PAY_IN_PROGRESSAUTHORIZATION_REQUIRED + 托管地址
跳转无(Agent 全程请求商户 API)商户 302 → 收银台 302 回跳
资源放行依据同步响应 / Webhook / inquiry 的 orderStatusWebhook / inquiry 的 orderStatus
适合自建 x402 服务、深度定制的商户快速上线、不碰协议细节的商户
订单状态语义(PAY_IN_PROGRESSAUTHORIZATION_REQUIRED 等)与其他支付方式一致,参见支付生命周期

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

同一笔交易中的金额有两层表示,不要混用:
字段表示方式示例(9.99 USDC)
Waffo API 层orderAmountString,最多 2 位小数"9.99"
链上 / x402 协议层valuemaxAmountRequiredString,原子单位整数(USDC 链上精度 6 位)"9990000"
换算规则:原子单位 = 金额 × 106币种与金额中 USDC 的 2 位小数指 Waffo API 层的 orderAmount;402 challenge 与 EIP-3009 签名中的金额始终是原子单位。模式一中两层金额必须对应同一数值,否则结算校验失败。

错误码

x402 复用 Waffo 既有对外错误码,msg 会说明具体原因:
错误码含义x402 场景下的常见触发
A0003参数校验失败challenge / 签名的 scheme 不是 exact;缺少 paymentRequestId
A0007不支持的交易币种orderCurrency 不是 USDC,或商户没有可用的同币种 USDC 合同
A0010商户合同不允许此操作未开通 CRYPTO/USDC 支付产品,或链上收款参数未配置
完整错误码列表见错误码参考

常见问题

沙箱走 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 作为付款方用稳定币购买你的服务。两者可以同时使用,但解决的问题不同。

延伸阅读