使用 Docker 部署 Epusdt / GMPay

在 VPS 上部署 epusdt / GMPay 并接入 Dujiao-Next:USDT-TRC20 收款

在 VPS 上部署 epusdt / GMPay,并将其接入 Dujiao-Next 作为 USDT-TRC20 支付渠道

epusdt,也就是现在界面中常见的 GMPay,是一个可私有化部署的多链加密货币支付网关,支持 GMPay API、EPay 兼容跳转收银台、托管收银台和异步回调。官方当前建议新接入优先使用 GMPay,而不是旧版 /payments/epusdt/v1/order/create-transaction 路由。

一、本文使用的示例信息

为了避免泄露真实信息,本文统一使用以下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
前台商城域名:
shop.example.com

管理后台域名:
admin.example.com

epusdt / GMPay 支付网关域名:
pay.example.com

VPS 公网 IP:
203.0.113.10

USDT-TRC20 收款地址:
TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

GMPay 商户 PID:
1000

GMPay 签名密钥:
REPLACE_WITH_GMPAY_SECRET_KEY

实际部署时,将这些示例替换成自己的真实信息即可。

整体结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
用户访问:
https://shop.example.com

管理员访问:
https://admin.example.com

支付网关:
https://pay.example.com

Nginx 反向代理:
pay.example.com -> http://127.0.0.1:9898

Docker 端口映射:
127.0.0.1:9898 -> epusdt 容器内 8000

这里使用 9898 作为 VPS 本机端口,是为了避免和已有的 Dujiao-Next 服务端口冲突。epusdt 容器内部仍然监听 8000


二、准备工作

需要准备:

1
2
3
4
5
6
7
一台 Linux VPS,本文以 Ubuntu / Debian 为例
一个域名
一个 USDT-TRC20 收款地址
Docker 和 Docker Compose
Nginx
Let's Encrypt SSL 证书
已部署好的 Dujiao-Next

USDT-TRC20 使用的是 TRON 网络。TRON 官方页面展示的 TRC-20 USDT 合约地址是:

1
TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t

在 GMPay 里配置 USDT-TRC20 时,网络应选择 tron,代币应选择 usdt


三、DNS 解析

在域名 DNS 管理后台添加一条 A 记录:

1
2
3
4
类型:A
主机记录:pay
记录值:203.0.113.10
代理状态:仅 DNS

这里建议先保持 仅 DNS,等支付完全跑通后再考虑开启 Cloudflare 小黄云。

最终访问地址是:

1
https://pay.example.com

四、安装 Docker、Nginx 和 Certbot

登录 VPS:

1
ssh [email protected]

安装基础组件:

1
2
apt update -y
apt install -y curl nginx certbot python3-certbot-nginx

安装 Docker:

1
2
3
4
5
6
7
curl -fsSL https://get.docker.com | bash

systemctl enable docker
systemctl start docker

docker version
docker compose version

epusdt 官方 Docker 文档推荐使用 Docker Compose 部署,并通过 EPUSDT_CONFIG=/data/.env 持久化配置、SQLite 主数据库和运行时数据。


五、部署 epusdt / GMPay

创建目录:

1
2
mkdir -p /opt/epusdt
cd /opt/epusdt

创建 docker-compose.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
cat > docker-compose.yaml <<'EOF'
services:
epusdt:
image: gmwallet/epusdt:latest
container_name: epusdt
restart: always
environment:
EPUSDT_CONFIG: /data/.env
ports:
- "127.0.0.1:9898:8000"
volumes:
- ./data:/data
EOF

启动容器:

1
docker compose up -d

查看容器状态:

1
docker ps

正常应该看到类似:

1
127.0.0.1:9898->8000/tcp   epusdt

查看日志:

1
docker logs --tail=100 epusdt

首次启动时,如果还没有配置文件,日志里通常会看到类似:

1
[install] no config found — install API available at http://localhost:8000/install

这不是错误,说明需要打开安装页面完成初始化。

测试本机端口:

1
curl -I http://127.0.0.1:9898/install

六、配置 Nginx 反向代理

创建 Nginx 配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat > /etc/nginx/sites-available/pay.example.com <<'EOF'
server {
listen 80;
server_name pay.example.com;

location / {
proxy_pass http://127.0.0.1:9898;
proxy_http_version 1.1;

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;
}
}
EOF

启用站点:

1
2
3
ln -s /etc/nginx/sites-available/pay.example.com /etc/nginx/sites-enabled/pay.example.com
nginx -t
systemctl reload nginx

申请 SSL 证书:

1
certbot --nginx -d pay.example.com

证书申请成功后,访问:

1
https://pay.example.com/install

七、完成 epusdt 安装向导

打开:

1
https://pay.example.com/install

安装页面建议这样填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
应用名称:
示例店铺 USDT 支付

应用地址:
https://pay.example.com

HTTP 绑定地址:
0.0.0.0

HTTP 绑定端口:
8000

运行时根目录:
/data/runtime

日志保存路径:
/data/runtime/logs

订单过期时间:
15

最大回调重试次数:
5

这里最容易填错的是 HTTP 绑定地址HTTP 绑定端口

虽然 VPS 本机使用的是 9898,但 epusdt 容器内部仍然监听 8000,所以安装向导里的端口要填:

1
8000

官方 Docker 文档特别提醒,Docker 部署时 http_bind_addr 必须填 0.0.0.0,不要填 127.0.0.1,否则服务重启后可能只监听容器内部本地地址,导致端口映射或反向代理无法访问。

如果安装时不小心填错,可以在 VPS 上修改配置:

1
nano /opt/epusdt/data/.env

找到类似:

1
http_listen=127.0.0.1:8000

改成:

1
http_listen=0.0.0.0:8000

然后重启:

1
docker restart epusdt

八、登录 GMPay 后台

安装完成后访问:

1
https://pay.example.com

登录管理后台。

首次安装时,管理员账号密码会出现在容器日志里:

1
docker logs --tail=100 epusdt

登录后建议第一时间修改管理员密码。


九、配置 TRON RPC 节点

进入:

1
左侧菜单 → 区块链 → RPC 节点

确认有 TRON 节点,并且状态正常:

1
2
3
4
5
链网络:tron
连接类型:HTTP
节点 URL:https://api.trongrid.io
状态:启用
健康状态:正常

官方 FAQ 提醒,TRON 链建议配置 TronGrid API Key,否则节点请求可能被限速或拒绝;同时 TRON 和 Solana 使用 HTTP/HTTPS 端点,ETH、BSC、Polygon 等链通常使用 WSS 端点。([epusdt][4])

测试阶段可以先使用默认节点,生产环境建议申请 TronGrid API Key 后填入。


十、配置链与代币

进入:

1
左侧菜单 → 区块链 → 链与代币

确认存在并启用:

1
2
链:tron
代币:usdt

如果需要手动新增 USDT-TRC20,可以参考:

1
2
3
4
5
6
7
链名称:TRON
网络标识:tron
代币名称:USDT
代币标识:usdt
合约地址:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
精度:6
状态:启用

十一、添加收款钱包地址

进入:

1
左侧菜单 → 财务 → 地址管理

点击新增钱包,填写:

1
2
3
4
5
6
7
8
链:
tron

钱包地址:
TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

备注:
示例店铺 USDT-TRC20 收款地址

保存后,确认该钱包处于启用状态。

这里填写的是自己的 USDT-TRC20 收款地址。不要填写助记词、私钥,也不要填写 ERC20、BEP20 或其他网络地址。


十二、确认收款资产

进入:

1
左侧菜单 → 支付接入 → 收款资产

确认 TRON 链下面支持:

1
2
TRX
USDT

如果看不到 USDT,说明链与代币、钱包地址或资产启用状态没有配置完整。

epusdt 的公开配置接口会根据后台启用的链、代币和钱包地址动态生成 supported_assets,所以每台环境返回的可用资产可能不同。([epusdt][4])

可以在 VPS 上测试:

1
curl https://pay.example.com/payments/gmpay/v1/config

正常返回里应该包含类似:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"status_code": 200,
"message": "success",
"data": {
"supported_assets": [
{
"network": "tron",
"display_name": "TRON",
"tokens": ["TRX", "USDT"]
}
]
}
}

epusdt API 文档中也说明,GET /payments/gmpay/v1/config 用于获取公开支付配置、可用链和可用币种。


十三、配置汇率

进入:

1
左侧菜单 → 系统配置 → 支付配置

建议填写:

1
2
3
4
5
6
7
8
金额精度:
2

汇率 API 地址:
https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/

强制汇率表:
{}

保存后重启容器:

1
docker restart epusdt

如果不配置汇率,创建订单时可能会在日志里看到:

1
2
api_rate_url is empty
rate api url is empty

然后 Dujiao-Next 前台会提示支付网关请求失败。

官方 FAQ 说明,系统会用汇率 API 把法币金额换算成加密货币数量,并给出了可使用的社区汇率 API;文档也提醒该免费 API 的准确性不做保证,生产环境可以考虑付费汇率源。


十四、获取 GMPay 商户 PID 和密钥

进入:

1
左侧菜单 → 系统 → 支付管理

默认会有一个 Key,例如:

1
2
3
4
名称:default
PID:1000
密钥:************
状态:启用

需要复制两个值:

1
2
3
4
5
PID:
1000

签名密钥:
REPLACE_WITH_GMPAY_SECRET_KEY

密钥要点击复制按钮复制真实内容,不能复制页面上的星号。

官方 FAQ 说明,pid 和签名密钥来自后台 API Key 记录,每个商户都有自己的 pid 和对应的 secret_key


十五、在 Dujiao-Next 后台新增 epusdt 渠道

进入 Dujiao-Next 管理后台:

1
https://admin.example.com

路径:

1
后台 → 支付管理 → 支付渠道 → 新增渠道

基础信息填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
渠道名称:
USDT-TRC20

渠道类型:
epusdt

支付方式:
USDT (TRC20)

交互方式:
跳转

排序权重:
10

百分比手续费:
0

固定手续费:
0

最小金额限制:
0

最大金额限制:
0

启用:
开启

Dujiao-Next 官方支付指南中说明,epusdt 常用必填项包括网关地址、商户 PID、签名密钥、代币、网络、通知地址和回跳地址,并且 epusdt 仅支持跳转模式,下单后会跳转到 epusdt 托管收银台完成付款。

epusdt 配置区域填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
网关地址:
https://pay.example.com

商户 PID:
1000

签名密钥:
REPLACE_WITH_GMPAY_SECRET_KEY

代币:
usdt

网络:
tron

法币:
cny

异步通知地址:
https://shop.example.com/api/v1/payments/callback

同步回跳地址:
https://shop.example.com/pay

Dujiao-Next 官方文档给出的通用支付回调地址是:

1
POST https://user.example.com/api/v1/payments/callback

epusdt、易支付、TokenPay、Bepusdt、OKPay 等都使用这个通用回调入口;用户支付完成后的返回地址通常填写前台域名下的 /pay


十六、支付流程测试

进入前台:

1
https://shop.example.com

下一笔小额订单,选择:

1
USDT-TRC20

正常流程应该是:

1
2
3
4
5
6
7
8
9
用户下单
→ 选择 USDT-TRC20
→ Dujiao-Next 请求 https://pay.example.com 创建支付订单
→ 跳转到 epusdt / GMPay 收银台
→ 显示 USDT-TRC20 付款金额和收款地址
→ 用户转账
→ epusdt 监听链上到账
→ epusdt 回调 Dujiao-Next
→ Dujiao-Next 订单变成已支付

epusdt 的 GMPay 创建交易接口是:

1
POST /payments/gmpay/v1/order/create-transaction

请求参数包括 pidorder_idcurrencytokennetworkamountnotify_urlredirect_urlsignature 等;成功后会返回 payment_url,用于跳转到收银台。


十七、常用测试命令

测试支付网关首页:

1
curl -I https://pay.example.com

测试公开配置:

1
curl https://pay.example.com/payments/gmpay/v1/config

查看 epusdt 日志:

1
docker logs --tail=100 epusdt

实时查看 epusdt 日志:

1
docker logs -f epusdt

查看 Dujiao-Next API 日志:

1
docker logs --tail=100 dujiaonext-api

容器名可能因部署方式不同而不同,可以用下面命令查看:

1
docker ps

测试 Dujiao-Next API 容器能否访问 GMPay:

1
docker exec -it dujiaonext-api sh

进入容器后执行:

1
wget -S -O- https://pay.example.com/payments/gmpay/v1/config

或者:

1
curl https://pay.example.com/payments/gmpay/v1/config

十八、常见问题排查

1. https://pay.example.com 打不开

检查容器:

1
2
docker ps | grep epusdt
docker logs --tail=100 epusdt

检查本机端口:

1
curl -I http://127.0.0.1:9898

检查 Nginx:

1
2
nginx -t
systemctl status nginx

检查监听端口:

1
ss -ltnp | grep ':80\|:443\|:9898'

2. 访问 pay.example.com 出现 502

通常是 Nginx 能访问,但后端 epusdt 没有正常响应。

检查:

1
2
curl -I http://127.0.0.1:9898
docker logs --tail=100 epusdt

如果安装时绑定地址填错,编辑配置:

1
nano /opt/epusdt/data/.env

确保是:

1
http_listen=0.0.0.0:8000

然后重启:

1
docker restart epusdt

3. Dujiao-Next 前台提示「支付网关请求失败」

先确认 GMPay 网关本身正常:

1
curl https://pay.example.com/payments/gmpay/v1/config

返回里应该能看到:

1
2
TRON
USDT

然后检查 Dujiao-Next 后台配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
网关地址必须是:
https://pay.example.com

商户 PID:
1000

签名密钥:
必须是真实 secret_key,不能是星号,不能是钱包地址

代币:
usdt

网络:
tron

法币:
cny

异步通知地址:
https://shop.example.com/api/v1/payments/callback

同步回跳地址:
https://shop.example.com/pay

再查看日志:

1
2
docker logs --tail=100 dujiaonext-api
docker logs --tail=100 epusdt

4. 日志出现 api_rate_url is empty

说明汇率没有配置。

进入:

1
GMPay 后台 → 系统配置 → 支付配置

填写:

1
2
汇率 API 地址:
https://cdn.jsdelivr.net/npm/@fawazahmed0/currency-api@latest/v1/currencies/

保存后重启:

1
docker restart epusdt

5. supported_assets 里没有 USDT

检查这几处:

1
2
3
4
5
6
7
8
9
10
11
区块链 → RPC 节点:
tron 节点是否启用,健康状态是否正常

区块链 → 链与代币:
tron / usdt 是否启用

财务 → 地址管理:
是否添加了 TRON 地址

支付接入 → 收款资产:
TRON 是否支持 USDT

6. 用户付款了,但订单没有自动完成

检查 epusdt 是否收到链上交易:

1
docker logs -f epusdt

检查 Dujiao-Next 是否收到回调:

1
docker logs -f dujiaonext-api

epusdt 支付成功后会向订单的 notify_url 发送异步通知,目标服务器处理成功后需要返回 HTTP 200,响应体为 oksuccess,否则 epusdt 会按配置进行重试。

重点检查:

1
2
3
4
5
异步通知地址是否正确
Dujiao-Next API 是否公网可访问
Cloudflare / WAF 是否拦截 POST 回调
Dujiao-Next 是否自定义过回调路由
签名密钥是否一致

十九、Cloudflare 小黄云设置建议

调试阶段建议 pay.example.com 保持 仅 DNS。支付流程完全跑通后再开启代理。

开启 Cloudflare 小黄云后,建议:

1
2
3
4
5
6
7
8
SSL/TLS 模式:
Full (strict)

缓存规则:
pay.example.com 绕过缓存

WAF / 安全规则:
放行支付接口和回调路径

Cloudflare 官方文档说明,Full strict 模式会更严格地校验源站证书;缓存规则可以选择 Bypass cache,让匹配请求不被缓存;WAF 自定义规则也支持 Skip 操作,用于让合法请求跳过可能误拦截的安全功能。([Cloudflare Docs][7])

建议绕过缓存的路径:

1
2
3
4
https://pay.example.com/payments/*
https://pay.example.com/pay/*
https://pay.example.com/admin/*
https://shop.example.com/api/v1/payments/callback

如果开启小黄云后支付失败,先改回 仅 DNS,确认是否是 Cloudflare 缓存或 WAF 导致。


二十、备份和升级

备份 epusdt 数据:

1
tar -czvf /root/epusdt-backup-$(date +%F).tar.gz /opt/epusdt/data

升级镜像:

1
2
3
cd /opt/epusdt
docker pull gmwallet/epusdt:latest
docker compose up -d

官方 Docker 文档提醒,不要把整个 /app 目录挂载成持久卷,否则升级时旧文件可能遮蔽镜像里的新程序和新文件;推荐只挂载 /data

二十一、安全注意事项

不要在博客里公开这些信息:

1
2
3
4
5
6
7
真实服务器 IP
真实钱包地址
GMPay secret_key
后台登录地址
后台用户名和密码
Cloudflare API Token
TronGrid API Key

也不要把钱包助记词、私钥填到 epusdt 里。普通收款只需要收款地址,资金会直接进入对应钱包地址。

建议上线后做这些事:

1
2
3
4
5
6
7
修改 GMPay 默认管理员密码
定期备份 /opt/epusdt/data
定期检查 docker logs
不要对公网暴露 9898 端口
只开放 80 和 443
开启 HTTPS
支付跑通后再考虑配置 Cloudflare WAF

二十二、最终配置速查

VPS Docker 端口

1
127.0.0.1:9898 -> 容器内 8000

Nginx 反向代理

1
https://pay.example.com -> http://127.0.0.1:9898

GMPay 安装配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
应用地址:
https://pay.example.com

HTTP 绑定地址:
0.0.0.0

HTTP 绑定端口:
8000

运行时根目录:
/data/runtime

日志保存路径:
/data/runtime/logs

GMPay 收款资产

1
2
3
4
5
6
7
8
链:
tron

代币:
usdt

收款地址:
TXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Dujiao-Next epusdt 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
渠道名称:
USDT-TRC20

渠道类型:
epusdt

交互方式:
跳转

网关地址:
https://pay.example.com

商户 PID:
1000

签名密钥:
REPLACE_WITH_GMPAY_SECRET_KEY

代币:
usdt

网络:
tron

法币:
cny

异步通知地址:
https://shop.example.com/api/v1/payments/callback

同步回跳地址:
https://shop.example.com/pay

结语

这套部署方式的核心思路是:Dujiao-Next 负责商城订单,epusdt / GMPay 负责生成 USDT 收银台、监听链上到账并回调订单系统

部署时最容易出错的地方有四个:

1
2
3
4
Docker 内部端口和宿主机端口混淆
安装向导把 HTTP 绑定地址填成 127.0.0.1
没有配置汇率 API
Dujiao-Next 里签名密钥填错

只要 https://pay.example.com/payments/gmpay/v1/config 能正常返回 TRON + USDT,并且 Dujiao-Next 后台的 PID、密钥、回调地址填写正确,基本就能顺利跳转到 GMPay 收银台。