Documentation Index
Fetch the complete documentation index at: https://docs.acedata.cloud/llms.txt
Use this file to discover all available pages before exploring further.
x402 是基于 HTTP 402 Payment Required 标准的链上支付协议,可让调用方在发起 API 请求的同时完成链上结算,非常适合自动化程序、AI Agent、微服务之间的按调用计费场景。通过本指南,你可以在自己的系统中以编程方式完成 AceDataCloud 订单的支付,实现「请求即付费」的体验。
官方资料参考:
本文档面向需要在业务中接入 AceDataCloud 平台 x402 支付能力的开发者,介绍从准备环境到完成支付调用的完整流程,并提供 Axios、Fetch、Python requests 与 httpx 的示例代码。核心要点:
- 支付链路在 Base 主网 完成,资产使用 USDC;
- 必须使用持币钱包的 EVM 私钥 生成
X-PAYMENT 签名头;
- 所有 API 均位于
https://platform.acedata.cloud 域名下,Authorization 头需携带 Platform Token。
一、准备工作
1. 查看订单并记录收款信息
登录控制台 https://platform.acedata.cloud,在订单列表或订单详情页可以看到需要支付的订单。订单详情会展示:
- 订单 ID(例如
7744945e-5e77-4dcc-a9c4-528692d17b34);
- 收款地址
pay_to(也会在 402 响应中返回,建议以页面信息为准)。
请记录订单 ID 并确认 pay_to 地址,后续签名时需要保证资金发送到该地址。
2. 准备付款钱包与资金
- 准备一个支持 Base 主网的 EVM 钱包,并导出待使用的私钥;
- 在 Base 主网充值足额 USDC(支付金额单位为 6 位小数的最小单位);
- x402 Facilitator 会代付网络费用,付款钱包只需保留足够的 USDC;
- 私钥仅用于本地签名,请妥善保管,避免在浏览器或不可信环境暴露。
Platform Token 用于调用平台 API,与登录后浏览器使用的用户 Token 功能类似,但不会过期。请按照以下步骤创建:
- 打开控制台页面 https://platform.acedata.cloud/console/platform-tokens;
- 点击「创建 Token」,根据提示填写备注信息后生成;
- 复制生成的 Token(例如
platform-v1-xxxx),妥善保存为 platform_token。
后续所有 API 调用 header 中都需要包含:
Authorization: Bearer {platform_token}
4. 请求基础信息
- API 基础域名:
https://platform.acedata.cloud
- 支付请求路径:
/api/v1/orders/{order_id}/pay/
- 请求和响应均使用 JSON,编码为 UTF-8。
二、支付流程总览
- 发起支付请求:无
X-PAYMENT 头的首次 POST 请求,触发平台返回 402 Payment Required;
- 读取支付要求:解析 402 响应中的
accepts 数组,确认 network 为 base、asset 为 USDC、payTo 与订单页面一致;
- 生成
X-PAYMENT:使用付款钱包私钥、响应体中的要求、Facilitator 返回的 EIP-712 域等信息生成签名(通常借助官方 SDK 完成);
- 携带签名重试:将
X-PAYMENT 头加入同一路径请求,平台验证成功后返回 200;
- 解析结果:读取响应头
X-PAYMENT-RESPONSE,可获取链上交易哈希、实际扣款金额等信息用于对账。
三、接口交互示例
1. 首次请求(触发 402)
POST https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/
Authorization: Bearer {platform_token}
Content-Type: application/json
{
"pay_way": "X402"
}
典型的 402 响应(字段顺序可能略有变化):
{
"error": "Payment required for this order.",
"accepts": [
{
"scheme": "exact",
"network": "base",
"asset": "0x833589fcd6edb6e08f4c7c32d4f71b54b268aa0e",
"maxAmountRequired": "1250000",
"payTo": "0x302afdd980aaefca3afa8df7222a6002774f6724",
"extra": {
"eip712": { "...": "..." }
}
}
],
"paywall": { ... }
}
关键字段说明:
network:必须是 base(Base 主网);
asset:Base USDC 合约地址(示例为官方主网合约);
maxAmountRequired:本次支付所需的 USDC 原子单位(1 USDC = 1,000,000 atomic units);
payTo:平台收款地址,应与订单详情页面一致;
extra:签名所需的 EIP-712 域信息等。
2. 生成 X-PAYMENT
常见做法为使用官方 SDK(如 x402-js、x402-fetch、x402.clients 等):
- 将付款钱包私钥转换为账户对象;
- 记录 402 响应中的
accepts 数据,选择 network == "base" 的支付选项;
- 调用 SDK 提供的签名函数生成 Base64 编码的
X-PAYMENT 字符串(无需客户端直连 facilitator;平台后端会负责调用 facilitator 完成 verify/settle);
- 建议校验
maxAmountRequired 是否在可接受范围,超过则提醒用户充值。
如需手动实现,请参考 x402 官方文档,按照 extra.eip712 提供的域信息构造 EIP-712 结构体后进行签名。
3. 携带签名重试
POST https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/
Authorization: Bearer {platform_token}
Content-Type: application/json
X-PAYMENT: {base64_signed_payload}
{
"pay_way": "X402"
}
若支付成功,响应状态为 200,响应体返回更新后的订单信息,并附带:
X-PAYMENT-RESPONSE: eyJ0cmFuc2FjdGlvbiI6IjB4...==
X-PAYMENT-RESPONSE 可使用 SDK 的解码函数获取链上交易哈希、支付网络、付款人地址等数据,用于业务入账或展示。
四、多语言示例代码
以下示例均假设通过环境变量或配置文件注入:
ACE_PLATFORM_TOKEN:Platform Token;
ACE_X402_ORDER_ID:订单 ID;
ACE_X402_PRIVATE_KEY:付款钱包私钥(带 0x 前缀)。
1. Axios(TypeScript)
import axios from "axios";
import { Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { buildPaymentHeader, decodePaymentResponse } from "x402-js";
const baseURL = "https://platform.acedata.cloud";
const orderId = process.env.ACE_X402_ORDER_ID!;
const platformToken = process.env.ACE_PLATFORM_TOKEN!;
const privateKey = process.env.ACE_X402_PRIVATE_KEY as Hex;
const account = privateKeyToAccount(privateKey);
const api = axios.create({
baseURL,
headers: {
Authorization: `Bearer ${platformToken}`,
"Content-Type": "application/json",
},
});
async function payOrder() {
const payPath = `/api/v1/orders/${orderId}/pay/`;
const initial = await api.post(
payPath,
{ pay_way: "X402" },
{ validateStatus: () => true }
);
if (initial.status !== 402) {
throw new Error(`unexpected status ${initial.status}`);
}
const requirement = initial.data.accepts.find(
(item: any) => item.network === "base"
);
if (!requirement) {
throw new Error("no base requirement returned");
}
const paymentHeader = await buildPaymentHeader({
account,
requirement,
});
const final = await api.post(
payPath,
{ pay_way: "X402" },
{ headers: { "X-PAYMENT": paymentHeader } }
);
if (final.status >= 400) {
throw new Error(`x402 payment failed: ${final.status} ${final.statusText}`);
}
const receipt = decodePaymentResponse(final.headers["x-payment-response"]);
console.log("x402 receipt", receipt);
}
payOrder().catch(console.error);
2. Fetch(JavaScript)
import { wrapFetchWithPayment, decodePaymentResponse } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.ACE_X402_PRIVATE_KEY!);
const platformToken = process.env.ACE_PLATFORM_TOKEN!;
const orderId = process.env.ACE_X402_ORDER_ID!;
const fetchWithPayment = wrapFetchWithPayment(fetch, account);
async function payOrder() {
const url = `https://platform.acedata.cloud/api/v1/orders/${orderId}/pay/`;
const response = await fetchWithPayment(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${platformToken}`,
},
body: JSON.stringify({ pay_way: "X402" }),
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`x402 payment failed: ${response.status} ${errorBody}`);
}
const receipt = decodePaymentResponse(
response.headers.get("x-payment-response")!
);
console.log("x402 receipt", receipt);
}
payOrder().catch(console.error);
3. Python requests
import os
from eth_account import Account
from x402.clients.requests import x402_requests
from x402.clients.base import decode_x_payment_response
order_id = os.environ["ACE_X402_ORDER_ID"]
platform_token = os.environ["ACE_PLATFORM_TOKEN"]
account = Account.from_key(os.environ["ACE_X402_PRIVATE_KEY"])
session = x402_requests(
account,
payment_requirements_selector=lambda accepts, **_: next(
req for req in accepts if req.network == "base" and req.scheme == "exact"
),
)
response = session.post(
f"https://platform.acedata.cloud/api/v1/orders/{order_id}/pay/",
json={"pay_way": "X402"},
headers={"Authorization": f"Bearer {platform_token}"},
)
response.raise_for_status()
receipt_header = response.headers.get("X-PAYMENT-RESPONSE")
if receipt_header:
print("x402 receipt:", decode_x_payment_response(receipt_header))
4. Python httpx(异步)
import asyncio
import os
from eth_account import Account
from x402.clients.httpx import x402HttpxClient
from x402.clients.base import decode_x_payment_response
async def pay_order() -> None:
order_id = os.environ["ACE_X402_ORDER_ID"]
platform_token = os.environ["ACE_PLATFORM_TOKEN"]
account = Account.from_key(os.environ["ACE_X402_PRIVATE_KEY"])
async with x402HttpxClient(
account=account,
base_url="https://platform.acedata.cloud",
headers={"Authorization": f"Bearer {platform_token}"},
payment_requirements_selector=lambda accepts, **_: next(
req for req in accepts if req.network == "base"
),
) as client:
response = await client.post(
f"/api/v1/orders/{order_id}/pay/",
json={"pay_way": "X402"},
)
response.raise_for_status()
receipt_header = response.headers.get("X-PAYMENT-RESPONSE")
if receipt_header:
print("x402 receipt:", decode_x_payment_response(receipt_header))
asyncio.run(pay_order())
示例仅演示关键调用,生产环境请补充异常处理、重试策略、日志与安全控制。
五、支付成功后的验证
- 控制台验证:访问订单详情页
https://platform.acedata.cloud/console/orders/{order_id},若页面显示「支付成功」或订单状态已变为已支付/已完成,即代表链上结算完成。
- API 验证:调用
GET https://platform.acedata.cloud/api/v1/orders/{order_id}/ 并携带 Authorization: Bearer {platform_token},检查响应中的 state 字段(PAID 或 FINISHED 表示支付成功)。
- 回传头部:在支付成功的响应中读取
X-PAYMENT-RESPONSE,可解析出链上交易哈希作为最终凭证;建议在系统日志中保存该信息以便对账。
六、常见问题排查
- 仍然返回 402:确认付款地址在 Base 主网拥有足够 USDC,检查
maxAmountRequired 是否超出钱包余额或自定义限额。
- 签名失败:确保私钥带
0x 前缀;签名时严格使用响应中的 extra(EIP-712 域)和 payTo,不要改动字段顺序。
- 网络不匹配:
accepts 中可能存在多条要求,请选择 network === "base" 的选项。
- 缺少
X-PAYMENT-RESPONSE:说明支付未实际扣款,可根据响应体中的错误重新发起;如遇链上拥堵,请稍后重试。
- 平台 Token 无效:确认 Token 未被删除,并以
platform-v1- 前缀开头;若接口返回 401,可在控制台重新生成。
七、更多帮助