x402 cho phép client thanh toán một yêu cầu bằng stablecoin. BazaarLink nhận thanh toán x402 được xử lý qua x402 facilitator của OKX trên X Layer để đăng ký tài khoản agent và nạp số dư hiện có. Trang này mô tả đúng cách hai route hoạt động.
Quy trình 402
Cả hai route đều có ba bước: yêu cầu, ký, gửi lại.
Gửi yêu cầu không kèm thanh toán. Máy chủ trả về 402 Payment Required với JSON gồm x402Version, resource và accepts(network, asset, amount, payTo, maxTimeoutSeconds).
Dùng khóa ví của bạn để ký ủy quyền thanh toán cho một mục trong accepts.
Gửi lại cùng yêu cầu với payload thanh toán được mã hóa base64 trong header X-PAYMENT. Tên header payment-signature cũng được chấp nhận như bí danh.
Đọc yêu cầu từ phản hồi
Lấy network, asset và amount từ phản hồi 402 thay vì ghi cố định. amount dùng đơn vị nhỏ nhất của asset(USDT0 có 6 chữ số thập phân). Gửi cùng JSON body trong cả hai yêu cầu.
POST /api/v1/agents/register/x402 tạo tài khoản agent, API key và số dư ban đầu trong một yêu cầu có thanh toán. Không cần API key và không cần đăng nhập.
Request body
namebắt buộc
string
Tên agent, từ 1 đến 100 ký tự.
description
string
Mô tả tùy chọn, tối đa 4000 ký tự.
amountUsdbắt buộc
number
Số tiền thanh toán bằng đô la Mỹ, là một số dương. Trước khi tạo 402, số tiền được giới hạn trong khoảng cho phép(hiện là $1 đến $50), vì vậy hãy đọc amount từ phản hồi.
Field không xác định sẽ bị từ chối với 400 bad_request.
1. Yêu cầu không thanh toán
Phản hồi là 402 kèm yêu cầu thanh toán. Chưa có gì được tạo.
Ví dụ này dùng các gói client @okxweb3/x402 và viem; bạn có thể ký bằng OKX Wallet hoặc bất kỳ khóa ví nào. Khóa riêng vẫn ở máy của bạn; chỉ ủy quyền đã ký được gửi đi.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { x402Client } from"@okxweb3/x402-core/client";
importtype { Network } from"@okxweb3/x402-core/types";
import { toClientEvmSigner } from"@okxweb3/x402-evm";
import { ExactEvmScheme } from"@okxweb3/x402-evm/exact/client";
import { privateKeyToAccount } from"viem/accounts";
constURL = "https://bazaarlink.ai/api/v1/agents/register/x402";
constHEADERS = { "content-type": "application/json" };
constBODY = JSON.stringify({ name: "my-agent", amountUsd: 1.1 });
// 1. Ask without paying. The 402 body lists what the server accepts.const challenge = awaitfetch(URL, { method: "POST", headers: HEADERS, body: BODY });
if (challenge.status !== 402) thrownewError("unexpected status " + challenge.status);
const paymentRequired = await challenge.json();
// 2. Sign the payment authorization with your own wallet key.const privateKey = readSecret("payer-private-key") as`0x${string}`; // from your own secret store, never from source codeconst signer = toClientEvmSigner(privateKeyToAccount(privateKey));
const client = newx402Client().register(
paymentRequired.accepts[0].networkasNetwork,
newExactEvmScheme(signer),
);
const payload = await client.createPaymentPayload(paymentRequired);
const xPayment = Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
// 3. Send the same request again with the signed payment.const res = awaitfetch(URL, { method: "POST", headers: { ...HEADERS, "x-payment": xPayment }, body: BODY });
const account = await res.json(); // 201: api_key, credits, claim_token, payment ...console.log(res.status, account.credits_usd);
Giữ khóa riêng của ví trong biến môi trường hoặc kho bí mật, không đặt trong mã nguồn.
Phản hồi đăng ký
Đăng ký thành công trả về 201 với các field sau. API key chỉ xuất hiện một lần ở đây, nên hãy lưu ngay.
Nạp tiền thành công trả về 200 với status là credited, số dư mới tính bằng đô la Mỹ, txHash, cùng paidUsd, creditedUsd và serviceFeeUsd (số tiền đã trả, số tiền được cộng và phí nạp tiền của nền tảng).
1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1200 OK
Content-Type: application/json
{"status":"credited","balance":12.5,"txHash":"0xTX_HASH","paidUsd":1.1,"creditedUsd":1,"serviceFeeUsd":0.1}
1
2
3
4
5
6
7
8
9
// Same three steps against /api/x402/topup; only the URL, body and auth header change.constURL = "https://bazaarlink.ai/api/x402/topup";
constHEADERS = {
"content-type": "application/json",
authorization: "Bearer " + process.env.BAZAARLINK_API_KEY,
};
constBODY = JSON.stringify({ amountUsd: 1.1 });
// ...reuse the challenge / sign / resend code from the registration example.// 200 -> { "status": "credited", "balance": 12.5, "txHash": "0x...", "paidUsd": 1.1, "creditedUsd": 1, "serviceFeeUsd": 0.1 }
Đọc giới hạn hiện tại
GEThttps://bazaarlink.ai/api/x402/topup
GET /api/x402/topup trả về minUsd, maxUsd và network mà không cần xác thực.
1
curl https://bazaarlink.ai/api/x402/topup
1
{"minUsd":1,"maxUsd":50,"network":"eip155:196"}
Thanh toán trùng và gửi lại
Khoản ủy quyền đã ký chỉ dùng được một lần. Máy chủ nhận diện thanh toán lặp trước khi liên hệ mạng thanh toán, nên thử lại không khiến bạn bị tính hai lần.
Nạp: gửi lại thanh toán đã được ghi có trả về 200 với status là already_credited.
Đăng ký: trong 15 phút, cùng thanh toán đã ký trả về cùng phản hồi 201 có API key, nên có thể thử lại an toàn khi mạng lỗi. Sau đó trả về 200 với status là already_registered và txHash thanh toán, không hiển thị lại API key.
Phản hồi lỗi
Các route x402 trả lỗi dưới dạng { "error": { "message", "code" } }. Có hai phản hồi khác biệt: 410 dùng { "error", "code" }, còn 429 dùng { "error" } kèm header Retry-After.
HTTP
Mã
Giải thích
400bad_request
Body không hợp lệ: sai kiểu, thiếu name hoặc có field không xác định.
400topup_unavailable
Không thể nạp cho tài khoản này.
401unauthenticated
Chỉ áp dụng cho nạp: không có API key hoặc session hợp lệ.
402(payment requirements body)
Chưa có thanh toán dùng được. Body chứa yêu cầu, hãy ký và gửi lại. Lỗi này cũng trả về khi thanh toán không khớp yêu cầu hoặc xác minh thất bại.
402payment_amount_too_low
Số tiền đã quyết toán thấp hơn số tiền yêu cầu.
403geo_blocked
Không thể dùng x402 từ khu vực của bạn.
410agent_register_discontinued
Đăng ký agent đang tắt.
429(Retry-After header)
Quá nhiều đăng ký từ cùng một nguồn mạng. Chờ số giây được nêu trong Retry-After.
502facilitator_error
Không thể xác minh hoặc quyết toán thanh toán. Hãy thử lại sau.
502settlement_error
Đã nhận thanh toán nhưng không thể ghi có. Gửi lại cùng thanh toán thay vì ký thanh toán mới.
502registration_error
Đã nhận thanh toán nhưng không thể tạo tài khoản. Gửi lại cùng thanh toán thay vì ký thanh toán mới.
503disabled / runtime_disabled
x402 đang tắt hoặc chưa được cấu hình.
503asset_unavailable / dedup_unavailable
Không thể kết nối một thành phần phụ thuộc(cấu hình asset, kiểm tra trùng hoặc kiểm tra nạp). Hãy thử lại sau.
503signup_disabled / agent_register_unavailable
Đăng ký tạm thời bị tắt hoặc không thể dùng.
Bàn giao tài khoản cho một người
Gửi upgrade_url trong phản hồi cho chủ tài khoản. Sau khi họ đăng nhập và nhận tài khoản, API key và số dư chuyển sang tài khoản của họ. Hãy nhận trước claim_expires.
1
https://bazaarlink.ai/claim?token=<claim_token>
Mạng và asset
Hiện là USDT0 trên X Layer, được quyết toán qua x402 facilitator của OKX. Áp dụng phí nạp tiền của nền tảng, nên số dư bạn nhận thấp hơn số tiền đã trả (xem bảng giá). Thanh toán được quyết toán trên chuỗi và không thể hoàn tác, vì vậy hãy kiểm tra số tiền và mạng trước khi ký.