支付宝 / 微信支付 / PayPal 三合一,内置管理控制台与商户开放 API。 单个镜像、单个容器、单个端口 —— 前端已静态导出并由 Go 二进制内嵌,无需 Nginx、无需 Node 运行时。
一套可运营的支付中台,把多渠道支付接入、渠道密钥管理、商户授权、变更审计收敛到一个容器里。
| 解决的问题 | 提供的能力 |
|---|---|
| 多渠道接入成本高 | 统一下单 / 查询 / 关单 / 退款接口,支付宝、微信、PayPal 一套调用 |
| 渠道密钥证书难管理 | 控制台热配置 + 证书全生命周期管理,保存即生效,不用重启 |
| 商户如何安全调用 | OAuth2 Client Credentials + 细粒度 scope + IP 白名单 + 限流 |
| 配置变更不可追溯 | 支付配置 / 证书操作审计日志(操作人、IP、before/after) |
| AI Skill 如何收费 | SkillHub X402:402 支付码 → 微信扫码 → 服务端幂等履约 |
自带 MySQL,无需准备任何外部依赖:
docker run -d --name pay-unify-mysql \
-e MYSQL_ROOT_PASSWORD=payunify_root \
-e MYSQL_DATABASE=payment_db \
-e MYSQL_USER=payment_db \
-e MYSQL_PASSWORD=payunify_pass \
mysql:8.0 --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
docker run -d --name pay-unify \
--link pay-unify-mysql:mysql \
-p 8097:8080 \
-e PANEL_DB_TYPE=mysql \
-e PANEL_DB_HOST=mysql \
-e PANEL_DB_PORT=3306 \
-e PANEL_DB_NAME=payment_db \
-e PANEL_DB_USER=payment_db \
-e PANEL_DB_USER_PASSWORD=payunify_pass \
-e PAY_JWT_SECRET="$(openssl rand -hex 32)" \
-e PAY_ADMIN_PASSWORD='ChangeMe123!' \
-e PAY_CERT_DIR=/app/runtime/certs \
-e TZ=Asia/Shanghai \
-v "$PWD/certs:/app/runtime/certs" \
-v "$PWD/logs:/app/logs" \
difyz9/pay-unify:2.0.0
打开 http://localhost:8097 ,用 admin / 你设置的 PAY_ADMIN_PASSWORD 登录。
docker run -d --name pay-unify \
-p 8097:8080 \
-e PANEL_DB_TYPE=mysql \
-e PANEL_DB_HOST=192.168.1.10 \
-e PANEL_DB_PORT=3306 \
-e PANEL_DB_NAME=payment_db \
-e PANEL_DB_USER=payunify \
-e PANEL_DB_USER_PASSWORD='your-db-password' \
-e PAY_JWT_SECRET="$(openssl rand -hex 32)" \
-e PAY_ADMIN_PASSWORD='ChangeMe123!' \
-e PAY_CERT_DIR=/app/runtime/certs \
-v "$PWD/certs:/app/runtime/certs" \
-v "$PWD/logs:/app/logs" \
difyz9/pay-unify:2.0.0
数据库:提前建好库即可,表结构由服务启动时自动
AutoMigrate:CREATE DATABASE payment_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;macOS / Windows 连宿主机 MySQL 用
-e PANEL_DB_HOST=host.docker.internal; Linux 加--add-host=host.docker.internal:host-gateway。
services:
mysql:
image: mysql:8.0
command: [--character-set-server=utf8mb4, --collation-server=utf8mb4_unicode_ci]
environment:
MYSQL_ROOT_PASSWORD: payunify_root
MYSQL_DATABASE: payment_db
MYSQL_USER: payment_db
MYSQL_PASSWORD: payunify_pass
volumes: [./data/mysql:/var/lib/mysql]
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-uroot", "-ppayunify_root"]
interval: 10s
retries: 10
pay-unify:
image: difyz9/pay-unify:2.0.0
depends_on:
mysql: {condition: service_healthy}
ports: ["8097:8080"]
environment:
PANEL_DB_TYPE: mysql
PANEL_DB_HOST: mysql
PANEL_DB_PORT: "3306"
PANEL_DB_NAME: payment_db
PANEL_DB_USER: payment_db
PANEL_DB_USER_PASSWORD: payunify_pass
PAY_JWT_SECRET: "替换为 openssl rand -hex 32"
PAY_ADMIN_PASSWORD: "ChangeMe123!"
PAY_CERT_DIR: /app/runtime/certs
TZ: Asia/Shanghai
volumes:
- ./data/certs:/app/runtime/certs
- ./data/logs:/app/logs
docker compose up -d
本镜像已适配 1Panel 应用包格式,支持表单化一键安装(面板托管数据库 + 自动生成密钥)。
应用包位于源码仓库 deploy/1panel/。
全部可选项。优先级:环境变量 > config.toml > 内置默认值,不写环境变量也能用。
| 变量 | 默认值 | 说明 |
|---|---|---|
PAY_LISTEN | :8097(镜像内置 :8080) | 监听地址 |
CONFIG_FILE | /app/config.toml | 配置文件路径,不存在则自动生成 |
PAY_CERT_DIR | /app/runtime/certs | 支付渠道证书落盘目录,需持久化 |
PAY_DEBUG | false | 调试模式;开启后才会创建测试 API 应用 |
TZ | Asia/Shanghai | 时区 |
| 变量 | 默认值 | 说明 |
|---|---|---|
PAY_JWT_SECRET | 随机生成 | 控制台会话签名密钥,生产必须显式设置(openssl rand -hex 32);< 16 字节拒绝启动 |
PAY_ADMIN_USERNAME | admin | 初始管理员用户名(仅首次建库生效) |
PAY_ADMIN_PASSWORD | admin123 | 初始管理员密码(仅首次建库生效);留空会打警告日志,请务必设置 |
账号只在首次建库(该用户名不存在)时创建。库已存在时改这两个变量不会改密码。
推荐用 1Panel 风格变量(自动拼 DSN,不用手算):
| 变量 | 说明 |
|---|---|
PANEL_DB_TYPE | mysql(默认)/ postgresql / mariadb |
PANEL_DB_HOST | 数据库主机;设置此项即启用该模式 |
PANEL_DB_PORT | 端口,缺省按驱动取 3306 / 5432 |
PANEL_DB_NAME | 库名,如 payment_db |
PANEL_DB_USER | 用户名 |
PANEL_DB_USER_PASSWORD | 密码 |
也支持直接给连接串:
| 变量 | 说明 |
|---|---|
PAY_DB_DRIVER | mysql / postgres |
PAY_MYSQL_DNS | 完整 MySQL DSN |
PAY_POSTGRES_DSN | 完整 PostgreSQL DSN |
| 项 | 值 | 说明 |
|---|---|---|
| 容器端口 | 8080 | 内部固定;对外映射到任意端口 |
| 卷 | /app/runtime/certs | 支付渠道证书,必须持久化,否则重启丢证书 |
| 卷 | /app/logs | 应用日志 |
| 卷 | /app/config.toml | 可选,挂载自定义配置文件 |
| 运行用户 | uid/gid 1000(非 root) | 挂载宿主机目录时需保证可写:chown -R 1000:1000 <dir> |
容器内监听端口固定为
8080(由镜像ENV PAY_LISTEN=:8080设定)。 用-p 8097:8080把控制台暴露到宿主机 8097。
镜像内置 HEALTHCHECK(interval 30s / timeout 5s / start-period 30s / retries 3):
wget -q -O /dev/null http://127.0.0.1:8080/health/db
/health/db 是就绪探针(含数据库连通性),正常返回:
{"db":"ok","status":"healthy"}
刻意用 GET(
-O /dev/null)而非--spider:/health/db只注册了 GET 路由,--spider发 HEAD 会 404,导致容器被误判为 unhealthy。
在编排里可作为依赖条件:
depends_on:
pay-unify:
condition: service_healthy
| 端点 | 说明 |
|---|---|
GET / | 管理控制台(浏览器访问返回 HTML;其它客户端返回服务信息 JSON) |
GET /health | 存活探针 |
GET /health/db | 就绪探针(含 DB 连通性) |
GET /metrics | Prometheus 文本格式指标 |
GET /api/v1/info | 服务信息 |
GET /swagger/index.html | Swagger UI |
| 项 | 值 |
|---|---|
| 基础镜像 | alpine:3.21 |
| 体积 | ≈ 57 MB(压缩后) |
| 架构 | linux/amd64、linux/arm64 |
| 运行用户 | 非 root(app,uid/gid 1000) |
| 构建方式 | 三阶段:Next.js 静态导出 → Go //go:embed 内嵌 → 单二进制 |
| 标签策略 | 2.0.0(精确版本)、latest(最新稳定版) |
生产环境建议锁定具体版本号,不要用 latest。
Q:容器起来了但控制台打不开?
先看 docker logs pay-unify。若报数据库连接失败,检查 PANEL_DB_* 是否正确、数据库是否允许该来源 IP 连接。
Q:登录提示"尝试次数过多,账号已临时锁定"?
登录失败 5 次会锁定 30 分钟([Auth] MaxLoginAttempts / LockoutDuration)。锁定记录在进程内存中,docker restart pay-unify 即可立即解锁。
Q:上传的支付证书重启后丢了?
/app/runtime/certs 没做持久化。务必挂载数据卷;挂载宿主机目录时还要保证 uid 1000 可写。
Q:git/docker pull 拉取慢?
使用镜像加速:docker pull docker.m.daocloud.io/difyz9/pay-unify:2.0.0(或你本地配置的加速地址)。
Q:改了渠道参数要重启吗? 支付宝 / 微信的配置与证书在控制台保存后热加载即时生效,不用重启。PayPal 由配置文件决定,需改配置并重启。
Q:怎么让商户调用支付接口?
控制台「API 应用管理」创建应用并勾选 scope → 商户调 POST /oauth/token 换 Bearer Token → 访问 /api/v2/*。
deploy/1panel/(见仓库内说明)v* tag 自动构建多架构镜像并推送到本仓库本文件即 Docker Hub 仓库 Overview 的内容源,可在 https://hub.docker.com/r/difyz9/pay-unify 直接编辑。
Content type
Image
Digest
sha256:09f644554…
Size
56.8 MB
Last updated
21 days ago
docker pull difyz9/pay-unify