x402集市:从服务发现到支付
一个实战演示:AI 代理发现 API、收到 402 响应、通过协调器支付、然后重试获取结果
一键发币: x402兼容 | Aptos | X Layer | SUI | SOL | BNB | ETH | BASE | ARB | OP | Polygon | Avalanche
大多数 API 市场仍然假设有人类参与其中——创建账户、添加银行卡、生成密钥、管理用量。这些摩擦是你的 AI 代理无法处理的。
Bazaar + x402 颠覆了这种模式。你的代理可以发现服务、收到带有支付详情的 HTTP 402(需要付费)响应、进行支付(通常使用 Base 上的 USDC)、携带支付证明重试相同的请求,然后 API 响应——无需账户,无需订阅。
在本文结束时,你将拥有一个可运行的演示,展示完整的端到端流程:列表 → 发现 → 402 → 支付 → 重试 → 使用。
1、你将构建什么
- 🧭 发布一个最小的 Bazaar 风格的列表,让你的代理可以发现
- 💳 模拟 x402 支付流程(HTTP 402 → 协调器结算 → 支付证明)
- 🔁 携带支付证明重试相同的请求,获取 付费 响应
- 🧪 所有操作在一个可在本地运行的 Node.js 脚本中完成
2、系统架构
Agent (buyer) ──> Bazaar catalog ──> Service endpoint
│ │
│ (Request) │ If unpaid:
│──────────────────────────────────> │ returns HTTP 402 + payment details
│ │
│ --pay via Facilitator------------> Facilitator (verifies/settles, returns proof)
│ │
│ (Retry + proof header) │
└──────────────────────────────────> │ Returns the result
组件(快速概览)
- Bazaar:简单的发现层,返回包含名称、价格、资产、网络的列表信息。
- Service(服务):你的 API 端点,要求按请求付费。如果未支付,它会返回 HTTP 402 和支付详情。
- x402 Facilitator(协调器):验证/结算客户端的支付,并颁发你的服务可以信任的支付证明。
- Agent(代理):一个精简的买方脚本,负责发现服务、调用服务、处理 402、通过协调器支付、携带证明重试并打印结果。
3、实现阶段
代码将分为两部分:卖方和买方。
3.1 项目设置
mkdir x402-baazar
cd x402-baazar
npm init -y
3.2 安装依赖
npm i @coinbase/cdp-sdk @coinbase/x402 dotenv express viem x402-express x402-fetch
我们将首先构建一个简单的石头-纸-剪刀端点。然后,我们将把它与 x402 集成,使每个请求都可以付费,并提供必要的配置以便在 Bazaar 中列出服务。创建一个名为 index.js 的文件。
3.3 使用 Express 设置端点
import express from "express";
const moves = ["rock", "paper", "scissors"];
function getOutcome(player, server) {
if (player === server) return "draw";
if (
(player === "rock" && server === "scissors") ||
(player === "paper" && server === "rock") ||
(player === "scissors" && server === "paper")
) {
return "win";
}
return "lose";
}
const app = express();
app.use(express.json());
app.post("/rps/play", (req, res) => {
try {
const { move } = req.body;
if (!move || !moves.includes(move)) {
res.status(400).send({
error: "Move must be rock, paper, or scissors"
});
return;
}
const serverMove = moves[Math.floor(Math.random() * moves.length)];
const outcome = getOutcome(move, serverMove);
res.send({
playerMove: move,
serverMove,
outcome
});
} catch (err) {
res.status(500).send({ error: "Internal server error" });
}
});
app.listen(4021, () => {
console.log(`Server listening at http://localhost:4021`);
});现在为上述端点设置 x402 和 Bazaar 所需的配置
// … existing imports
import { paymentMiddleware } from "x402-express";
import { facilitator } from "@coinbase/x402";
// after `app.use(express.json())`
app.use(
paymentMiddleware(
"0xB1De43C2Ca1195258FEE160adAcB1820c3776B7D",
{
"POST /rps/play": {
price: "$0.001", // USDC testnet price
network: "base",
config: {
name: "Rock-Paper-Scissors",
description: "Pay to play a simple game of Rock-Paper-Scissors.",
discoverable: true,
inputSchema: {
type: "object",
properties: {
move: {
type: "string",
enum: ["rock", "paper", "scissors"],
description: "Your move"
}
},
required: ["move"]
},
outputSchema: {
type: "object",
properties: {
playerMove: { type: "string" },
serverMove: { type: "string" },
outcome: { type: "string" }
}
}
}
}
},
{
facilitator
}
)
);
// before `app.post("/rps/play"…`paymentMiddleware 将 x402 作为 Express 中间件集成到本项目中(在这里了解更多关于 Express 中间件的信息)。
它接受两个参数:
- 收款地址 — 接收该端点付款的钱包地址。
- Bazaar 配置 — 描述你在 Bazaar 目录中服务元数据,使 AI 代理可以发现它。
配置中的 discoverable 标志设置为 true,这确保你的 API 会自动列在 Bazaar 目录中。
注意:要使你的 API 可被 Bazaar 索引,你必须将其部署到公有云(例如 Railway、AWS 等),并确保它可以被公开访问。
接下来,让我们创建一个模拟买方的简单函数:
- 它查询 Bazaar 目录以列出可用的服务。
- 选择我们的石头-纸-剪刀服务。
- 在每次请求时支付 USDC 来玩游戏。
现在创建另一个名为 buyer.js 的文件,从列出目录开始:
const listCatalog = async () => {
const response = await fetch(
"https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources"
);
const res = await response.json();
console.log(res);
};
const run = async () => {
const catalog = await listCatalog();
};
run();这将返回一个对象数组:
{
"items": […]
}
现在我们有了服务列表,在发起调用之前还需要设置一些前置条件:
钱包设置 — 我们需要一个钱包来支付服务费用。最快的选择是使用 CDP 钱包,它将所有复杂性抽象为两行代码。或者你也可以使用自己的钱包,但需要自己处理完整的 viem 配置。
发起 API 调用 — 有两种方式:
- 手动方式:使用 fetch 或 axios 调用 API,收到 402 Payment Required 响应,进行支付,然后重试。
- 自动方式:使用 CDP 封装的 fetch 或 axios,它们会自动处理整个支付流程。
在本教程中,我们将使用 x402-fetch 来封装 fetch。
import { CdpClient } from "@coinbase/cdp-sdk";
import dotenv from "dotenv";
import {
wrapFetchWithPayment,
decodeXPaymentResponse
} from "x402-fetch";
dotenv.config();
// Setup CDP account or bring your own wallet
const cdp = new CdpClient();
const cdpAccount = await cdp.evm.getAccount({
name: "buyer-account"
});
// feel free to enable this in testnet, perks for using CDP 😅
// await cdp.evm.requestFaucet({
// address: cdpAccount.address,
// network: "base-sepolia",
// token: "usdc"
// });
// providing x402 super power to our good old `fetch`
const fetchWithPayment = wrapFetchWithPayment(fetch, cdpAccount);
// … previous listCatalog function
const run = async () => {
try {
const catalog = await listCatalog();
// choosing a service, assuming that it's our RPS API
const service = catalog.items[0];
const response = await fetchWithPayment(service.resource, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ move })
});
const result = await response.json();
console.log("Game result:", result);
const paymentResponse = decodeXPaymentResponse(
response.headers.get("x-payment-response")
);
console.log(paymentResponse);
} catch (error) {
console.log(error);
}
};
run();使用 fetchWithPayment 可以确保当 API 返回 402 Payment Required 时,支付会被自动处理并且请求会自动重试——因此你无需自己管理支付流程即可获得结果。
4、运行应用
卖方
node index.ts
买方
node buyer.js
你将看到:
- 服务器启动
- 买方发现服务
- 第一次调用返回 HTTP 402 及支付详情
- 测试网协调器颁发收据
- 携带 X-PAYMENT 头重试
- 服务器返回有效响应
5、从演示到生产环境的映射
- Bazaar UI 和目录:在生产环境中,这是一个带有评分、定价、延迟和网络信息的托管目录。你的代理会选择匹配预算和政策约束的服务提供商。
- x402:模式完全相同——服务对未支付请求返回 402,代理通过协调器完成结算,然后携带支付证明头重试完全相同的 HTTP 请求。
- 协调器:在生产环境中,你会使用 Coinbase 的默认协调器处理 Base 上的 USDC(或者运行自己的协调器/选择社区协调器)。它的职责是:验证支付并颁发你的服务可以信任的支付证明。
- 服务:你的 API 应该将 402 视为一份合约:明确指定金额、资产、网络、卖家和协调器 URL,然后在重试时验证协调器的支付证明后再返回数据。
6、加固与扩展
- 重放保护:将支付证明绑定到
paymentRequestId+ 方法 + 路径 + 查询参数,并设置快速过期。注意:CDP 协调器默认设计已考虑这一点——提供 60 秒的支付和重试窗口。 - 分级响应:提供免费预览,对高分辨率/长时间运行收费。
- 动态定价:在 402 响应体中根据输入大小(如音频秒数、token 数)报价。
- 服务提供商切换:你的代理可以比较评分/价格/延迟,在工作流中途切换提供商,继续执行。
- 链上收据:包含交易哈希和协调器证明,将链下工作与链上支付锚定。
7、结束语
你刚刚运行了一个完整的、对代理友好的 Bazaar + x402 循环:发现服务,调用并收到 402 Payment Required 状态,通过协调器支付,携带证明重试,并获得付费结果——无需账户,无需订阅,按请求付费。
原文链接: Ship a 402-Powered API Bazaar with x402 — From Discovery to Paid Response in One Script
DefiPlot翻译整理,转载请标明出处
免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。