Docker 一键部署加密支付网关:从零开始完整教程

Docker 一键部署加密支付网关:从零开始完整教程

在电商或 SaaS 项目中集成加密货币支付,很多人第一反应是接入 BitPay 或 Coinbase Commerce。但对于有一定技术能力的团队来说,自托管(Self-Hosted)方案在成本、安全性和品牌体验上都有显著优势。

本文将从零开始,手把手教你用 Docker 部署一个生产级的自托管加密支付网关,并集成到你的应用中。

环境准备

硬件要求

配置项 最低要求 推荐配置
CPU 1 核 2 核
内存 1GB 4GB
磁盘 20GB 50GB (SSD)
网络 公网 IP 公网 IP + 域名

大部分云厂商的入门级 VPS(如阿里云轻量、腾讯云轻量、AWS Lightsail 等)都能满足需求。

软件要求

  • 操作系统:Ubuntu 22.04 / Debian 12 / CentOS 8+(本文以 Ubuntu 22.04 为例)
  • Docker:20.10+
  • Docker Compose:v2+

安装 Docker

bash 复制代码
# 更新包索引
sudo apt update

# 安装依赖
sudo apt install -y ca-certificates curl gnupg lsb-release

# 添加 Docker 官方 GPG 密钥
sudo mkdir -m 0755 -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 添加 Docker 仓库
echo \
  "deb [arch=$(dpkg --print-architecture) \
  signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 安装 Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 验证安装
sudo docker --version
sudo docker compose version

第一步:生成主种子(Master Seed)

种子短语是支付网关的根密钥,所有收款地址都由它派生。这一步必须在离线环境中完成

方式一:使用离线工具生成

下载 iancoleman.io/bip39 的离线版本,在不联网的机器上生成 12 或 24 个单词的 BIP-39 种子:

复制代码
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about

安全警告 :上面的种子是 BIP-39 测试向量,仅用于测试。生产环境绝不可使用。必须在离线、无网络的机器上生成真实种子。

方式二:使用命令行生成(离线)

bash 复制代码
# 使用 openssl 生成 128 位随机数(12 词助记词)
openssl rand -hex 16
# 输出示例: 7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f

# 然后使用 BIP-39 工具将熵转换为助记词(需要离线运行)

记录下生成的 12 或 24 个单词,将其安全保存(纸质备份 + 加密存储)。

第二步:创建项目目录

bash 复制代码
mkdir -p ~/payment-gateway
cd ~/payment-gateway

第三步:配置环境变量

创建 .env 文件:

bash 复制代码
cat > .env << 'EOF'
# 数据库
DB_ROOT_PASSWORD=your_secure_root_password_here
DB_PASSWORD=your_secure_db_password_here

# Redis
REDIS_PASSWORD=your_secure_redis_password_here

# 支付网关
XPAY_MASTER_SEED="your twelve word seed phrase generated offline"
XPAY_WEBHOOK_SECRET=whsec_your_webhook_secret_here
XPAY_API_KEY=xpay_your_api_key_here
XPAY_CHAINS=tron,eth,bsc,polygon

# 链配置(可选,默认使用公共 RPC)
# XPAY_TRON_NETWORK=mainnet
# XPAY_ETH_RPC_URL=https://eth.drpc.org
# XPAY_BSC_RPC_URL=https://bsc.drpc.org
# XPAY_POLYGON_RPC_URL=https://polygon.drpc.org
EOF

注意 :生产环境请将以上密码全部替换为强随机字符串。可以使用 openssl rand -base64 32 生成。

第四步:编写 Docker Compose 文件

创建 docker-compose.yml

yaml 复制代码
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    container_name: gateway-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: xpay_gateway
      MYSQL_USER: xpay
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - gateway-net
    restart: always
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: gateway-redis
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_data:/data
    networks:
      - gateway-net
    restart: always
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  gateway:
    image: ghcr.io/xpaylabs/gateway:latest
    container_name: xpay-gateway
    ports:
      - "8080:8080"
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/xpay_gateway?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
      SPRING_DATASOURCE_USERNAME: xpay
      SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
      SPRING_DATASOURCE_DRIVER_CLASS_NAME: com.mysql.cj.jdbc.Driver
      SPRING_REDIS_HOST: redis
      SPRING_REDIS_PORT: 6379
      SPRING_REDIS_PASSWORD: ${REDIS_PASSWORD}
      XPAY_MASTER_SEED: ${XPAY_MASTER_SEED}
      XPAY_WEBHOOK_SECRET: ${XPAY_WEBHOOK_SECRET}
      XPAY_API_KEY: ${XPAY_API_KEY}
      XPAY_CHAINS: ${XPAY_CHAINS}
      # 可选:自定义区块链 RPC
      # XPAY_TRON_GRID_URL: https://api.trongrid.io
      # XPAY_ETH_RPC_URL: https://eth.drpc.org
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - gateway-net
    restart: always
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  mysql_data:
  redis_data:

networks:
  gateway-net:
    driver: bridge

第五步:启动网关

bash 复制代码
# 启动所有服务
sudo docker compose up -d

# 查看启动日志
sudo docker compose logs -f gateway

# 等待约 30-60 秒,看到类似以下日志表示启动成功:
# [INFO] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http)
# [INFO] [main] c.xpay.gateway.GatewayApplication : Started GatewayApplication in 25.4 seconds

第六步:验证网关运行状态

bash 复制代码
# 测试网关 API 是否正常响应
curl -X GET http://localhost:8080/api/v1/health

# 预期返回:
# {"status":"UP","timestamp":"2025-01-15T10:30:00Z"}

创建一张测试发票验证功能:

bash 复制代码
curl -X POST http://localhost:8080/api/v1/invoices \
  -H "Content-Type: application/json" \
  -H "X-API-Key: xpay_your_api_key_here" \
  -d '{
    "amount": "10.00",
    "currency": "USD",
    "chain": "tron",
    "settlementAsset": "USDT",
    "description": "测试订单 #001",
    "metadata": {"orderId": "001"}
  }'

成功后会返回类似:

json 复制代码
{
  "id": "inv_a1b2c3d4",
  "amount": "10.00",
  "currency": "USD",
  "chain": "tron",
  "settlementAsset": "USDT",
  "depositAddress": "TXYZ1234...",
  "status": "pending",
  "checkoutUrl": "http://localhost:8080/checkout/inv_a1b2c3d4",
  "createdAt": "2025-01-15T10:31:00Z",
  "expiresAt": "2025-01-15T11:01:00Z"
}

第七步:配置 Nginx 反向代理(生产环境)

生产环境不应直接暴露网关端口。使用 Nginx 反向代理 + SSL 证书:

nginx 复制代码
# /etc/nginx/sites-available/payments.example.com
server {
    listen 443 ssl;
    server_name payments.example.com;

    ssl_certificate /etc/letsencrypt/live/payments.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/payments.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name payments.example.com;
    return 301 https://$server_name$request_uri;
}

申请 SSL 证书:

bash 复制代码
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d payments.example.com

第八步:集成到你的后端应用

Node.js/TypeScript 集成

bash 复制代码
npm install @xpaylabs/node-sdk
typescript 复制代码
import { XPayClient } from '@xpaylabs/node-sdk';

const client = new XPayClient({
  apiKey: process.env.XPAY_API_KEY,
  gatewayUrl: 'https://payments.example.com'
});

// 创建支付订单
app.post('/api/create-payment', async (req, res) => {
  const { orderId, amount } = req.body;

  const invoice = await client.createInvoice({
    amount: amount.toString(),
    currency: 'USD',
    chain: 'tron',
    settlementAsset: 'USDT',
    description: `订单 #${orderId}`,
    metadata: { orderId },
    successUrl: `https://myshop.com/order/success/${orderId}`,
    cancelUrl: `https://myshop.com/order/${orderId}`
  });

  res.json({
    invoiceId: invoice.id,
    checkoutUrl: invoice.checkoutUrl
  });
});

// Webhook 处理支付确认
app.post('/api/webhooks/xpay',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const sig = req.headers['x-webhook-signature'];
    const expected = crypto
      .createHmac('sha256', process.env.XPAY_WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    if (sig !== expected) {
      return res.status(401).send('Invalid signature');
    }

    const event = JSON.parse(req.body);
    if (event.type === 'invoice.confirmed') {
      const { orderId } = event.data.metadata;
      // 释放订单、发送商品、更新数据库
      console.log(`订单 ${orderId} 支付确认`);
    }

    res.status(200).send('OK');
  }
);

Java/Spring Boot 集成

xml 复制代码
<dependency>
    <groupId>io.xpay</groupId>
    <artifactId>xpay-java-sdk</artifactId>
    <version>0.1.0</version>
</dependency>
java 复制代码
@Configuration
public class XPayConfig {
    @Bean
    public XPayClient xPayClient(@Value("${xpay.api-key}") String apiKey,
                                  @Value("${xpay.gateway-url}") String gatewayUrl) {
        return new XPayClient(apiKey, gatewayUrl);
    }
}

@Service
public class PaymentService {
    @Autowired
    private XPayClient xPayClient;

    public Invoice createPayment(String orderId, BigDecimal amount) {
        CreateInvoiceRequest request = new CreateInvoiceRequest();
        request.setAmount(amount.toString());
        request.setCurrency("USD");
        request.setChain("tron");
        request.setSettlementAsset("USDT");
        request.setDescription("订单 #" + orderId);
        request.setSuccessUrl("https://myshop.com/order/success/" + orderId);

        return xPayClient.createInvoice(request);
    }
}

@RestController
public class WebhookController {
    @PostMapping("/api/webhooks/xpay")
    public ResponseEntity<String> handleWebhook(
            @RequestBody String payload,
            @RequestHeader("x-webhook-signature") String signature) {

        String expected = HmacUtils.hmacSha256Hex(
            webhookSecret, payload);

        if (!expected.equals(signature)) {
            return ResponseEntity.status(401).body("Invalid signature");
        }

        // 处理事件...
        return ResponseEntity.ok("OK");
    }
}

第九步:配置 Nginx 白标结账页面

网关自带白标结账页面。只需配置前端域名,客户看到的就是你的品牌:

yaml 复制代码
# docker-compose.yml 中添加前端环境变量
services:
  gateway:
    environment:
      XPAY_BRAND_NAME: "你的品牌名称"
      XPAY_BRAND_LOGO_URL: "https://example.com/logo.png"
      XPAY_SUPPORT_EMAIL: "support@example.com"
      XPAY_PRIMARY_COLOR: "#2563eb"

运维与监控

查看日志

bash 复制代码
# 实时日志
sudo docker compose logs -f --tail=100

# 查看特定服务的日志
sudo docker compose logs -f gateway
sudo docker compose logs -f mysql

备份数据库

bash 复制代码
# 创建备份脚本 backup.sh
#!/bin/bash
BACKUP_DIR="/backups/gateway"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR

# 备份 MySQL
sudo docker compose exec -T mysql \
  mysqldump -u root -p${DB_ROOT_PASSWORD} xpay_gateway \
  > $BACKUP_DIR/gateway_$TIMESTAMP.sql

# 压缩备份
gzip $BACKUP_DIR/gateway_$TIMESTAMP.sql

# 保留最近 30 天备份,删除更早的
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

添加到 crontab 实现自动备份:

bash 复制代码
0 3 * * * /root/payment-gateway/backup.sh

更新网关

bash 复制代码
cd ~/payment-gateway

# 拉取最新镜像
sudo docker compose pull gateway

# 重新创建容器
sudo docker compose up -d --no-deps gateway

常见问题

1. 网关启动后立即退出

检查配置文件和数据库连接:

bash 复制代码
# 查看完整错误日志
sudo docker compose logs gateway

# 常见原因:数据库连接失败、种子短语格式错误
# 确认 MySQL 服务健康:
sudo docker compose ps

2. 无法创建发票

bash 复制代码
# 检查 API 密钥是否正确
curl -X POST http://localhost:8080/api/v1/invoices \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_key_here" \
  -d '{"amount":"10","currency":"USD","chain":"tron","settlementAsset":"USDT"}'

# 如果返回 401,检查 .env 中的 XPAY_API_KEY 配置

3. 交易检测不到

bash 复制代码
# 检查是否配置了正确的链
curl -X GET http://localhost:8080/api/v1/chains

# 确认使用的网络(主网/测试网)
# 测试网使用 TRON Shasta 网络:XPAY_TRON_NETWORK=shasta

4. Webhook 收不到回调

bash 复制代码
# 确认 Webhook URL 可公网访问
# 确认 Webhook Secret 前后端一致
# 查看 Webhook 投递日志:
curl -X GET http://localhost:8080/api/v1/webhooks/logs?limit=10 \
  -H "X-API-Key: your_key_here"

成本估算

部署完成后,运行成本如下:

项目 月成本
VPS(2核4G) ¥50-100
域名 ¥5-10
SSL 证书(Let's Encrypt) 免费
区块链 RPC 费用 $0-15
总计 约 ¥50-150/月

对比第三方网关(月流水 10 万美元情况下):

方案 月费用 年费用
BitPay 1,030-1,300 12,360-15,600
Coinbase Commerce $1,000 $12,000
自托管 ¥50-150 (~$7-21) ¥600-1,800 (~$84-252)

总结

本文从零开始完成了 Docker 部署加密支付网关的全流程:

  1. 环境准备:服务器、Docker 安装
  2. 密钥生成:离线 BIP-39 种子短语
  3. 配置部署:Docker Compose 一键启动
  4. 集成验证:API 创建发票 + Webhook 回调
  5. 生产加固:Nginx 反向代理、SSL、备份

整个部署过程大约需要 30 分钟,之后的维护主要是偶尔更新镜像和检查备份。对于月流水 1 万美元以上的商家,一年节省的费用足以覆盖数十倍的部署投入。

如果你正在寻找替代 BitPay 或 Coinbase Commerce 的自托管方案,这个部署流程是一个很好的起点。对于需要 TRON USDT 原生支持、多链架构和白标体验的团队,基于 Docker 的自托管网关是目前性价比最高的选择。

相关推荐
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工2 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
Alsn862 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
酣大智2 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_2 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉2 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
AC赳赳老秦2 天前
用 OpenClaw 搭建服务器故障应急响应系统,自动处理 80% 常见运维故障
android·运维·服务器·python·rxjava·deepseek·openclaw
2601_961875242 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant