Skip to content

lookteas/x402-api-server

Repository files navigation

x402-mainnet 服务(FastAPI)

使用 FastAPI 集成 x402 支付协议的完整示例,包含:

  • 支付验证与结算中间件(Verify / Settle)
  • 业务路由(/mint/mint1/mint10/premium/mint
  • 自定义付费页(Paywall 页面中文与品牌化)
  • 结算结果持久化到 MySQL、交易哈希发布到 Redis
  • 调试与观测接口(/debug-mint

适合用作自有 API 与 x402 Facilitator 对接的最小可运行示例,也可作为生产环境集成参考。


总览

  • 框架:FastAPI
  • 支付协议:x402(验证与结算均由 Facilitator 提供)
  • 语言与运行:Python >=3.10(开发使用 3.11)
  • 依赖:cdp-sdkaiomysqlredis.asynciopython-dotenvuvicorn
  • 端口:3001(本地运行)

核心路径:

  • 请求头:客户端需在请求中携带 X-PAYMENT(Base64(JSON))
  • 验证:middleware/x402_verify_guard.py → facilitator.verify
  • 路由:main.py → /mint* 与 /premium/mint
  • 结算:middleware/x402_verify_guard.py → facilitator.settle
  • 数据:db/mysql_async.py(写入 x402_data 表)与 db/redis_async.py(发布 tx_hash)
  • 调试:/debug-mint 返回最近结算、错误与环境配置快照

目录结构

mainnet/
├── main.py                      # FastAPI 入口与路由注册
├── config/
│   ├── settings.py              # 统一集中配置(环境读取/路由/付费页)
│   ├── config.py                # 兼容旧接口的适配层
│   ├── config_routes.py         # 路由集合与价格策略(MINT、PREMIUM 前缀)
│   └── config_paywall.py        # 付费页配置生成与索引
├── middleware/
│   ├── x402_verify_guard.py     # 验证与结算中间件(核心)
│   └── payment_capture.py       # 捕获响应头与错误快照(外层中间件)
├── db/
│   ├── mysql_async.py           # 异步 MySQL 连接池与插入接口
│   └── redis_async.py           # 异步 Redis 客户端与发布接口
├── templates/
│   ├── paywall_custom.py        # 中文与品牌化的付费页模板
│   └── branding.py              # 品牌与文案配置(中文)
├── scripts/
│   ├── redis_subscriber.py      # 示例订阅器(打印接收的 tx_hash)
│   └── redis_publish_test.py    # 示例发布器(向频道发布模拟 tx_hash)
├── request_flow.svg             # 简化版请求流程图
├── request_flow_tx_hash_highlight.svg  # 详细流程图(带 tx_hash 流)
├── pyproject.toml               # 项目依赖与构建配置
├── .env / .env-local            # 环境变量文件(示例/本地覆盖)
└── uv.lock                      # 开发工具锁文件

配置

集中由 config/settings.py 管理。所有配置可通过 .env 或系统环境变量注入。

必需:

  • NETWORK:x402 支付网络(如 basebase-sepolia
  • ADDRESS:收款地址(pay_to
  • CDP_API_KEY_IDCDP_API_KEY_SECRET:CDP SDK Key(用于构建 Facilitator 配置)

可选:

  • FACILITATOR_URL:显式指定 Facilitator 服务地址(不设则通过 cdp.x402.create_facilitator_config 自动生成)
  • ENV:运行环境字符串(prod/production 视为生产环境)
  • DEBUG_ERRORS:在非生产环境启用更详尽错误返回(1/true
  • MYSQL_HOSTMYSQL_PORT(默认 3306)、MYSQL_USERMYSQL_PASSWORDMYSQL_DATABASE
  • REDIS_URL:Redis 连接串(默认 redis://localhost:6379/7
  • X402_TX_HASH_CHANNEL:发布交易哈希的频道(默认 error_x402_txh_hash
  • 代理:HTTP_PROXYHTTPS_PROXYNO_PROXY(仅用于调试输出,不影响功能)

付费与路由:

  • config_routes.py 定义 MINT_ROUTES/mint/mint1/mint10)与 ROUTE_POLICY(价格/币种/模板)
  • config_paywall.py 根据路由策略自动生成 PAYWALL_ROUTES,包括 PREMIUM_PREFIX=/premium/ 前缀匹配(match: prefix
  • 自定义付费页通过 templates/paywall_custom.py 注入中文与品牌样式,get_paywall_config 提供前端所需 cdp_client_key 等信息

示例 .env

ENV=local
NETWORK=base
ADDRESS=0xYourPayToAddress
CDP_API_KEY_ID=your_public_key_id
CDP_API_KEY_SECRET=your_secret_key
# FACILITATOR_URL=https://facilitator.example.com

MYSQL_HOST=127.0.0.1
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=passwd
MYSQL_DATABASE=yourdata

REDIS_URL=redis://localhost:6379/7
X402_TX_HASH_CHANNEL=x402_tx_hash
DEBUG_ERRORS=1

启动

  • 安装依赖(使用 uv):
    • uv sync(根据 pyproject.toml 安装依赖并创建本地 .venv,生成/更新 uv.lock
    • 如需新增依赖:uv add <package>(同时更新 pyproject.tomluv.lock
  • 运行(使用 uv):
    • uv run uvicorn main:app --reload --port 3001(推荐,热重载开发)
    • uv run python main.py(使用内置 uvicorn.run,默认 127.0.0.1:3001
  • CORS:已放开全部来源与头,且暴露 x-payment-response 响应头
  • 代理头:proxy_headers=Trueforwarded_allow_ips="*"(生产建议限制来源)

接口与路由

  • GET/POST /mint/mint1/mint10
    • 需携带 X-PAYMENT 请求头(Base64(JSON))
    • 验证通过后进入业务逻辑,业务返回 2xx 将触发结算与哈希获取
  • GET/POST /premium/mint
    • PREMIUM_PREFIX 前缀策略保护,价格与模板可在 ROUTE_POLICY 中调整
  • GET/POST /debug-mint
    • 返回统一调试快照:请求、环境、配置与 status(最近支付/错误/结算原始返回)

路由与价格来源:

  • config_routes.py → ROUTE_POLICY
    • /mint$0.1、USD
    • /mint1$1、USD
    • /mint10$10、USD(使用自定义付费页模板)
    • PREMIUM_PREFIX=/premium/$0.01、USD(前缀匹配)

请求说明(X-PAYMENT)

  • 客户端需构造 X-PAYMENT 请求头,内容为支付凭证 JSON 的 Base64 字符串
  • 形如:
X-PAYMENT: Base64(
  {
    "payload": {
      "authorization": { "value": "<atomic-amount>", ... },
      "signature": "<eip712-signature>"
    },
    ...
  }
)
  • 后端在 x402_verify_guard.py 中解析:
    • safe_base64_decode → json.loads → PaymentPayload(**dict)
    • 根据路由价格生成 PaymentRequirements 并调用 facilitator.verify

模块功能

  • middleware/payment_capture.py
    • 外层中间件;在响应阶段解析 x-payment-response 头(Base64(JSON))
    • 更新最近一次支付信息 _LAST_PAYMENT_INFO;失败时记录 _LAST_PAYMENT_ERROR
    • 保留签名与原始支付载荷,便于调试“旧签名/截止时间”类问题
  • middleware/x402_verify_guard.py
    • 内层中间件;对匹配路径执行支付验证与结算
    • 验证:facilitator.verify,失败返回 402(浏览器则返回 HTML 付费页)
    • 业务:call_next,仅当业务返回 2xx 才进行结算
    • 结算:facilitator.settle,读取 transaction 作为 tx_hash
    • 持久化:写入 MySQL(x402_data 表),并发布到 Redis 频道
    • 观测:最近一次结算原始返回 _LAST_SETTLE_RAW 存档(便于 /debug-mint 查看)
  • db/mysql_async.py
    • 基于 aiomysql 的连接池;提供 insert_x402_data(record) 写入接口
  • db/redis_async.py
    • 基于 redis.asyncio 的发布接口;初始化失败时安全降级并记录日志
  • templates/paywall_custom.py
    • 注入中文文案与品牌样式,监听异步渲染替换默认英文模板内容
  • scripts/redis_subscriber.py / scripts/redis_publish_test.py
    • 订阅/发布示例脚本,辅助验证 Redis 推送

请求流程

流程图:

完整流程图(含 tx_hash 获取与持久化)

简化流程图(序列图)

摘要:

  1. 客户端发起请求(携带 X-PAYMENT
  2. Verify Guard 调用 facilitator.verify 验证凭证
  3. 验证通过进入路由处理;业务返回 2xx 才结算
  4. 调用 facilitator.settle 获取 tx_hash
  5. 将 Base64(JSON) 的结算结果写入响应头 x-payment-response
  6. 写入 MySQL x402_data(含 txh_hashfrom_addressamount 等)
  7. 发布 tx_hash 到 Redis 频道
  8. 客户端可解码响应头获取 tx_hash 等信息

数据持久化(MySQL)

  • 表名:x402_data
  • 插入字段(与代码一致):
    • from_addressamountBIGINT)、to_addresssignaturesign_jsonJSON
    • statustoken_statustxh_hashmintstart_timeend_time(均 INT/VARCHAR 视情况)

示例建表 SQL(可按需调整类型与索引):

CREATE TABLE IF NOT EXISTS `x402_data` (
  `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
  `from_address` VARCHAR(64),
  `amount` BIGINT,
  `to_address` VARCHAR(64),
  `signature` VARCHAR(512),
  `sign_json` JSON,
  `status` INT,
  `token_status` INT,
  `txh_hash` VARCHAR(80),
  `mint` VARCHAR(32),
  `start_time` INT,
  `end_time` INT,
  PRIMARY KEY (`id`),
  KEY `idx_txh_hash` (`txh_hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

消息发布(Redis)

  • 频道名:X402_TX_HASH_CHANNEL(默认 error_x402_txh_hash
  • 发布内容:tx_hash 文本
  • 订阅示例:
    • python scripts/redis_subscriber.py(会打印收到的哈希)
  • 发布示例:
    • python scripts/redis_publish_test.py 0xdeadbeef...(不传参则生成随机哈希)

异常处理

  • 验证异常:返回 402 Payment Required(浏览器请求返回 HTML 付费页)
  • 网络或上游故障:捕获异常并返回 500(在 DEBUG_ERRORS=1 时包含 type/correlationId 等细节)
  • 业务非 2xx:跳过结算,直接返回原响应
  • 结算失败:记录错误并返回原响应(或按需返回 402),同时保留最近失败信息供调试
  • MySQL/Redis:写入/发布失败仅记录日志,不阻塞主流程

调试与观测

  • GET/POST /debug-mint 返回统一调试快照:
    • method/path/query/url/headers/client/json/body_text/body_length
    • env: HTTP_PROXYHTTPS_PROXYNO_PROXYENVDEBUG_ERRORS
    • config: networkfacilitator_url
    • status: last_paymentlast_errorlast_settle_raw
  • 最近一次支付/错误由外层中间件在响应阶段记录;结算原始返回由内层中间件保存

快速联调建议

  • 前端或客户端用官方 x402 SDK 生成 X-PAYMENT 请求头
  • 逐步验证:
    • 未携带头 → 应返回 402(浏览器看到付费页)
    • 携带无效签名/过期凭证 → 返回 402(错误描述)
    • 携带有效凭证 → /mint* 返回 2xx,响应头含 x-payment-response
  • 查数与观测:
    • MySQL 表是否有新增记录
    • Redis 频道是否收到 tx_hash
    • /debug-mintstatus.last_payment.tx_hashstatus.last_settle_raw.transaction

安全与部署提示

  • CORS 与代理头在示例中处于较为开放的配置,生产环境请按需收紧(白名单域名、forwarded_allow_ips
  • 付费页模板为前端 HTML 注入,请确保自定义脚本来源可信并避免 XSS
  • 建议为 x402_data 添加必要的唯一键或业务索引,避免重复写入
  • 结合 API 网关/反向代理统一接入层的限流与鉴权策略

变更与维护

  • 路由与价格只需修改 config/config_routes.py → ROUTE_POLICYROUTE_PATHS
  • 付费页样式与文案修改 templates/branding.pytemplates/paywall_custom.py
  • 环境与集中配置通过 config/settings.py 一处维护,config/config.py 保留兼容接口

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages