第 08 集:接入 x402 微支付:让它能"收钱"
时长:约 6 分钟 | 本集产出:智能体自动收款闭环(测试网验证:付 0.001 USDC → 拿到回答)
1. 本集目标
给智能体装上"收银台"——x402 微支付:
-
别人/别的 AI 调用你的智能体时,先付 0.001 USDC,付款验证通过后服务端才干活返回结果
-
全程自动:不用人工确认,钱直接进你的钱包(第 3 集的钱包)
我们的真实闭环(已跑通):客户端构造 0.001 USDC 转账 → 服务端用 Solana RPC 链上验证 → 验证通过 → AI 干活返回 → 记账。国内还配了支付宝 0.01 元通道。
2. x402 是什么(30 秒)
x402 = HTTP 402 付费协议:像给 API 调用"贴邮票"。
-
客户端请求 → 服务端返回
402 Payment Required + 价格信息
-
客户端付 USDC(链上转账)→ 带上付款凭证再次请求
-
标准流程:请求 → 402 报价 → 付款上链 → 带凭证重试 → 验证 → 交付。
3. 前置条件
-
第 5 集的 A2A Server 代码(server.mjs)
-
第 3 集的钱包(收款地址)+ devnet SOL + 一些 devnet USDC
-
一个 AI API key(可选,用于真实回答;没有也能验证付款闭环,返回占位)
4. 操作步骤
Step 1:装依赖(1 分钟)
npm install @solana/web3.js bs58 dotenv
Step 2:写付款验证模块(5 分钟)
创建 solana-verify.mjs(核心:验证付款真的到账了):
import { Connection } from '@solana/web3.js';
import 'dotenv/config';
const RPC = process.env.SOLANA_RPC_URL || 'https://solana-rpc.publicnode.com';
const WALLET = process.env.SOLANA_WALLET; // 第3集钱包地址(收款方)
const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; // USDC 官方 mint
const PRICE_MIN = 1000; // 0.001 USDC = 1000 最小单位
export async function verifyPayment(txBase64) {
// 1. 解析交易
const conn = new Connection(RPC);
// 交易签名来自客户端提交的 base64 交易
const decoded = JSON.parse(Buffer.from(txBase64, 'base64').toString('utf8'));
// 2. 用 RPC 查这笔交易(真实链上验证)
const tx = await conn.getParsedTransaction(decoded.signature, { maxSupportedTransactionVersion: 0 });
if (!tx) return { ok: false, reason: 'tx not found on chain' };
// 3. 遍历转账指令,确认: 收款=你的钱包 & 币种=USDC & 金额达标
const transfers = tx.transaction.message.instructions.filter(ix =>
ix.parsed?.type === 'transferChecked' && ix.parsed.info.mint === USDC_MINT
);
const paid = transfers.some(t =>
t.parsed.info.destination === WALLET &&
Number(t.parsed.info.tokenAmount.amount) >= PRICE_MIN
);
return paid ? { ok: true } : { ok: false, reason: 'amount/wallet mismatch' };
}
⚠️ 解析坑(我们踩过):Solana 交易解析要用 jsonParsed 格式读 info.tokenAmount.amount,别用 json 格式(data 编码有异常)。RPC 用 https://solana-rpc.publicnode.com(国内可访问),api.mainnet-beta.solana.com 直连常超时。
Step 3:给 server 加付款闸门(3 分钟)
改 server.mjs,在 /tasks/send 前加中间件: