开发者平台
主题

HTTP 端 API - 单次支付#

本文档是单次支付的 API 参考,涵盖 exactuptocharge 三种 scheme 的完整接口定义。使用指南与 SDK 接入示例请参阅 单次支付 · 接入文档

选 scheme#

exact 单收款方,同步 / 异步结算都支持,资产转移方式可选 EIP-3009(仅支持原生实现该接口的代币,如 USDC)或 Permit2(兼容所有 ERC-20)。

upto 按上限授权 + 按实际用量结算,适用于 AI Agent 按次计费 / 流式服务计量 / 试用转付费等场景。底层强制走 Permit2,并同时接受外部 EOA 钱包(secp256k1)与 OKX agentic wallet(Ed25519 session key)两类签名。

charge 除了单收款方,还支持分账(Split),即单次支付多地址收款(≤10),默认且只支持同步结算。

维度exact (EIP-3009)exact (Permit2)uptocharge
收款方单收款方单收款方单收款方单 / 分账 ≤10
结算时序同步 / 异步均可同步 / 异步均可异步(默认 pending)同步
资产转移EIP-3009 transferWithAuthorizationPermit2 canonical → x402ExactPermit2ProxyPermit2 canonical → x402UptoPermit2ProxyEIP-3009
代币兼容性仅 EIP-3009 token所有 ERC-20所有 ERC-20仅 EIP-3009 token
金额语义签名 = 实付签名 = 实付签名 = 上限,实付 ≤ 上限签名 = 实付
接入指南exact 路径exact 路径upto 路径charge 路径
  • Base URL:https://web3.okx.com
  • exact / upto 路径前缀:/api/v6/pay/x402(共用 verify / settle / supported / settle/status 四个 endpoint,由 payload 内容自动路由)
  • charge 路径前缀:/api/v6/pay/mpp/charge
  • Network:X Layer(chainId 196,CAIP-2 标识 eip155:196

认证#

所有接口均需通过 API Key 认证,请求头中携带以下字段:

Header必传描述
OK-ACCESS-KEYAPI Key
OK-ACCESS-SIGN请求签名
OK-ACCESS-PASSPHRASEAPI 密码短语
OK-ACCESS-TIMESTAMPISO 8601 时间戳
Content-TypePOST 请求需设为 application/json

所有响应统一使用业务包络:

json
{
  "code": "0",
  "msg": "success",
  "data": { /* 业务字段 */ }
}

业务错误时 code 为非 "0"datanull,错误码集中见文末 错误码 章节。


exact Scheme#

exact 同时支持两种资产转移方式,由 accepted.extra.assetTransferMethod 和 payload 字段决定:

  • EIP-3009 路径:填 payload.authorizationaccepted.extra 不带或带 assetTransferMethod=eip3009
  • Permit2 路径:填 payload.permit2Authorizationaccepted.extra.assetTransferMethod="permit2"paymentRequirements.extra 同步

两路径互斥,payload.authorizationpayload.permit2Authorization 必须严格二选一。

1. /api/v6/pay/x402/supported#

GET
/api/v6/pay/x402/supported

查询 Broker 支持的 scheme、network 及签名者列表。Seller SDK 调用此接口构建 402 响应的 accepts 数组。kinds 数组按 Apollo 灰度开关动态输出。

请求参数#

无。

响应参数#

参数类型描述
kindsArray<SupportedKind>支持的支付类型列表
kinds[].x402VersionInteger协议版本,如 2
kinds[].schemeString结算方案:exact / aggr_deferred / upto
kinds[].networkStringCAIP-2 链标识,如 eip155:196
kinds[].extraObjectscheme 特有扩展配置,见下表
extensionsArray<String>支持的扩展标识列表
signersObjectCAIP-2 通配符 → 签名者地址数组映射

kinds[].extra 子字段:

子字段适用 scheme描述
assetTransferMethodexact / upto"permit2" 表示走 Permit2 canonical + Proxy 合约结算;exact 在缺省时即原生 EIP-3009
facilitatorAddressuptofacilitator EOA 地址,buyer 必须在 witness.facilitator 填同一地址
signatureSchemesupto当前 facilitator 支持的签名算法列表,开关关闭时仅 ["ed25519"],EOA 灰度开启后追加 "secp256k1"

请求示例#

bash
curl --location --request GET 'https://web3.okx.com/api/v6/pay/x402/supported' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z'

响应示例#

json
{
  "code": "0",
  "msg": "",
  "data": {
    "kinds": [
      { "x402Version": 2, "scheme": "exact",         "network": "eip155:196" },
      { "x402Version": 2, "scheme": "exact",         "network": "eip155:196",
        "extra": { "assetTransferMethod": "permit2" } },
      { "x402Version": 2, "scheme": "aggr_deferred", "network": "eip155:196" },
      { "x402Version": 2, "scheme": "upto",          "network": "eip155:196",
        "extra": {
          "assetTransferMethod": "permit2",
          "facilitatorAddress": "0xFacilitatorEOA...",
          "signatureSchemes": ["ed25519", "secp256k1"]
        } }
    ],
    "extensions": [],
    "signers": {}
  }
}

2. /api/v6/pay/x402/verify#

POST
/api/v6/pay/x402/verify

校验 Buyer 签名的支付授权有效性,不执行链上交易

请求参数#

参数类型必传描述
x402VersionInteger协议版本,如 2
paymentPayloadObject客户端随受保护请求携带的支付载荷,详见 PaymentPayload
paymentRequirementsObjectSeller 定义的支付要求,详见 PaymentRequirements

约束:

  • paymentPayload.accepted.scheme 必须与 paymentRequirements.scheme 一致,取值 "exact""upto"
  • paymentPayload.payload.authorizationpaymentPayload.payload.permit2Authorization 必须严格二选一
    • exact + EIP-3009:填 authorization
    • exact + Permit2:填 permit2Authorization,且 accepted.scheme="exact"
    • upto:填 permit2Authorization,且 accepted.scheme="upto"witness.facilitator 必填

响应参数#

参数类型描述
isValidBooleantrue 验证通过,false 验证失败
invalidReasonString机器可读的无效原因(验证失败时返回)
invalidMessageString人类可读的无效说明(验证失败时返回)
payerString付款方钱包地址

请求示例 — exact + EIP-3009#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/x402/verify' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "x402Version": 2,
  "paymentPayload": {
    "x402Version": 2,
    "resource": {
      "url": "https://api.example.com/premium-data",
      "description": "Access to premium data",
      "mimeType": "application/json"
    },
    "accepted": {
      "scheme": "exact",
      "network": "eip155:196",
      "amount": "10000",
      "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
      "payTo": "0xRecipientAddress",
      "maxTimeoutSeconds": 60,
      "extra": { "name": "USDG", "version": "2" }
    },
    "payload": {
      "signature": "0xf3746613c2d920b5fdabc0856f2aeb2d4f88ee6037b8cc5d04a71a4462f13480...",
      "authorization": {
        "from": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
        "to": "0xRecipientAddress",
        "value": "10000",
        "validAfter": "0",
        "validBefore": "1740672154",
        "nonce": "0xf374661..."
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "eip155:196",
    "amount": "10000",
    "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
    "payTo": "0xRecipientAddress",
    "maxTimeoutSeconds": 60,
    "extra": { "name": "USDG", "version": "2" }
  }
}'

请求示例 — exact + Permit2#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/x402/verify' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "x402Version": 2,
  "paymentPayload": {
    "x402Version": 2,
    "resource": { "url": "https://api.example.com/premium-data" },
    "accepted": {
      "scheme": "exact",
      "network": "eip155:196",
      "amount": "10000",
      "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
      "payTo": "0xMerchantAddr...",
      "maxTimeoutSeconds": 60,
      "extra": { "assetTransferMethod": "permit2" }
    },
    "payload": {
      "signature": "0xf374...1c",
      "permit2Authorization": {
        "from": "0xBuyerEOA...",
        "permitted": {
          "token": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
          "amount": "10000"
        },
        "spender": "0x402085c248EeA27D92E8b30b2C58ed07f9E20001",
        "nonce": "1027389471020934876123987612938712398761239",
        "deadline": "1714813500",
        "witness": {
          "to": "0xMerchantAddr...",
          "validAfter": "1714812840"
        }
      }
    }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "eip155:196",
    "amount": "10000",
    "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
    "payTo": "0xMerchantAddr...",
    "extra": { "assetTransferMethod": "permit2" }
  }
}'

注意:

  • permit2Authorization.witness 仅含 to / validAfter 两个字段,不需要 facilitator(DTO 上存在但 exact 路径不读不校验)。
  • spender 必须等于 Apollo x402.exact.permit2.proxy.address,否则返回 invalid_permit2_spender
  • permit2Authorization.permitted.amount 必须等于 paymentRequirements.amount(signed = paid)。

响应示例 — 验证通过#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "isValid": true,
    "invalidReason": null,
    "invalidMessage": null,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d"
  }
}

响应示例 — 验证失败#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "isValid": false,
    "invalidReason": "insufficient_allowance",
    "invalidMessage": "Insufficient allowance to Permit2: allowance=0, required=10000",
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d"
  }
}

3. /api/v6/pay/x402/settle#

POST
/api/v6/pay/x402/settle

验证通过后,提交链上结算。每次调用都会发起一笔独立的链上交易:

  • exact + EIP-3009:直接调用 token 合约的 transferWithAuthorization
  • exact + Permit2:调用 x402ExactPermit2Proxy.settle,Buyer 对 Permit2 canonical 合约的 ERC-20 必须已 approve(MAX_UINT256)
  • upto:调用 x402UptoPermit2Proxy.settle,由 Facilitator EOA 二次签名(HSM)后上链

请求参数#

参数类型必传描述
x402VersionInteger协议版本,如 2
paymentPayloadObject同 verify
paymentRequirementsObject同 verify。upto 路径下 amount 表示实付金额,必须 ≤ permit2Authorization.permitted.amount(上限)
syncSettleBooleanOKX 扩展true=同步等待链上确认(轮询至超时);false(默认)=异步广播。upto 路径忽略此字段,永远异步

响应参数#

参数类型描述
successBoolean结算是否成功
errorReasonString机器可读的失败原因(失败时返回)
errorMessageString人类可读的失败说明(失败时返回)
payerString付款方钱包地址
transactionString链上交易哈希
networkStringCAIP-2 链标识
statusStringOKX 扩展。结算状态,见下表
amountStringOKX 扩展upto scheme 返回实际结算金额(原子单位);零结算时为 "0"exact / exact + permit2 不返回此字段

status 取值矩阵:

路径syncSettle结果statustransactionamount
exact (EIP-3009 / Permit2)false(默认)已广播pendingtxHash
exact (EIP-3009 / Permit2)true链上确认成功successtxHash
exact (EIP-3009 / Permit2)true等待超时timeouttxHash
exact (EIP-3009 / Permit2)验签 / 模拟 / 链上失败failed""
upto—(忽略)零结算successnull"0"
upto—(忽略)已广播pendingtxHash实付金额
upto—(忽略)验签 / 模拟 / 链上失败failed""

请求示例 — exact + EIP-3009 同步结算#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/x402/settle' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "x402Version": 2,
  "paymentPayload": { "...同 verify..." },
  "paymentRequirements": { "...同 verify..." },
  "syncSettle": true
}'

请求示例 — exact + Permit2 异步结算#

请求体与 verify 完全一致,paymentPayload.payloadpermit2AuthorizationsyncSettle 缺省。

响应示例 — exact 同步结算成功(syncSettle=true)#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "errorReason": null,
    "errorMessage": null,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "0x4f46ed8eac92ddbccfb56a88ff827db3616c7beb191adabbeeded901340bd7d5",
    "network": "eip155:196",
    "status": "success"
  }
}

响应示例 — exact 异步结算(syncSettle=false)#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "errorReason": null,
    "errorMessage": null,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "0x4f46ed8eac92ddbccfb56a88ff827db3616c7beb191adabbeeded901340bd7d5",
    "network": "eip155:196",
    "status": "pending"
  }
}

响应示例 — exact 等待超时(syncSettle=true)#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "0x4f46ed8eac92ddbccfb56a88ff827db3616c7beb191adabbeeded901340bd7d5",
    "network": "eip155:196",
    "status": "timeout"
  }
}

客户端拿到 timeout 时应继续走 /settle/status 轮询。

响应示例 — 结算失败#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": false,
    "errorReason": "insufficient_funds",
    "errorMessage": "Transaction reverted",
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "",
    "network": "eip155:196",
    "status": "failed"
  }
}

4. /api/v6/pay/x402/settle/status#

GET
/api/v6/pay/x402/settle/status

根据链上交易哈希查询结算状态,适用于异步结算(syncSettle=falseupto、或 syncSettle=true 超时)的轮询场景。

请求参数#

参数位置类型必传描述
txHashqueryString链上交易哈希

响应参数#

参数类型描述
successBoolean查询是否成功(txHash 不存在时为 false,settleStatus=FAILED 时也为 false
errorReasonString机器可读的失败原因(DB error_reason 字段)
errorMessageString人类可读的失败说明
payerString付款方钱包地址
transactionString链上交易哈希
networkStringCAIP-2 链标识
statusString当前结算状态:pending / success / failed
amountStringOKX 扩展upto scheme 的实际结算金额(原子单位);exact / exact + permit2null

请求示例#

bash
curl --location --request GET 'https://web3.okx.com/api/v6/pay/x402/settle/status?txHash=0x4f46ed8eac92ddbccfb56a88ff827db3616c7beb191adabbeeded901340bd7d5' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z'

响应示例 — 查询成功(exact)#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "0x4f46ed8eac92ddbccfb56a88ff827db3616c7beb191adabbeeded901340bd7d5",
    "network": "eip155:196",
    "status": "success",
    "amount": null
  }
}

响应示例 — 查询成功(upto)#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "payer": "0xcb30ed083ad246b126a3aa1f414b44346e83e67d",
    "transaction": "0xabc...",
    "network": "eip155:196",
    "status": "success",
    "amount": "1234000"
  }
}

响应示例 — 交易未找到#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": false,
    "errorReason": "not_found",
    "errorMessage": "Transaction not found for txHash: 0xabc123...",
    "payer": null,
    "transaction": null,
    "network": null,
    "status": null
  }
}

upto Scheme#

upto = "按上限授权 + 按实际用量结算"。底层走 Permit2 canonical → x402UptoPermit2Proxy强制带 witness.facilitator,由 Facilitator 用注册的 EOA 对 (owner, token, permittedAmount, permitNonce, permitDeadline, witnessHash, userSignatureHash, amount, relayer, deadline) 二次签名(HSM)后上链。

复用 /api/v6/pay/x402/{verify,settle,supported,settle/status} 四个 endpoint,由 paymentPayload.accepted.scheme="upto" + payload.permit2Authorization != null 自动路由。

双签名路径#

upto 同时接受两类签名 buyer,由 accepted.extra.sessionCert + accepted.extra.signatureScheme 决定路由:

路径签名钱包签名算法sessionCertsignatureScheme
EOAMetaMask / Rabby / Coinbase Wallet 等secp256k1 (EIP-712)不填缺省 / "secp256k1"
SESSIONOKX agentic walletEd25519 (session key)必填(base64 sessionCert)缺省 / "ed25519"

互斥校验失败(sessionCert 存在 + signatureScheme="secp256k1",或缺 sessionCert + signatureScheme="ed25519")→ 返回 upto_signature_route_conflict

EOA 路径受 Apollo x402.upto.eoa.signature.enabled 灰度控制,关闭时返回 unsupported_scheme

5. /api/v6/pay/x402/verify — scheme=upto#

POST
/api/v6/pay/x402/verify

请求体结构与 exact + Permit2 完全一致,差异点:

字段upto 要求
paymentPayload.accepted.scheme必须 "upto"
paymentRequirements.scheme必须 "upto"
paymentPayload.payload.permit2Authorization.witness.facilitator必填,且必须在 facilitator 白名单(Apollo x402.upto.facilitator.address
paymentPayload.accepted.extra.facilitatorAddresswitness.facilitator 字符串相等(忽略大小写)
paymentPayload.accepted.extra.sessionCertSESSION 路径必填,EOA 路径不填
paymentPayload.accepted.extra.signatureScheme可选,"secp256k1" / "ed25519";缺省时按 sessionCert 自动判定
paymentPayload.payload.permit2Authorization.spender必须等于 Apollo x402.upto.permit2.proxy.address(与 exact + permit2 的 proxy 不同),否则 invalid_spender
paymentPayload.payload.permit2Authorization.permitted.amount授权上限,必须 > 0。verify 阶段强制 permitted.amount == paymentRequirements.amount(buyer 把 ceiling 同时签进 requirements,settle 时 seller 才把 paymentRequirements.amount 改写为实付金额)

请求示例 — upto + EOA#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/x402/verify' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "x402Version": 2,
  "paymentPayload": {
    "x402Version": 2,
    "resource": { "url": "https://api.example.com/agent-call" },
    "accepted": {
      "scheme": "upto",
      "network": "eip155:196",
      "amount": "5000000",
      "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
      "payTo": "0xMerchant...",
      "maxTimeoutSeconds": 60,
      "extra": {
        "assetTransferMethod": "permit2",
        "facilitatorAddress": "0xFacilitatorEOA..."
      }
    },
    "payload": {
      "signature": "0x...65byte_secp256k1_sig",
      "permit2Authorization": {
        "from": "0xBuyerEOA...",
        "permitted": {
          "token": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
          "amount": "5000000"
        },
        "spender": "0x4020e7...0002",
        "nonce": "1027389471020934876",
        "deadline": "1714813500",
        "witness": {
          "to": "0xMerchant...",
          "facilitator": "0xFacilitatorEOA...",
          "validAfter": "1714812840"
        }
      }
    }
  },
  "paymentRequirements": {
    "scheme": "upto",
    "network": "eip155:196",
    "amount": "5000000",
    "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
    "payTo": "0xMerchant...",
    "extra": {
      "assetTransferMethod": "permit2",
      "facilitatorAddress": "0xFacilitatorEOA..."
    }
  }
}'

请求示例 — upto + SESSION(OKX agentic wallet)#

accepted.extra 多两个字段,payload.signature 为 base64 Ed25519:

json
{
  "accepted": {
    "scheme": "upto",
    "network": "eip155:196",
    "amount": "5000000",
    "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
    "payTo": "0xMerchant...",
    "extra": {
      "assetTransferMethod": "permit2",
      "facilitatorAddress": "0xFacilitatorEOA...",
      "sessionCert": "eyJhbGciOi...base64",
      "signatureScheme": "ed25519"
    }
  },
  "payload": {
    "signature": "MEUCIQ...base64_ed25519_sig",
    "permit2Authorization": {
      "from": "0xAaAddress...",
      "permitted": { "token": "0x4ae46a...", "amount": "5000000" },
      "spender": "0x4020e7...0002",
      "nonce": "1027389471020934876",
      "deadline": "1714813500",
      "witness": {
        "to": "0xMerchant...",
        "facilitator": "0xFacilitatorEOA...",
        "validAfter": "1714812840"
      }
    }
  }
}

响应#

结构与 exact verify 一致:{isValid, invalidReason, invalidMessage, payer}

6. /api/v6/pay/x402/settle — scheme=upto#

POST
/api/v6/pay/x402/settle

请求体结构同 verify,关键差异:

  • paymentRequirements.amount实付金额,必须满足 0 ≤ amount ≤ permit2Authorization.permitted.amount
  • paymentRequirements.amount = "0" 进入零结算快速路径:不调 TEE、不上链、DB 写 SUCCESS、响应 transaction=null / status=success / amount="0"
  • syncSettle 字段被忽略,upto 永远异步返回 pending

settle 响应矩阵#

场景successstatustransactionamounterrorReason
零结算truesuccessnull"0"
正常广播(异步)truependingtxHash实付金额
settle 实付 > 上限falsefailed""upto_settlement_exceeds_amount
facilitator 字段错falsefailed""upto_facilitator_mismatch
EOA 签名格式错falsefailed""invalid_eoa_signature
TEE 转签失败(SESSION)falsefailed""tee_sign_failed
Intent 提交失败falsefailed""intent_submit_failed
同 (payer, nonce) 重复 settletrue上次状态上次 txHash 或 ""DB settle_amount"0"

请求示例#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/x402/settle' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "x402Version": 2,
  "paymentPayload": {
    "x402Version": 2,
    "accepted": {
      "scheme": "upto",
      "network": "eip155:196",
      "amount": "5000000",
      "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
      "payTo": "0xMerchant...",
      "extra": {
        "assetTransferMethod": "permit2",
        "facilitatorAddress": "0xFacilitatorEOA..."
      }
    },
    "payload": {
      "signature": "0x...secp256k1_sig",
      "permit2Authorization": { "...同 verify..." }
    }
  },
  "paymentRequirements": {
    "scheme": "upto",
    "network": "eip155:196",
    "amount": "1234000",
    "asset": "0x4ae46a509f6b1d9056937ba4500cb143933d2dc8",
    "payTo": "0xMerchant...",
    "extra": {
      "assetTransferMethod": "permit2",
      "facilitatorAddress": "0xFacilitatorEOA..."
    }
  }
}'

响应示例 — 正常广播#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "payer": "0xbuyer...",
    "transaction": "0xabc...",
    "network": "eip155:196",
    "status": "pending",
    "amount": "1234000"
  }
}

响应示例 — 零结算#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": true,
    "payer": "0xbuyer...",
    "transaction": null,
    "network": "eip155:196",
    "status": "success",
    "amount": "0"
  }
}

响应示例 — 失败#

json
{
  "code": "0",
  "msg": "success",
  "data": {
    "success": false,
    "errorReason": "upto_settlement_exceeds_amount",
    "errorMessage": "Settlement amount exceeds authorized ceiling",
    "payer": "0xbuyer...",
    "transaction": "",
    "network": "eip155:196",
    "status": "failed"
  }
}

charge Scheme#

charge 基于 HTTP 402 Challenge-Credential 流程提供一次性代币转账能力。

  • 服务端代付(transaction 模式):Buyer 签署 EIP-3009 授权,Broker 代为提交链上交易
  • 客户端自付(hash 模式):Buyer 自行广播链上交易,Broker 验证交易有效性

7. /api/v6/pay/mpp/charge/settle#

POST
/api/v6/pay/mpp/charge/settle

服务端代付 — 代替用户提交链上 ERC-20 转账。支持 EIP-3009 授权方式,支持分账(最多 10 笔)。

请求参数#

参数类型必传描述
challengeObject服务端签发的 Challenge 对象(原样回传),详见 Challenge
payloadObjectEVM 支付凭证
payload.typeString固定 "transaction"
payload.authorizationObjectEIP-3009 授权对象
payload.authorization.typeString固定 "eip-3009"
payload.authorization.fromString付款方钱包地址
payload.authorization.toString收款方钱包地址
payload.authorization.valueString支付金额(base units)
payload.authorization.validAfterString授权生效 Unix 时间戳
payload.authorization.validBeforeString授权过期 Unix 时间戳
payload.authorization.nonceString随机 bytes32,每笔授权唯一
payload.authorization.signatureString65 字节 EIP-712 签名(r‖s‖v)
payload.authorization.splitsArray分账列表,最多 10 条,详见 Split
sourceString付款方 DID(did:pkh:eip155:196:0x...

响应参数#

参数类型描述
methodString固定值 "evm"
referenceString链上交易哈希(0x 前缀)
statusString固定值 "success"
timestampStringRFC 3339 结算时间
chainIdInteger结算所在链 ID,如 196
challengeIdStringChallenge ID,用于客户端关联
externalIdString原样回传自 Challenge request 的商户订单号

请求示例#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/mpp/charge/settle' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "challenge": {
    "id": "qB3wErTyU7iOpAsD9fGhJk",
    "realm": "api.example.com",
    "method": "evm",
    "intent": "charge",
    "request": "eyJhbW91bnQiOiIxMDAwMCIsImN1cnJlbmN5Ijoi...",
    "expires": "2026-04-01T12:05:00Z"
  },
  "payload": {
    "type": "transaction",
    "authorization": {
      "type": "eip-3009",
      "from": "0x1234567890abcdef1234567890abcdef12345678",
      "to": "0x742d35Cc6634c0532925a3b844bC9e7595F8fE00",
      "value": "10000",
      "validAfter": "0",
      "validBefore": "9999999999",
      "nonce": "0x9337d07c707c703b86f05e66b9097e38e7587e7ecfe740551ac608693864abdd",
      "signature": "0x5a9827232b5c640d7239462dbb3f0eede1aa2522eb53e552369db8db66720293..."
    }
  }
}'

响应示例#

json
{
  "code": "0",
  "msg": "",
  "data": {
    "method": "evm",
    "reference": "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
    "status": "success",
    "timestamp": "2026-04-01T12:04:30Z",
    "chainId": 196,
    "challengeId": "qB3wErTyU7iOpAsD9fGhJk",
    "externalId": "order-12345"
  }
}

请求示例 — 含分账#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/mpp/charge/settle' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "challenge": {
    "id": "sP1itPaym3ntEx4mple",
    "realm": "marketplace.example.com",
    "method": "evm",
    "intent": "charge",
    "request": "eyJ...",
    "expires": "2026-04-01T12:05:00Z"
  },
  "payload": {
    "type": "transaction",
    "authorization": {
      "type": "eip-3009",
      "from": "0x1234567890abcdef1234567890abcdef12345678",
      "to": "0x742d35Cc6634c0532925a3b844bC9e7595F8fE00",
      "value": "940000",
      "validAfter": "0",
      "validBefore": "1775059500",
      "nonce": "0x1111111111111111111111111111111111111111111111111111111111111111",
      "signature": "0xabc...primary",
      "splits": [
        {
          "from": "0x1234567890abcdef1234567890abcdef12345678",
          "to": "0xA1B2C3d4e5F6a1B2c3d4e5F6a1b2c3d4e5F6a1b2",
          "value": "50000",
          "validAfter": "0",
          "validBefore": "1775059500",
          "nonce": "0x2222222222222222222222222222222222222222222222222222222222222222",
          "signature": "0xdef...split1"
        },
        {
          "from": "0x1234567890abcdef1234567890abcdef12345678",
          "to": "0xC4D5e6F7A8B9c4D5E6f7a8B9c4d5e6F7a8b9C4D5",
          "value": "10000",
          "validAfter": "0",
          "validBefore": "1775059500",
          "nonce": "0x3333333333333333333333333333333333333333333333333333333333333333",
          "signature": "0xghi...split2"
        }
      ]
    }
  },
  "source": "did:pkh:eip155:196:0x1234567890abcdef1234567890abcdef12345678"
}'

8. /api/v6/pay/mpp/charge/verifyHash#

POST
/api/v6/pay/mpp/charge/verifyHash

客户端自付 — 验证客户端已广播的链上交易,确认交易符合 Challenge 中的支付要求。

请求参数#

参数类型必传描述
challengeObject服务端签发的 Challenge 对象(原样回传),详见 Challenge
payloadObject支付凭证
payload.typeString固定 "hash"
payload.hashString客户端已广播的链上交易哈希
sourceString付款方 DID(did:pkh:eip155:196:0x...

响应参数#

参数类型描述
methodString固定值 "evm"
referenceString链上交易哈希(0x 前缀)
statusString固定值 "success"
timestampStringRFC 3339 确认时间
chainIdInteger链 ID,如 196
challengeIdStringChallenge ID,用于客户端关联
externalIdString原样回传自 Challenge request 的商户订单号

请求示例#

bash
curl --location --request POST 'https://web3.okx.com/api/v6/pay/mpp/charge/verifyHash' \
--header 'Content-Type: application/json' \
--header 'OK-ACCESS-KEY: 37c541a1-****-****-****-10fe7a038418' \
--header 'OK-ACCESS-SIGN: leaV********3uw=' \
--header 'OK-ACCESS-PASSPHRASE: 1****6' \
--header 'OK-ACCESS-TIMESTAMP: 2026-04-01T12:21:41.274Z' \
--data '{
  "challenge": {
    "id": "qB3wErTyU7iOpAsD9fGhJk",
    "realm": "api.example.com",
    "method": "evm",
    "intent": "charge",
    "request": "eyJhbW91bnQiOiIxMDAwMCIsImN1cnJlbmN5Ijoi...",
    "expires": "2026-04-01T12:05:00Z"
  },
  "payload": {
    "type": "hash",
    "hash": "0xd9a703784f0cb489ea90c52f5626a22516f39c5063558733bb742972fdf6f722"
  },
  "source": "did:pkh:eip155:196:0x1234567890abcdef1234567890abcdef12345678"
}'

响应示例#

json
{
  "code": "0",
  "msg": "",
  "data": {
    "method": "evm",
    "reference": "0x9f8e7d6c5b4a3928170fabcdef1234567890abcdef1234567890abcdef123456",
    "status": "success",
    "timestamp": "2026-04-01T12:04:30Z",
    "chainId": 196,
    "challengeId": "qB3wErTyU7iOpAsD9fGhJk",
    "externalId": "order-12345"
  }
}

公共数据结构#

PaymentPayload#

Buyer 签名后通过 X-PAYMENT Header(base64 编码)传递给 Seller,Seller 原样透传给 Broker。

参数类型必传描述
x402VersionInteger协议版本,如 2
resourceObject受保护资源描述
resource.urlString受保护资源的 URL
resource.descriptionString资源描述
resource.mimeTypeString预期响应的 MIME 类型
acceptedObjectBuyer 选中的支付方式(从 accepts 数组中选取),结构同 PaymentRequirements
payloadObject签名数据
payload.signatureString签名(编码与路径相关,见下文 Permit2Authorization
payload.authorizationObject条件EIP-3009 授权对象,exact + EIP-3009 时必填
payload.permit2AuthorizationObject条件Permit2 授权对象,exact + Permit2 / upto 时必填

约束:payload.authorizationpayload.permit2Authorization 严格二选一,否则返回 param_mismatch

PaymentRequirements#

同时用作 402 响应 accepts 数组元素和 paymentPayload.accepted

参数类型必传描述
schemeString"exact" / "upto" / "aggr_deferred"
networkStringCAIP-2 链标识,如 eip155:196
amountString金额(原子单位字符串)。exact = 实付;upto verify 阶段 = 上限,settle 阶段 = 实付
assetString代币合约地址
payToString收款钱包地址
maxTimeoutSecondsInteger支付完成的最大超时时间(秒)
extraObjectscheme 特有扩展,见下表

extra 子字段:

子字段适用 scheme说明
name / versionexact (EIP-3009)EIP-712 domain 字段,部分 token 需要
assetTransferMethodexact / upto"permit2" 走 Permit2 路径;缺省 / "eip3009" 走 EIP-3009
facilitatorAddressuptofacilitator EOA 地址
sessionCertupto (SESSION)base64 session cert
signatureSchemeupto"secp256k1" / "ed25519"

Authorization#

exact + EIP-3009 路径专用。

参数类型必传描述
fromString付款方钱包地址(EOA)
toString收款方钱包地址(应等于 payTo
valueString支付金额(原子单位,应等于 amount
validAfterString授权生效的 Unix 时间戳
validBeforeString授权过期的 Unix 时间戳
nonceString32 字节随机 nonce(0x hex,防重放)

Permit2Authorization#

exact + Permit2 / upto 路径专用。

子字段类型必传 (exact + Permit2)必传 (upto)说明
fromStringBuyer 钱包地址(EOA 路径:EOA;SESSION 路径:AA)
permitted.tokenString代币合约地址
permitted.amountStringexact = 实付;upto = 授权上限
spenderStringexact: x402ExactPermit2Proxy;upto: x402UptoPermit2Proxy
nonceStringPermit2 nonce 十进制字符串(uint256)
deadlineStringPermit2 deadline Unix 时间戳
witness.toString收款方地址,必须等于 accepted.payTo
witness.facilitatorStringupto 必填;exact 路径忽略此字段
witness.validAfterString授权生效 Unix 时间戳

payload.signature 编码规则:

路径编码
exact + Permit2(EOA)0x 前缀 65 byte hex,secp256k1 r‖s‖v(EIP-2 低 s)
upto + EOA同上
upto + SESSIONbase64 编码的 Ed25519 签名

Permit2 链上前置条件:buyer 必须对 Permit2 canonical 合约 0x000000000022D473030F116dDEE9F6B43aC78BA3 执行 approve(MAX_UINT256),否则 verify 返回 insufficient_allowance

Challenge#

由服务端签发的 Challenge 对象,客户端原样回传(仅 charge 使用)。

参数类型必传描述
idStringChallenge ID
realmString保护空间标识
methodString固定 "evm"
intentString支付意图:"charge" / "session"
requestStringbase64url 编码的请求参数
expiresString过期时间(ISO 8601)

Split#

charge 分账列表中的单条分账项,每笔需独立签名。

参数类型必传描述
fromString付款方地址(与主签名相同)
toString分账收款方地址
valueString分账金额(base units)
validAfterString授权生效 Unix 时间戳
validBeforeString授权过期 Unix 时间戳
nonceString独立 nonce(bytes32)
signatureString65 字节 EIP-712 签名

支持的网络和币种#

网络Chain Index状态
X Layer196已支持

X Layer 支持的稳定币:

币种合约地址
USDG0x4ae46a509f6b1d9056937ba4500cb143933d2dc8
USD₮00x779ded0c9e1022225f8e0630b35a9b54be713736

错误码#

错误响应统一使用包络 {"code": "<code>", "msg": "<message>", "data": null}

1. 认证错误(HTTP 401)#

错误码描述
50103请求头 OK-ACCESS-KEY 不能为空
50104请求头 OK-ACCESS-PASSPHRASE 不能为空
50105请求头 OK-ACCESS-PASSPHRASE 错误
50106请求头 OK-ACCESS-SIGN 不能为空
50107请求头 OK-ACCESS-TIMESTAMP 不能为空
50111无效的 OK-ACCESS-KEY
50112无效的 OK-ACCESS-TIMESTAMP
50113无效的签名

2. 请求错误#

错误码HTTP 状态描述
50011429用户请求频率过快,超过该接口允许的限额
50014400必填参数 {param} 不能为空

3. 业务错误#

错误码HTTP 状态描述
50026500系统错误,请稍后重试
81001200{param} 参数错误
81004200不支持的链
80007200风险地址

4. exact / upto verify / settle 业务字段#

exact / upto 接口的失败原因通过响应 data 中的 invalidReason(verify)或 errorReason(settle / settle/status)返回,常见取值:

字段值适用接口描述
insufficient_fundsverify, settle付款方余额不足(兼容旧版)
insufficient_balanceverify, settle余额扣除 pending 后不足实付
insufficient_allowanceverify, settlebuyer 对 Permit2 canonical 合约的 ERC-20 allowance 不足
nonce_already_usedverify, settlenonce 已被使用
expired_authorizationverify, settle授权已过期(兼容旧版)
expiredverify, settledeadline 已过
not_yet_validverify, settlevalidAfter > now
signature_invalidverify, settle签名校验失败(兼容旧版)
invalid_signatureverify, settlesecp256k1 / Ed25519 验签失败 / 格式错 / 低 s 违反
requirements_mismatchverify, settleacceptedpaymentRequirements 不一致(兼容旧版)
param_mismatchverify, settle字段缺失 / 互斥违反 / 一致性校验失败
unsupported_schemeverify, settlescheme 未启用(Apollo 灰度开关关闭)
unsupported_chainverify, settlechainIndex 不在配置
payer_blockedverify, settlebuyer 命中黑名单
risk_addressverify, settleKYS 合规拦截(payer 或 payTo)
transaction_revertedsettle链上交易回滚
chain_unavailablesettle链上 RPC 不可用
onchain_errorverifyverify 阶段 multicall 调用异常
onchain_recheck_errorsettlesettle 阶段链上 TOCTOU 二次校验失败
settle_busysettle同一 (payer, token) 并发结算锁冲突
settle_interruptedsettle等锁期间线程被中断
not_foundsettle/statustxHash 不在 Broker 记录中
invalid_permit2_spenderverify (exact + permit2)spender ≠ x402ExactPermit2Proxy
permit2_token_mismatchverify (exact + permit2)permitted.token ≠ accepted.asset
permit2_amount_mismatchverify (exact + permit2)permitted.amount ≠ paymentRequirements.amount
invalid_permit2_recipient_mismatchverify (exact + permit2)witness.to ≠ accepted.payTo
permit2_not_yet_validverify (exact + permit2)witness.validAfter > now
permit2_deadline_expiredverify, settle (permit2)deadline ≤ now + buffer
invalid_permit2_signatureverify (exact + permit2)Permit2 EIP-712 签名验证失败
invalid_spenderverify (upto)spender ≠ x402UptoPermit2Proxy
invalid_amountverify (upto)upto ceiling ≤ 0
upto_signature_route_conflictverify (upto)sessionCertsignatureScheme 互斥校验失败
upto_facilitator_mismatchverify, settle (upto)witness.facilitator 缺失 / 非法 / 不在白名单 / 与 accepted.extra.facilitatorAddress 不一致
upto_invalid_settlement_amountsettle (upto)paymentRequirements.amount 为负或格式错
upto_settlement_exceeds_amountsettle (upto)settle 实付 > permit ceiling
invalid_eoa_signaturesettle (upto + EOA)EOA sig 非 0x 前缀或长度 ≠ 65 byte
tee_sign_failedsettle (upto + SESSION)TEE signMsg(eip712Hash) 转签失败
account_resolve_errorsettle (upto + SESSION)AA 账户解析失败
intent_submit_failedsettle (upto)Intent Framework 提交失败

5. charge 业务错误#

错误码错误名称描述
8000SERVICE_ERRORAPI 服务内部错误
70000invalid_params缺少必填字段或格式错误
70001unsupported_chain链不在支持列表
70002payer_blocked付款方在黑名单
70003invalid_credentialsource 缺失、或 txHash 已被使用
70004invalid_signature签名验证失败
70005split_sum_exceeds_total分账总额 >= 总金额
70006split_count_exceeded分账数量 > 10
70007tx_not_confirmed交易未在链上确认
70009challenge_invalidChallenge 不存在或已过期
目录