常见问题
汇总 DaxPay 使用、部署、二次开发中高频出现的疑问。未覆盖的问题可至 GitHub Issues 或 交流群 反馈。
基础概念
DaxPay 是什么
DaxPay 是一款开源支付系统,提供支付、退款、查询、回调等支付核心能力,将支付宝、微信、银联等多种支付通道封装为统一的 HTTP 接口,业务系统只需对接一套标准协议即可接入多种支付方式。详见 项目介绍。
开源版和商业版有什么区别
开源版(本项目)交付完整的支付核心链路与多端管理界面,支付平台核心基于 LGPL-3.0-or-later 协议开源。
商业版(dax-pay-plus)在开源版基础上扩展:
转账与分账已包含在开源版交付范围内。
LGPL v3.0 协议可以商用吗
可以。LGPL-3.0-or-later 允许在遵守许可证条件的前提下进行商业使用。你的业务系统通常可通过 HTTP 接口调用 DaxPay,无需因此公开业务系统代码;修改、分发 DaxPay 本身或使用其他组件时仍须遵守对应条款。详见 开源协议。
部署运行
后端编译必须用 mvnd 吗
项目约定使用 mvnd(Maven Daemon)加速编译。普通 mvn 也能编译,但 mvnd 自带守护进程,增量编译速度显著更快,推荐使用。
Apache Artemis 能否替换为其他消息队列
当前版本强依赖 Artemis(用于支付延时通知等 JMS 场景),不支持直接替换为 RabbitMQ / Kafka。如需替换需自行改造消息中间件适配层。
延时消息提前或延后投递怎么办
现象:延时消息设置 10 秒,约 6 秒就被消费;或设置 5 秒,过了 8 秒才收到。 原因:应用与 Artemis broker 跨机器部署且两机时钟不一致,延时消息按绝对时间戳投递,实际延时被平移两机时钟差。 修复:两台机器均开启 NTP 对时,详见 延时消息时钟偏差。
套了 CDN 后登录报「请求验证已失效」或「请求时间戳已过期」怎么办
现象:本地直连后端一切正常,套上 CDN(腾讯 EdgeOne、CloudFlare 等)后登录必报 「请求验证已失效,请重试」或「请求时间戳已过期,请重试」。
原因:登录防重放机制要求每次登录先取一个一次性 nonce,CDN 把这个 GET 接口的响应缓存后, 所有用户拿到同一份旧 nonce —— 缓存 5 分钟内报前者(nonce 已被消费),超 5 分钟报后者(时间戳超容差)。 图形验证码接口被缓存同理(所有人看到同一张图)。
排查:用一个仍是 GET 的接口(如公钥)连续请求两次,观察缓存状态:
curl -sD - -o /dev/null https://你的域名/api/token/public-key | grep -i "cache-status"
# EO-Cache-Status: HIT 说明命中缓存(腾讯 EdgeOne;CloudFlare 看 CF-Cache-Status)修复:在 CDN 给所有 API 路径(/api/* 及网关域名的 /unipay/*、/client/*)配置不缓存规则, 详见 CDN 部署注意事项。
套了 CDN 后站内通知一直断开重连怎么办
现象:浏览器控制台反复报 ERR_HTTP2_PROTOCOL_ERROR 200 (OK) 之类的连接中断错误,通知消息要刷新页面才能看到,该请求按固定间隔断开重连。
原因:站内通知走 SSE 长连接(/api/notify/user/sse/connect),靠服务端周期性心跳维持;链路中间任何一层(CDN 回源超时、代理超时)等不到数据时,会在浏览器已收到 200 之后把连接掐断,前端随即自动重连,形成「周期性断连」。这是长连接超时问题,不是缓存问题,也不是鉴权或后端报错。
修复:在 CDN 给 /api/notify/* 配置回源超时 ≥ 60 秒(须大于心跳间隔,当前版本为 10 秒);EdgeOne 注意规则要配到站点实际所在的「中国大陆 / 全球」环境才生效。详见 站内通知(SSE)断开重连排查。
上传文件报跨域(CORS)错误怎么办
现象:「测试连接」通过,但上传文件时报跨域错误(No 'Access-Control-Allow-Origin' header ...)或直接失败。 原因:预签名直传是浏览器直连对象存储的跨域请求,桶上未放行跨域规则;后端「测试连接」不经过浏览器,测不出这个问题。 修复:在桶上配置跨域规则——来源填管理端与 H5 的地址(联调可用 *)、方法必须含 PUT、暴露响应头加 ETag;Cloudflare R2 的 * 只能写在 AllowedOrigins。详见 存储跨域(CORS)配置与上传排查。
收款播报激活成功但收不到播报怎么办
现象:收款播报 APP 激活成功,收款成功后手机不播报、不打印。 原因:播报消息经 MQTT over WebSocket(wss) 长连接下发,管道未打通或配置不一致——平台「MQTT 接入」配置未填、接入地址错误、证书问题、接入域名套了不支持长连接的 CDN 等都会如此,而 APP 侧没有明确报错。 修复:按收款播报收不到消息排查从平台侧向手机侧逐环检查;完整部署流程见收款播报(虚拟设备)。
支持哪些数据库
仅支持 PostgreSQL 14+。时间字段统一使用 timestamptz(6),实体类使用 OffsetDateTime,不支持 MySQL / Oracle 等。
容器化部署最低配置
建议最低 2 核 4G(含 PostgreSQL / Redis / Artemis / 主应用 / 通道子应用全部容器化)。生产环境建议 4 核 8G 起步,并根据交易量水平扩展通道子应用实例。
PowerShell 下 mvnd 编译参数报错
PowerShell 下含 = 的 -D 参数会被空格拆分,必须加引号:
# 错误 — 会被拆分
mvnd compile -Dmaven.test.skip=true
# 正确 — 加引号
mvnd compile "-Dmaven.test.skip=true"详见 项目构建。
一键部署与运维面板
使用一键部署或运维面板时的高频问题,完整的分阶段排查步骤见运维面板故障排查。
在线安装下载失败或校验不通过
可能是下载源异常或 install.sh 过期,换源重试或改用离线安装。
离线安装没反应、提示在线下载
install.sh 与 .xz 安装包必须在同一个目录(脚本只探测自身所在目录,不探测 $PWD),且用 bash install.sh 执行。
忘记面板初始密码或登录被锁定
daxpay info 查看初始账号密码;改过又忘了用 daxpay reset-password 重置;连续 5 次输错锁定用 daxpay unlock 解锁。
端口冲突(8060 / 80)
中间件与业务服务默认不映射端口,宿主机只占这两个端口(面板 8060、网关 80)。停掉占用进程,或用 --port 换面板端口。HTTPS 由外层 CDN / 网关终结,源站网关不再监听 443。
业务后端容器 unhealthy 反复重启
常见根因是数据库密码为空,或业务侧与中间件侧密码不一致,导致认证失败。在基础环境服务卡片「查看密码」确认密码非空,用「配置」抽屉的「修改密码」对齐后重启业务容器。
页面出现 drift(漂移)横幅
提示「重新部署 <某服务>」= 该服务的端口/内存/暴露模式改了未生效,点击只重建这一个容器;提示整栈「重新部署」= 版本/JVM/内存档位等栈级变更未生效,需重建所有已启用容器;提示「应用网关配置」= 网关配置改动未应用,点击应用即可(nginx reload,无需重建容器)。
明明部署了,面板却显示「未部署」
「已部署」判定基于运行时容器探测 + 部署快照。手动用 docker compose 拉起的容器,面板启动时会自动补齐快照自愈;仍未识别就到对应页面点一次「部署」让面板接管。
支付通道对接
开源版已支持哪些支付通道
已形成 20+ 支付通道能力口径:
- 直连通道(
channel-one)— 支付宝、微信、抖音、银联商务、银联(云闪付) - 聚合与国际通道(
channel-two/channel-three)— 拉卡拉、海科融通、斗拱(汇付天下)、乐刷、随行付、河马付(杉德)、Adapay、富友、Stripe 等,通过对应扩展包和版本按需提供
直连通道、通道扩展包与具体可用清单以版本说明和官网产品页为准。
详见 特色功能 - 通道总数与分布。
如何新增一个支付通道
- 在对应通道子应用(直连走
channel-one,聚合走channel-two)的daxpay-channel-impl下实现 SDK 调用与签名/验签 - 在主应用
daxpay-channel注册通道策略与配置数据 CRUD - 在
ChannelEnum补充通道枚举
新增通道只需实现 SDK 调用并注册策略,不影响主链路。
channel-one / channel-two / channel-three 有什么区别
三者架构完全相同,区别在于承载的通道集合:
channel-one— 对接支付宝、微信等直连通道(官方 SDK)channel-two— 对接拉卡拉、富友等聚合通道(聚合 SDK)channel-three— 对接 Stripe 等国际通道
主应用通过 daxpay.channel.one/two/three.base-url 路由,子应用编号固定不可改名。
通道子应用的 Java 版和 Go 版怎么选
channel-one 同时提供 Java(Spring Boot)与 Go(Gin)两套完全对等的实现,端口、路由、响应契约一致:
- Java 版 — 生态完整,通道官方 SDK 现成,适合快速对接
- Go 版 — 更高吞吐、更低内存占用,全部自研 HTTP 签名对接(无第三方 SDK)
按团队技术栈与性能诉求选用,两者二选一,端口冲突不可同时启动。
通道子应用必须独立部署吗
是的。通道子应用独立部署是 DaxPay 的核心设计 —— 将第三方 SDK 隔离到子应用,避免 SDK 依赖污染主应用,支持独立升级与弹性伸缩。主应用通过 @HttpExchange 声明式 HTTP 客户端调用子应用,链路 AES-GCM 加密。
微信服务商支付报「受理机构必须传入sub_mch_id」怎么办
现象:服务商模式发起支付时报「受理机构必须传入sub_mch_id」,但请求参数里的 sub_mchid 明明有值。
原因:这条报错文案有误导性 —— 它真正的含义是微信对「服务商 ↔ 特约商户」绑定关系的校验失败,不是字段缺失。最常见的触发是配置错误:服务商自己的商户号被填进了特约商户号位置(sp_mchid 与 sub_mchid 是同一个号),而微信不允许服务商特约自己。
判别:在通道子应用日志里核对请求体,出现 sp_mchid == sub_mchid(且 sp_appid == sub_appid)即可确认是配置问题。
修复:商户本身是普通商户(没有服务商资质)的,不该使用微信服务商产品,改配微信直连;确实是服务商的,特约商户号必须填服务商进件绑定的真实二级商户号。详见 微信服务商支付报错, 通道配置说明见 微信支付。
功能边界
是否支持分账 / 提现
分账已支持:支付宝、微信、抖音三通道直连商户分账。使用流程:统一下单时声明 allocation=true 创建分账订单 → 通过开放接口 发起分账 / 查询 / 同步;分账接收方需提前在通道侧完成绑定(管理端「通道商户详情 → 分账接收方」提供绑定入口)。详见接口文档。
提现(代付)暂未实现,属后续增强方向。
是否支持国际支付(PayPal / Stripe)
Stripe 已通过 channel-three 子应用接入(持续完善中),支持国际卡组织支付。PayPal 等其他国际通道为后续规划。
沙箱环境怎么用
DaxPay 采用部署级沙箱隔离:
- 测试 / 开发环境配置
daxpay.platform.config.sandbox-enabled=true,允许沙箱联调 - 生产环境必须配置
sandbox-enabled=false,启动时会强制将所有activeEnv=sandbox的产品重置为prod,保证生产数据纯净
生产环境隔离
沙箱联调请走独立的测试环境部署,生产数据库严禁从测试环境导入数据。详见 配置说明。
是否支持多商户 / 多商户隔离
支持。DaxPay 原生支持多商户模式:
- 运营端 + 商户端双入口,数据行级隔离(商户编号自动隔离)
- 单商户可配置多个支付应用,独立凭证与回调地址
二次开发
能否修改源码用于自己的项目
可以。基于 LGPL-3.0-or-later,你可以按许可证修改、使用源码。若你修改了 DaxPay 受许可证覆盖的源码(而非通过接口调用),需按 LGPL 条款提供相应修改源码;若仅通过 HTTP 接口调用,你的业务代码通常无需因此开源。
前端如何对接后端接口
前端通过 RESTful HTTP 接口对接主应用(端口 9999),接口请求 / 响应支持 RSA 签名防篡改,认证基于 Sa-Token(token name: Accesstoken)。详细接入方式见 接口文档。
如何新增一种界面语言(i18n)
- 后端 — 资源文件在
common-i18n/src/main/resources/i18n/{locale}/,按业务模块拆分,新增语种需同步维护zh-CN/en-US/zh-TW/zh-HK/ja-JP/ko-KR - 前端(Web/H5) — 10 语种,新增 key 需全语种同步
- 小程序 — 仅中英(小程序端条件编译剔除繁体 / 日韩 / 东盟)
详见各端 i18n 规范。
数据库表结构在哪?如何初始化
SQL 脚本位于主应用仓库 _config/sql/ 目录,全新安装顺序为 table.sql(建表)→ data.sql(初始数据,已脱敏)。仓内另提供升级脚本 update-tables.sql → update-datas.sql 与菜单种子 iam_perm_menu.sql。详见 项目构建 - 数据库准备。
为什么缓存会出现「只读 L1、不读写 Redis」的情况
这不是普通缓存的常规形态,而是敏感缓存的安全降级保护:缓存名命中敏感名单(secure: 前缀或 secureNames 配置)、且平台数据加密未启用时,敏感数据被禁止明文写入 Redis,仅写 L1 本机内存、读侧直接穿透。启用数据加密后自动恢复 L1+L2 双层。完整行为矩阵见 缓存 L1 只读降级。
未找到答案?欢迎到 GitHub Issues 提问或加入 交流群 讨论。