XPayLabs 部署全攻略:从零搭建你自己的多链加密货币支付网关
XPayLabs 是一款生产级的自托管加密货币支付网关,支持多链收款和多商家架构。本文将从零开始,完整演示部署全过程。
你要部署的是什么东西?
整个 XPayLabs 由 11 个 Docker 服务组成:
| 服务 | 职责 | 技术栈 |
|---|---|---|
mysql | 持久化数据库 | MySQL 8.0 |
redis | 缓存、队列、nonce 存储 | Redis 7 Alpine |
sui-node-service | SUI 区块链 RPC 代理 | Express (Node.js) |
xpay-tron | TRON 链扫描器 | Spring Boot 3.4 (Java 17) |
xpay-sui | SUI 链扫描器 | Spring Boot 3.4 (Java 17) |
xpay-eth | EVM 扫描器 (ETH, BSC, Polygon, Avalanche) | Spring Boot 3.4 (Java 17) |
xpay-user | 用户端 API(收款订单、余额查询等) | Spring Boot 3.4 (Java 17) |
xpay-merchant | 商家后台 API | Spring Boot 3.4 (Java 17) |
merchant-vue | 商家管理后台前端 | Vue 3 + Element Plus (Nginx) |
checkout | 收银台支付页面 | Vue 3 + Vite 7 (Nginx) |
gateway | 反向代理(统一入口) | Nginx Alpine |
所有 Java 服务共用同一个基础镜像 ghcr.io/yan253319066/xpay-java,通过 command 参数启动不同的 JAR 包。
前置条件
- Docker 24+ 和 Docker Compose v2+
- Linux 服务器(最低 4 GB 内存,推荐 8 GB)
- 两个域名(商家后台 + 收银台)
- SSL 证书(Let's Encrypt 免费或商业证书)
- 各区块链的 RPC 节点地址
第一步:克隆部署仓库
git clone https://github.com/yan253319066/XPayLabs-docker.git
cd XPayLabs-docker
这个仓库包含了部署所需的一切:docker-compose.yml、Nginx 配置、SQL 初始化脚本、环境变量模板。
第二步:配置环境变量
cp .env.example .env
编辑 .env 文件,逐项说明如下:
数据库与缓存
MYSQL_ROOT_PASSWORD=<强随机密码>
DB_USERNAME=root
DB_PASSWORD=<与上面相同或不同>
REDIS_PASSWORD=<可选,留空则不设密码>
MySQL 首次启动时自动执行 ./sql/init.sql 初始化数据库。Redis 密码留空表示不启用认证。
加密密钥(关键)
ENCRYPTION_KEY=<必须恰好32个字符>
JWT_SECRET_KEY=<随机字符串>
SKIP_SIGN_SECRET=<64位十六进制密钥>
ENCRYPTION_KEY:AES-256-CBC 密钥,必须恰好 32 个字符。用于sui-node-service和xpay-sui加密 SUI 私钥JWT_SECRET_KEY:xpay-merchant用于签发商家后台会话的 JWT TokenSKIP_SIGN_SECRET:SkipSign 功能的 HMAC-SHA256 签名密钥,用于服务间内部请求签名
公网域名
XPAY_PAY_DOMAIN=https://pay.your-domain.com/checkout
XPAY_API_DOMAIN=https://api.your-domain.com
Java 服务会使用这两个域名构造回调 URL 和收银台跳转地址。配置好 DNS 后必须改为你实际的域名。
区块链 RPC 配置
EVM 链(ETH, BSC, Polygon, Avalanche):
ETH_NETWORKS=ETH,ETH_SEPOLIA,BSC,BSC_TEST,POLYGON,POLYGON_AMOY,AVAX_C_CHAIN,AVAX_FUJI_TEST
RPC_ETH=https://0xrpc.io/eth,https://rpc.flashbots.net
SCAN_ETH=15
ETH_NETWORKS:逗号分隔的活跃网络列表RPC_*:逗号分隔的 RPC 地址(扫描器按顺序依次尝试,实现故障转移)SCAN_*:区块扫描间隔(秒)
主网建议使用商业 RPC 服务商(Alchemy、Infura、QuickNode),测试网可以用公共 RPC。
TRON:
TRON_NETWORKS=TRON,TRON_TEST
NODE_TRON=grpc.trongrid.io:50051
SOLIDITY_TRON=grpc.trongrid.io:50052
APIKEY_TRON=<你的trongrid-api-key>
TRON 使用 gRPC 协议而非 JSON-RPC。扫描器同时连接 full node 和 solidity node。生产环境需要在 trongrid.io 申请 API Key。
SUI:
SUI 无需在 .env 中配置 RPC。xpay-sui 扫描器通过 Docker 内网连接 sui-node-service(Express RPC 代理),地址为 http://sui-node-service:3001。
端口映射
HOST_PORT_GATEWAY_HTTP=180
HOST_PORT_MYSQL=13306
HOST_PORT_REDIS=16379
HOST_PORT_XPAY_USER=18077
HOST_PORT_XPAY_MERCHANT=18078
HOST_PORT_XPAY_ETH=18076
HOST_PORT_XPAY_TRON=18075
HOST_PORT_XPAY_SUI=18074
HOST_PORT_SUI_NODE=13001
只有 180 端口(Nginx 网关)需要暴露到公网。其他端口仅供内部通信和调试使用。
第三步:启动服务
docker compose up -d
Docker Compose 按依赖顺序启动服务:
mysql和redis最先启动- 链扫描器(
xpay-tron、xpay-eth、xpay-sui+sui-node-service)在 MySQL 就绪后启动 xpay-user在扫描器之后启动xpay-merchant在xpay-user之后启动- 前端服务(
merchant-vue、checkout)在后端就绪后启动 gateway(Nginx)最后启动
验证部署
# 检查所有服务运行状态
docker compose ps
# 查看日志
docker compose logs xpay-user
docker compose logs xpay-eth
# 测试 API
curl http://localhost:180/api/symbol/supportSymbols
第四步:配置 DNS 和 SSL
DNS 记录
将域名指向服务器的公网 IP:
merchant.your-domain.com A <服务器IP>
pay.your-domain.com A <服务器IP>
api.your-domain.com A <服务器IP>
Nginx 网关按路径前缀路由流量:
/checkout/*→ 收银台服务(支付页面)/api/*→ xpay-user API/prod-api/*→ xpay-merchant API/*→ 商家管理后台(默认)
使用 Let's Encrypt 配置 SSL
- 获取证书:
docker run -it --rm -p 80:80 -v "$(pwd)/certs:/etc/letsencrypt" certbot/certbot certonly --standalone -d merchant.your-domain.com -d pay.your-domain.com
- 复制证书:
cp certs/live/merchant.your-domain.com/fullchain.pem certs/merchant.crt
cp certs/live/merchant.your-domain.com/privkey.pem certs/merchant.key
- 修改
docker-compose.yml启用 SSL:
gateway:
ports:
- "180:80"
- "1443:443" # 取消注释
volumes:
- ./nginx/gateway.conf:/etc/nginx/conf.d/default.conf
# 替换为:
# - ./nginx/gateway-ssl.conf:/etc/nginx/conf.d/default.conf
- ./certs:/etc/nginx/certs # 取消注释
-
修改
.env:HOST_PORT_GATEWAY_HTTPS=1443 -
重启网关:
docker compose restart gateway
第五步:创建第一个商家
访问 http://localhost:180(或你的域名)进入商家管理后台:
- 注册账号 — 使用邮箱和密码创建商家账户
- 获取 API 凭证 — 登录后进入 设置 → API 密钥,生成 API Key 和 Secret
- 配置 Webhook — 设置支付通知的回调 URL
- 开始收款 — 系统使用 HD 钱包自动为每笔订单生成充值地址,无需手动配置
使用 API
拿到 API Key 和 Secret 后:
curl -X POST https://api.your-domain.com/v1/collection/create \
-H "Content-Type: application/json" \
-d '{
"sign": "<hmac签名>",
"timestamp": 1717000000000,
"nonce": "<uuid>",
"data": {
"amount": "100.00",
"symbol": "USDT",
"chain": "tron",
"orderId": "order_001"
}
}'
SDK 会自动处理签名逻辑:
- Node.js:
npm install @xpaylabs/node-sdk - Java:Maven Central
com.xpaylabs:xpay-java-sdk
架构详解
多商家设计
XPayLabs 采用平台运营模式。一个部署可入驻无限商家,每个商家拥有:
- 独立的数据隔离(通过
merchant_id字段作用域) - 独立的 API 凭证(HMAC 密钥对)
- 独立的 Webhook 配置
- 可配置的费率(运营者自主定价)
HD 钱包密钥管理
网关采用 BIP-44 分层确定性钱包派生:
m / 44' / coin_type' / 0' / 0 / address_index
- 主种子通过环境变量注入(此 Docker 部署中种子内置于扫描器服务)
- 数据库仅存储派生索引,不存储私钥
- 恢复方式:恢复种子短语 + 重放区块链历史
区块链扫描器原理
每条链有独立的扫描器服务:
- 按配置间隔(2-15 秒)轮询 RPC 节点
- 获取涉及追踪地址的
Transfer事件 - 将事件与待处理的收款订单匹配
- 更新订单状态并加入 Webhook 投递队列
- 等待链特定的确认数后标记为成功
| 链 | 检测方式 | 出块时间 | 建议确认数 |
|---|---|---|---|
| TRON | TRON Grid gRPC API | ~3 秒 | 1-2 |
| Ethereum | JSON-RPC eth_getLogs | ~12 秒 | 12-30 |
| BSC | JSON-RPC 轮询 | ~3 秒 | 15-30 |
| Polygon | JSON-RPC 轮询 | ~2 秒 | 30-100 |
| Avalanche | JSON-RPC 轮询 | ~2 秒 | 10-20 |
| Arbitrum | JSON-RPC 轮询 | ~1 秒 | 10-20 |
| SUI | SUI RPC(通过 sui-node-service) | ~2 秒 | 5-10 |
生产运维
日常监控
- 查看服务状态:
docker compose ps - 查看日志:
docker compose logs -f --tail=100 <服务名> - 日志持久化在
./logs/目录,每个服务有独立的子目录 - 建议使用 Uptime Kuma 等工具监控网关可用性
数据库备份
# 手动备份
docker exec xpay-mysql mysqldump -u root -p xpaylabs > backup_$(date +%Y%m%d).sql
# crontab 自动备份(每天凌晨 3 点)
0 3 * * * docker exec xpay-mysql mysqldump -u root -p$MYSQL_ROOT_PASSWORD xpaylabs > /backups/xpaylabs_$(date +\%Y\%m\%d).sql
更新服务
docker compose pull # 拉取最新镜像
docker compose up -d # 用新镜像重启
ghcr.io/yan253319066/xpay-java 镜像包含所有 Java JAR 包。新版本发布后更新 docker-compose.yml 中的镜像标签即可。
水平扩展
当前架构为单实例部署。如需扩展:
- 读副本:添加 MySQL 从库分担查询压力
- 多扫描器:使用不同 RPC 提供商运行多个扫描器实例实现冗余
- 负载均衡:将多个网关实例放在 TCP 负载均衡器后面
常见问题排查
ghcr.io 镜像拉取失败
镜像托管在公开的 GitHub Container Registry 上,无需登录即可拉取。常见原因:
- 网络环境被屏蔽 — 尝试配置 Docker 代理或使用镜像加速器
- ghcr.io 限流 — 稍后再试
如果确实无法拉取,可以从源码自行构建:
# 构建 Java 服务
cd XPayLabs-java
mvn clean install -P prod -DskipTests
docker build -t ghcr.io/yan253319066/xpay-java .
# 构建前端服务
cd XPayLabs-checkout
docker build -t ghcr.io/yan253319066/checkout .
cd XPayLabs-merchant-vue
docker build -t ghcr.io/yan253319066/merchant-vue .
然后在 docker-compose.yml 中设置 pull_policy: never,或用本地镜像标签覆盖远程镜像名。
MySQL 连接被拒绝
MySQL 首次启动需要 30-60 秒初始化(尤其是导入 SQL 初始化脚本)。检查健康状态:
docker compose logs mysql
docker compose exec mysql mysqladmin ping -h localhost
扫描器检测不到交易
- 检查扫描器日志中的 RPC 错误
- 确认容器可以访问 RPC 地址
- 确认充值地址派生路径与链匹配
- 检查
TRON_NETWORKS或ETH_NETWORKS中包含正确的网络名
端口冲突
如果宿主机 180 端口已被占用,修改 .env 中的 HOST_PORT_GATEWAY_HTTP 为其他可用端口(如 8080)。所有内部服务端口均可重新映射。
运营成本分析
作为支付平台运营者运行 XPayLabs:
| 项目 | 月成本 |
|---|---|
| 服务器 (4 GB 内存, 2 vCPU) | ~¥140-280 |
| RPC 节点 (主网) | ~¥360-1,400 (按链数浮动) |
| 域名 + SSL | ~¥7-35 |
| 合计 | ~¥500-1,700/月 |
假设向商家收取 0.5% 手续费,月处理 50 万美元流水:
| 收入项 | 月收入 |
|---|---|
| 交易手续费 (0.5%) | $2,500 |
| 服务器成本 | -$70-250 |
| 净利润 | ~$2,250-2,430/月 |
总结
XPayLabs 让一条 docker compose up 命令就能拥有完整的加密货币支付基础设施。作为运营者,你需要承担以下运维职责:
- 保护主种子 — 离线生成,存放在硬件钱包或加密保险库中
- 监控服务健康 — 关注扫描器日志和网关可用性
- 备份数据库 — 定期执行 MySQL 备份
- 维护 RPC 节点 — 使用可靠的服务商并配置故障转移
SDK(Node.js 和 Java)、收银台 UI 和商家管理后台以 MIT 协议开源在 github.com/yan25331906…。核心网关引擎为源可用许可(XPay Enterprise License)。
SDK 地址:npm | Maven Central