创建 x402 支付保护服务器
使用 Express.js 和 Hono 创建 x402 支付保护服务器。适用于构建返回 402 Payment Required 的资源服务器,设置支付中间件,配置受保护的路由,实现多网络支持(AVM+EVM+SVM),集成支付墙 UI,构建促进者服务器,或实现动态定价。强触发词包括“创建 x402 服务器”,“向 Express 添加支付中间件”,“用 x402 保护路由”,“设置支付门控 API”,“hono 支付中间件”,“402 支付所需服务器”,“x402 express 服务器”,“x402 hono 服务器”,“构建促进者服务器”,“费用抽象服务器”。
创建 x402 支付保护服务器
构建使用 Express.js 或 Hono 中间件的 TypeScript 服务器,以 Algorand (AVM) 支付保护 API 端点。
先决条件
在创建支付保护服务器之前:
- 安装 Node.js 18+
- 一个 Algorand 地址 接收支付(58个字符地址)
- 一个促进者 —— 要么运行你自己的,要么使用
https://facilitator.goplausible.xyz - 初始化的 TypeScript 项目 带有
tsconfig.json
核心工作流程:基于中间件的支付门控
服务器中间件拦截对受保护路由的请求,检查有效的 X-PAYMENT 头,要么返回 402(先支付),要么传递给路由处理器(支付已验证)。
请求 → 中间件检查 X-PAYMENT 头
├── 没有头 → 返回带有 PaymentRequirements 的 402
├── 有头 → 转发到促进者
│ ├── verify() 失败 → 返回 402
│ └── verify() 通过 → settle() → 传递给路由处理器
└── 路由不受保护 → 传递
如何进行
第 1 步:安装依赖
Express.js:
npm install @x402-avm/express @x402-avm/avm @x402-avm/core express
npm install -D @types/express typescript
Hono:
npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono
npm install -D typescript
Hono 与 Node.js 服务器:
npm install @x402-avm/hono @x402-avm/avm @x402-avm/core hono @hono/node-server
带支付墙 UI(可选):
npm install @x402-avm/paywall
第 2 步:选择中间件变体
有三种中间件变体,从最简单到最可配置:
| 变体 | 用例 | 它创建了什么 |
|---|---|---|
paymentMiddlewareFromConfig |
快速开始,简单应用 | 内部创建 x402ResourceServer |
paymentMiddleware |
需要自定义服务器配置 | 使用你的 x402ResourceServer 实例 |
paymentMiddlewareFromHTTPServer |
需要钩子(API 密钥绕过,日志记录) | 使用带有钩子的 x402HTTPResourceServer |
第 3 步:定义路由
路由将 HTTP 方法 + 路径模式映射到支付配置:
import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
const routes = {
"GET /api/weather": {
accepts: {
scheme: "exact",
network: ALGORAND_TESTNET_CAIP2,
payTo: "YOUR_ALGORAND_ADDRESS",
price: "$0.01",
},
description: "天气数据",
},
"GET /api/premium/*": {
accepts: {
scheme: "exact",
network: ALGORAND_TESTNET_CAIP2,
payTo: "YOUR_ALGORAND_ADDRESS",
price: "$0.10",
},
description: "高级 API 端点",
},
};
第 4 步:应用中间件(Express)
import express from "express";
import { paymentMiddleware, x402ResourceServer } from "@x402-avm/express";
import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
import { HTTPFacilitatorClient } from "@x402-avm/core/server";
const app = express();
const facilitatorClient = new HTTPFacilitatorClient({
url: process.env.FACILITATOR_URL || "https://facilitator.goplausible.xyz",
});
const server = new x402ResourceServer(facilitatorClient);
registerExactAvmScheme(server);
app.use(paymentMiddleware(routes, server));
app.get("/api/weather", (req, res) => {
res.json({ temperature: 72, condition: "sunny" });
});
app.listen(4021);
第 4 步(替代):应用中间件(Hono)
import { Hono } from "hono";
import { paymentMiddleware, x402ResourceServer } from "@x402-avm/hono";
import { registerExactAvmScheme } from "@x402-avm/avm/exact/server";
import { HTTPFacilitatorClient } from "@x402-avm/core/server";
const app = new Hono();
const facilitatorClient = new HTTPFacilitatorClient({
url: process.env.FACILITATOR_URL || "https://facilitator.goplausible.xyz",
});
const server = new x402ResourceServer(facilitatorClient);
registerExactAvmScheme(server);
app.use(paymentMiddleware(routes, server));
app.get("/api/weather", (c) => {
return c.json({ temperature: 72, condition: "sunny" });
});
export default app;
第 5 步:添加促进者服务器(可选)
如果你需要自己的促进者而不是公共的:
import express from "express";
import { x402Facilitator } from "@x402-avm/core/facilitator";
import { registerExactAvmScheme } from "@x402-avm/avm/exact/facilitator";
import { ALGORAND_TESTNET_CAIP2 } from "@x402-avm/avm";
import algosdk from "algosdk";
const secretKey = Buffer.from(process.env.AVM_PRIVATE_KEY!, "base64");
const address = algosdk.encodeAddress(secretKey.slice(32));
const algodClient = new algosdk.Algodv2("", "https://testnet-api.algonode.cloud", "");
// 创建实现 FacilitatorAvmSigner 接口的签名者
const signer = { /* ... 见 EXAMPLES.md 了解完整实现 ... */ };
const facilitator = new x402Facilitator();
registerExactAvmScheme(facilitator, { signer, networks: ALGORAND_TESTNET_CAIP2 });
const app = express();
app.use(express.json());
app.post("/verify", async (req, res) => { /* ... */ });
app.post("/settle", async (req, res) => { /* ... */ });
app.get("/supported", (req, res) => { /* ... */ });
app.listen(4020);
第 6 步:设置环境变量
# 资源服务器
AVM_ADDRESS=YOUR_ALGORAND_ADDRESS_HERE
FACILITATOR_URL=https://facilitator.goplausible.xyz
PORT=4021
# 促进者(如果运行你自己的)
AVM_PRIVATE_KEY=<base64-encoded-64-byte-key>
ALGOD_SERVER=https://testnet-api.algonode.cloud
ALGOD_TOKEN=
FACILITATOR_PORT=4020
重要规则 / 指南
- 无条件注册 AVM 方案 —— 总是调用
registerExactAvmScheme(server)而不加环境变量保护 - 公共路由不受影响 —— 只有在
routes配置对象中列出的路由受到保护 - 路由模式支持通配符 ——
"GET /api/premium/*"匹配所有子路径 - 方法前缀是可选的 ——
"/api/resource"匹配所有 HTTP 方法 - 多网络路由使用数组 —— 为跨链支持传递数组到
accepts - 促进者 URL 是必需的 —— 资源服务器必须能够到达促进者
- 价格字符串使用 USD 符号 ——
"$0.01"解析为适当的资产金额
常见错误 / 故障排除
| 错误 | 原因 | 解决方案 |
|---|---|---|
| 所有路由返回 402 | 路由模式太宽泛 | 检查路由模式匹配预期路径 |
402 但没有 accepts 数组 |
AVM 方案未在服务器上注册 | 调用 registerExactAvmScheme(server) |
| 促进者无法到达 | 错误的 URL 或促进者未运行 | 检查 FACILITATOR_URL 和促进者状态 |
paymentMiddleware 不是函数 |
错误的导入 | 从 @x402-avm/express 或 @x402-avm/hono 导入 |
| 浏览器中的 CORS 错误 | 缺少 CORS 中间件 | 在支付中间件之前添加 cors() 中间件 |
| 支付墙未显示 | 缺少 mimeType: "text/html" |
为浏览器路由在路由配置中设置 mimeType |
| 动态定价错误 | 价格函数抛出 | 确保价格函数处理所有边缘情况 |
| 验证/结算时 500 | 促进者签名者错误 | 检查促进者日志,验证私钥 |
参考资料 / 进一步阅读
- REFERENCE.md - 详细的中间件 API 参考
- EXAMPLES.md - 完整的服务器代码示例
- @x402-avm/express 在 npm 上
- @x402-avm/hono 在 npm 上
- GoPlausible x402-avm 示例
- GoPlausible x402-avm 文档