本文介绍推荐的 x402 V2 商户接入流程。B402 只能由可信服务端调用,并且 API Key 必须属于已完成 B402 开通的同一个 Developer Portal Project。
Portal 开通与运行时 API
Developer Portal 和 B402 运行时 API 用途不同:
| 阶段 | 操作位置 | 使用方式 |
|---|---|---|
| 开通 | Developer Portal | 选择 Project、完成 B402 Payments 申请,并配置设置后不可修改的 payTo 地址。 |
| Key 配置 | Developer Portal | 在同一个 Project 下创建包含 B402 Payments 权限的 API Key;如启用 IP 白名单,请加入商户服务端的公网出口 IP。 |
| 运行时 | 商户服务端 | 使用 API Key 和 Secret Key 签名调用 https://web3.binance.com/build/api/v2/b402/*。 |
不要把 Portal 的 Onboarding 请求复制到商户服务端。Public 运行时请求不能传
apiKey 或 projectCode Query 参数、merchantId、X-OC-Tenant-Id 或
X-OC-User-Id。Web3 Gateway 会根据已鉴权的 API Key 自动解析 Project 和
Account Identity。
1. 创建并配置包含 B402 权限的 API Key
请在已完成 B402 开通的同一个 Developer Portal Project 中操作:
- 打开 API 密钥管理,点击添加新密钥。
- 输入 Key Name,并在 API 权限步骤中勾选 B402 Payments 后再创建。未勾选该权限的 API Key 无法调用任何 B402 接口。
- 如配置 IP 白名单,请加入实际调用 B402 的商户服务端稳定公网出口 IP,不要填写内网、Localhost 或终端用户 IP。
- 创建成功后,将页面显示的两个值立即保存到商户服务端的 Secret Manager。Secret Key 只展示一次;如果丢失,需要重新创建或轮换 API Key。
| Portal 显示值 | 建议的服务端配置 | B402 使用方式 |
|---|---|---|
| API Key | OC_API_KEY | 作为 X-OC-APIKEY 请求头发送。 |
| Secret Key | OC_SECRET_KEY | 仅作为 HMAC-SHA256 签名密钥,不能放在 URL、Header 或 Body 中发送。 |
| Project | 无需请求配置 | Web3 Gateway 根据 API Key 自动解析,不能传 projectCode。 |
payTo | 业务配置 | 在返回给买方的 HTTP 402 Payment Requirements 中使用开通时锁定的地址。 |
这些凭证只能保存在可信服务端。不要在浏览器或移动端代码中使用 Secret Key,也不要提交到 Git 或粘贴到客户端请求中。
Web3 请求鉴权
每个 B402 请求都使用标准 Binance Web3 HMAC 请求头:
X-OC-APIKEYX-OC-TIMESTAMPX-OC-SIGN- 可选:
X-OC-RECV-WINDOW和X-OC-NONCE
请严格按照鉴权说明生成签名。签名路径必须包含
/build,签名使用的 JSON 字符串必须与实际发送的原始 Body 完全一致。
B402 使用外层请求信封。签名并发送 {"body": ...},不能只发送内部 x402 对象。签名后重新
序列化 JSON 会改变请求字节,导致签名失败。
Web3 Gateway 会根据已鉴权 Project 的 Tenant
Identity 解析 B402 商户。Portal 流量不要传入或信任客户端提供的 merchantId。
2. 使用 Supported 验证 API Key
下面的 Node.js 18+ 示例只需要通过本地或部署环境的 Secret 配置提供 OC_API_KEY 和 OC_SECRET_KEY
即可运行。不要修改 Host,也不要从 requestPath 中删除 /build:
Code
Helper 接收属于 body 内部的对象,并只创建一次外层 {"body": ...} Envelope。签名和发送使用同一个
rawBody 字符串。Verify 和 Settle 可以复用该 Helper:
Code
permit2-upto 还需要在上述 Settle 内层对象中加入 settleAmount。
获取并缓存 Supported 配置
服务启动时调用 POST /api/v2/b402/supported,之后定期刷新。空请求为:
Code
响应包含 kinds[]、extensions 和 signers。选择与目标资产和转账方式匹配的 Kind,并将对应
kinds[].extra 完整复制到返回给买方的 paymentRequirements.extra。
请把首次 Supported 调用作为接入就绪检查:
- 成功响应的 Envelope Code 为
000000000。 1160401表示同一个 Developer Portal Project 尚未完成 B402 开通。- Gateway Code
40104表示请求被访问策略拒绝。请先检查 B402 Payments 权限和 API Key IP 白名单;如果两项都正确,请联系支持人员检查 Endpoint Allowlist。
不要硬编码 signerAddress、spenderAddress、EIP-712 name 或
version。Facilitator 配置或 Permit2 Proxy 升级时这些值可能变化。
3. 向买方返回 HTTP 402
需要支付时,返回类似以下 x402 V2 响应:
Code
金额使用 Token 最小单位的十进制字符串。payTo 必须是 B402 开通时配置的收款地址。
4. 接收买方签名 Payload
买方选择一个支付要求并签名,然后携带 x402 Payment
Payload 重新请求资源。商户必须在服务端保存原始 Payment
Requirements,不能允许买方替换金额、资产、网络、payTo、超时时间或 extra。
商户服务端必须拒绝 paymentPayload.accepted 与服务端保存的 paymentRequirements
不完全一致的买方 Payload,然后将这两个对象原样发送给 B402。不同转账方式的签名数据位于
paymentPayload.payload:
eip3009使用authorization。permit2-exact和permit2-upto使用permit2Authorization。
5. 结算前 Verify
将买方 Payload 和服务端保存的原始 Requirements 发送到
POST /api/v2/b402/verify。请求示例如下,完整字段说明请查看 REST API Reference:
Code
Verify 是链下操作,不会花费资金。只有 data.isValid 为 true 时才继续。业务验证失败仍然返回 HTTP
200,因此不能只判断 HTTP Status;还要检查 data.isValid、data.invalidReason 和可选的
data.invalidMessage。
6. Settle 支付
使用相同 Body 调用 POST /api/v2/b402/settle。permit2-upto 还需要传入
body.settleAmount,且不能超过 paymentRequirements.amount 授权上限。
Settle 会提交不可逆的链上交易。仅当 data.success 为 true 时视为成功。
success: true:记录transaction、payer、network和amount,然后交付资源。success: false且transaction非空:交易已广播,需要先查询或对账再决定是否重试。success: false且transaction为空:广播前终态失败,根据errorReason处理。
同一个签名授权的 Settle 具备幂等性。临时故障可以有限重试并使用退避,但不要自动创建新的买方授权。
运维建议
- 保持服务器时钟同步,过期 Timestamp 会被拒绝。
- 使用签名授权或交易 Hash 作为幂等键持久化结算结果。
- 记录 Request ID 和交易 Hash,但不要记录签名、API Secret 或完整授权 Payload。
- 对
invalidReason、errorReason、HTTP 429 和基础设施错误配置监控。 - 每笔支付都先 Verify,不要只根据买方提交的签名交付资源。