# DaxPay 开源支付系统 - 全量文档> 本文件合并了所有公开中文文档,供 AI 工具一次性读取。生成时间: 2026-07-31T11:22:42.303Z
---
# 应用介绍
**源**: https://doc.open.daxpay.cn/architecture/apps.md
# 应用介绍
DaxPay 由多个独立 git 仓库的子项目协同构成,主应用通过 HTTP 调用各独立通道子服务,前端多端通过 RESTful 接入主应用。下面分别介绍各应用 (含已交付与规划中)。
## 主应用 dax-pay-open
支付核心后端,承载支付业务、通道路由编排、风控与系统管理。
| 模块 | 职责 |
|------|------|
| `daxpay-platform` | 基础层 — 通用契约 (core) + 技术设施 (common) + 平台能力 (capability) + 业务服务 (service) |
| `daxpay-payment` | 支付业务 — 领域内核 (core) + 运营端 (admin) + 商户端 (merchant) + 统一收单 (unipay) + 移动端 (app-admin) |
| `daxpay-channel` | 通道业务 — 13 个通道的编排层 (路由/策略/配置 CRUD,不含 SDK) |
| `daxpay-plugin` | 支付插件 — 易支付协议、风控黑名单 |
| `daxpay-demo` | 功能演示模块 |
| `daxpay-start` | 启动入口 |
**技术栈**: Java 25 · Spring Boot 4.1.0 · PostgreSQL 14+ · Redis 7+ · Apache Artemis · MyBatis-Plus 3.5 · Sa-Token 1.45 · SpringDoc 3.0 · MapStruct 1.6 · Hutool 5.8 · Caffeine 3.2 · BouncyCastle 1.84
**端口**: 9999
**启动**:
```bash
cd dax-pay-open/daxpay-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
```
## 通道子应用 dax-pay-channel-one
对接支付宝、微信、抖音、银联商务等**直连通道**的独立部署微服务,承载第三方 SDK 的直接调用。
| 模块 | 说明 |
|------|------|
| `daxpay-platform` | 基础层 — core + common (util/json/i18n) + service-system |
| `daxpay-channel-impl` | 通道实现 — alipay / wechat / douyin / ums 四个子模块 |
| `daxpay-channel-start` | 启动入口 |
**SDK 版本**: alipay-sdk `4.40.272.ALL` · weixin-java-pay (wxjava) `4.8.4.B` · douyinpay `1.0.6` · UMS 自研 HTTP 对接
**与主应用通信** — 主应用通过 `@HttpExchange` 声明式客户端调用,链路 AES-GCM 加密,响应统一 `{code, msg, data}`
**端口**: 20100
## 通道子应用 dax-pay-channel-one-go
与 Java 版 `channel-one` **完全对等**的 Go 实现,端口、路由、响应契约一致,作为通道对接层的另一种语言选择。
| 维度 | 实现 |
|------|------|
| Web 框架 | Gin v1.10.1 |
| Go 版本 | 1.26 |
| 对接通道 | 支付宝、微信 (直连 + ISV)、银联商务 (UMS)、抖音 (与 Java 版对等) |
| 第三方 SDK | **无**,全部自研 HTTP 签名对接 |
| 链路追踪 | OpenTelemetry (进程内,不导出 OTLP) |
| 国际化 | 嵌入式 JSON,支持 10 语种 |
**定位** — 与 Java 版并列的另一种语言选择,提供更高吞吐与更低内存占用的部署选项;按团队技术栈按需选用。
**端口**: 20100 (与 Java 版相同)
两者端口与路由完全重叠,同时启动会冲突。部署时二选一。
## 通道子应用 dax-pay-channel-two
对接**聚合通道**的独立部署微服务,与 `channel-one` 架构完全相同,区别在于承载的通道集合。
| 模块 | 说明 |
|------|------|
| `daxpay-platform` | 基础层 (与 channel-one 同构) |
| `daxpay-channel-impl` | 通道实现 — lakala / hkrt / dougong / leshua / vbill / hmpay / adapay / fuyou (+ yeepay 待启用) |
| `daxpay-channel-start` | 启动入口 |
**已对接通道** — 拉卡拉、海科融通、斗拱 (汇付天下)、乐刷、随行付、河马付 (杉德)、Adapay、富友;易宝已实现但启动模块未启用
**SDK 版本** — 各聚合通道 SDK + yeepay `4.4.15`
**端口**: 20200
## Web 管理端 dax-pay-ui
管理后台前端,基于 Vue Vben Admin 5 二次开发的 monorepo,**同源编译出运营端与商户端两个独立应用**。
| 子应用 | 定位 | dev 端口 | `VITE_APP_CLIENT_CODE` |
|--------|------|----------|----------------------|
| `apps/daxpay-admin` | 运营 (管理) 端 — 平台运营方使用 | 6999 | `admin` |
| `apps/daxpay-merchant` | 商户端 — 商户自助使用 | 7999 | `merchant` |
两端共用 `packages/` 下的框架包 (`@core` / `effects` / `locales` / `stores` / `utils` 等) 与 `packages/business/ui-biz` 业务组件库,通过菜单 `client_code` 与权限码实现端级隔离。
```
dax-pay-ui/
├── apps/
│ ├── daxpay-admin/ # 运营端应用
│ └── daxpay-merchant/ # 商户端应用
├── packages/ # 核心包 (@core / effects / business / locales ...)
├── internal/ # 内部工具 (lint / tsconfig / vite-config)
└── scripts/ # 脚本 (deploy / turbo-run / vsh)
```
**技术栈** — Vue 3.5 · Vite 8 · TypeScript 5.9 · antdv-next · vxe-table 4 · Vben Admin 5 · TailwindCSS 4 · vue-i18n 11 · pnpm 10 + Turbo 2.9
**国际化** — 10 语种 (中日韩 + 东盟四语 + 繁体台港),框架层与应用层消息合并加载
**启动**:
```bash
pnpm run dev:admin # 运营端 6999
pnpm run dev:merchant # 商户端 7999
```
## 移动 H5 端 dax-pay-h5
移动端网关应用,**单应用同时承载 PC 与移动两套完全独立的页面**,由入口设备探测分发。
- **设备探测** — `index.html` 在 Vue 挂载前写入 `window.__DEVICE__` (`'pc' | 'mobile'`),零闪烁
- **目录分离** — 移动端代码在 `src/mobile/`,PC 端在 `src/pc/`,公共代码在 `src/shared/`
- **移动适配** — `postcss-mobile-forever` 做 vw 适配;PC 源码被排除出 vw 转换,使用原生 px + 媒体查询
- **路由三桶** — 真实路由 / 对端独占存根 / catch-all 404,单一 URL 空间两端各自解析
**技术栈** — Vue 3.5 · Vite 8 · Vue Router 5 · Vant 4 (移动端) · UnoCSS 66 · Pinia 3 · vue-i18n 11
**端口** (dev): 9500
**国际化** — 10 语种
**启动**: `pnpm run dev`
## 运营端应用(小程序)dax-pay-app-admin
面向平台运营方的**管理类小程序**,基于 unibest 4 (uni-app + Vue 3) 二次开发,一次开发多端编译。对应 Web 运营端 (`apps/daxpay-admin`),调用 `/app-admin/` 接口管理商户、门店、用户、应用等资源。
| 维度 | 实现 |
|------|------|
| UI 库 | `@wot-ui/ui` (wot-ui v2,组件前缀 `wd-*`) |
| 列表 | z-paging |
| 样式 | UnoCSS (carbon 图标集) |
| 国际化 | vue-i18n |
**编译目标** — H5 / 微信小程序 / 支付宝小程序 / 抖音小程序 / App (Android / iOS)
**页面结构** — tabBar 三项 (工作台 / 应用 / 我的) + 商户管理子包 (`pages-merchant`) + 支付配置子包 (`pages-payment`) + 系统设置子包 (`pages-system`)
**国际化** — 全端 10 语种;**小程序端条件编译仅中英** (繁体/日韩/东盟仅 H5 与 App 打入)
**启动**:
```bash
pnpm run dev # H5
pnpm run dev:mp # 微信小程序
```
## 商户端应用(小程序)dax-pay-app-merchant (规划中)
面向商户自助的**管理类小程序**,与 `dax-pay-app-admin` (运营端) 对标,技术栈一致 (unibest 4 + wot-ui v2)。商户通过它管理自己的订单、门店、用户、应用与支付配置。
**当前状态** — 规划中,参照 `dax-pay-app-admin` 的工程结构与页面骨架实现。
## 收银小程序 dax-pay-cashier
面向最终消费者的**收银类小程序**,技术栈与 `dax-pay-app-admin` 一致,但定位极简收银。
| 维度 | 实现 |
|------|------|
| 编译端 | 微信小程序 / 支付宝小程序 / 抖音小程序 (无 App / H5) |
| 页面 | 首页 / 认证 / 支付 / 结果 (4 页,全自定义导航) |
| 子包 | 无 (极简) |
| 国际化 | 仅中英 |
**与 dax-pay-app-admin 的差异** — 后者是功能完整的运营端管理应用 (30+ 页面);前者是面向最终消费者的极简收银台,无 tabBar、无子包、依赖精简。
**启动**: `pnpm run dev:mp-weixin` (默认微信小程序)
## 文档站 dax-pay-doc
本站,基于 VitePress 2.0 构建。
**技术栈** — VitePress 2.0 · Vue 3.5 · mermaid 11 · markmap · medium-zoom · 阅读增强插件
**特性**:
- **密码保护** — 商业版板块采用构建时 AES-256-GCM 加密 + 运行时滚动密码 / 万能密码验证
- **图表** — 支持 mermaid 流程图与 markmap 思维导图
- **LLM 友好** — 构建期生成 `llms.txt` / `llms-full.txt`,可供 AI 工具直接抓取
- **中英双语** — 中文 (root) + 英文 (`/en/`)
**启动**: `pnpm dev` (5173) / `pnpm build`
---
# 架构设计总览
**源**: https://doc.open.daxpay.cn/architecture/overview.md
# 架构设计总览
DaxPay 主应用采用**基础层聚合 + 业务模块 + 启动入口**的分层范式,通道对接下沉到独立子应用,各子应用保持相同模式以便维护时对照同步。
## 主应用分层 (dax-pay-open)
```
dax-pay-open/
├── daxpay-platform/ # 基础层
│ ├── daxpay-platform-core # 通用契约: DTO / 枚举 / 异常 / 结果封装
│ ├── daxpay-platform-common # 通用技术设施 (聚合)
│ │ ├── common-i18n # 后端国际化资源 + JsonMessageSource
│ │ ├── common-mybatis-plus # ORM 配置
│ │ ├── common-redis # Redis 配置
│ │ ├── common-artemis # 消息队列
│ │ ├── common-json # JSON 序列化
│ │ ├── common-swagger # API 文档
│ │ ├── common-config # 加密 / 平台配置 / 部署模式强制
│ │ ├── common-request-context # 请求上下文
│ │ ├── common-translate # 翻译
│ │ └── common-spring # Spring 扩展
│ ├── daxpay-platform-capability # 平台能力 (聚合)
│ │ ├── capability-auth # 认证
│ │ ├── capability-audit-log # 审计日志
│ │ ├── capability-file # 文件
│ │ ├── capability-cache # 缓存
│ │ ├── capability-nonce # 防重放
│ │ ├── capability-social # 社交登录
│ │ ├── capability-wechat # 微信开放平台
│ │ ├── capability-alipay # 支付宝开放平台
│ │ ├── capability-douyin # 抖音开放平台
│ │ └── capability-sensitive-word # 敏感词
│ └── daxpay-platform-service # 平台业务服务 (聚合)
│ ├── service-iam # 用户/角色/菜单/权限码
│ ├── service-system # 字典/配置/日志
│ ├── service-baseapi # 基础 API
│ └── service-notify # 站内通知/公告/SSE
├── daxpay-payment/ # 支付业务
│ ├── daxpay-payment-core # 支付域内核: 领域模型/交易引擎/开放 API 契约
│ ├── daxpay-payment-admin # 运营管理端控制器与服务
│ ├── daxpay-payment-merchant # 商户自助端控制器与服务
│ ├── daxpay-payment-unipay # 统一收单 /unipay/**、网关产品、公开 H5
│ └── daxpay-payment-app-admin # 运营移动端 APP/小程序支付接口
├── daxpay-channel/ # 通道业务 (编排层)
│ ├── daxpay-channel-alipay # 支付宝通道 (HTTP 声明 + 配置 CRUD)
│ ├── daxpay-channel-wechat # 微信通道
│ ├── daxpay-channel-douyin # 抖音通道
│ ├── daxpay-channel-ums # 银联商务通道
│ └── ... # 共 13 个通道模块,均为编排层,不含 SDK
├── daxpay-plugin/ # 支付插件
│ ├── daxpay-plugin-easypay # 易支付协议插件
│ └── daxpay-plugin-risk # 支付风控插件 (黑名单 + 命中记录)
├── daxpay-demo/ # 功能演示模块
└── daxpay-start/ # 启动入口 (端口 9999)
```
## 通道编排与对接的职责边界
DaxPay 的通道体系严格区分**编排层** (主应用) 与**对接层** (子应用),这是 SDK 隔离的核心设计:
| 职责 | 主应用 `daxpay-channel/*` | 子应用 `channel-one` / `channel-two` |
| ---- | ------------------------ | ------------------------------------ |
| 第三方 SDK 调用 | 无任何 SDK import | 直接调用 alipay-sdk / wxjava / 等 |
| 通道配置数据 CRUD | Entity / DAO / Controller | 无持久化 |
| 支付策略编排 | strategy → service | 无业务编排 |
| HTTP 声明式接口 | `@HttpExchange` client | `@RestController` 接收 |
| 签名 / 验签 | 业务签名 (RSA) | 通道签名 (SDK 内部) |
| 回调组装 | 转发至子应用验签解析 | 原始报文验签解析 |
**调用机制** — 主应用通过 `ChannelRestClientSupport` 工厂为每个通道创建 `@HttpExchange` 代理,绑定到对应子应用 `baseUrl`;请求经过 `ChannelTransportEncryptInterceptor` 做 AES-GCM 传输加密;子应用响应统一 `{code, msg, data}` (`DaxResult`),主应用按 `code == 0` 判断成败。
**通道路由分配** — 每个通道的 `XxxClientConfig` 在编译期绑定到 `channelProperties.getOne()` (端口 20100) 或 `getTwo()` (端口 20200):
| 绑定 channel-one (20100) | 绑定 channel-two (20200) |
| ------------------------ | ------------------------ |
| 支付宝、微信、抖音、银联商务 | 拉卡拉、海科融通、斗拱、乐刷、随行付、河马付、Adapay、富友、易宝 |
## 子服务拆分原则
主应用通过 **HTTP 调用**各独立子服务,拆分目的:
- **通道 SDK 依赖隔离** — 第三方 SDK 不污染主应用,避免 alipay-sdk / wxjava 等传递依赖冲突
- **独立升级** — 子服务可按通道单独发版,高频通道升级不影响低频通道
- **弹性伸缩** — 高频通道 (支付宝、微信) 可多实例独立扩缩容
## 通道子服务清单
| 子服务 | 语言 / 框架 | 对外能力 | 端口 | 通道数 |
| ------ | ---------- | -------- | ---- | ------ |
| `dax-pay-channel-one` | Java / Spring Boot 4.1 | 直连通道对接 | 20100 | 4 (支付宝/微信/抖音/银联商务) |
| `dax-pay-channel-one-go` | Go / Gin 1.10 | 与 Java 版对等的实验副本 | 20100 | 同上 4 通道 |
| `dax-pay-channel-two` | Java / Spring Boot 4.1 | 聚合通道对接 | 20200 | 8+ (拉卡拉/海科融通/乐刷/富友等) |
> **Java + Go 双实现** — `channel-one` 与 `channel-one-go` 端口、路由与响应契约完全对等,按团队技术栈与性能诉求**按需选用**;同端口的 Java 版与 Go 版切勿同时启动。
主应用与各子服务的调用关系:
```mermaid
graph TD
P[dax-pay-open
主应用 9999]
P -->|HTTP 加密| C1[channel-one Java
20100]
P -.->|或| C1G[channel-one-go Go
20100]
P -->|HTTP 加密| C2[channel-two Java
20200]
C1 --> SDK1[支付宝 / 微信
抖音 / 银联商务 SDK]
C2 --> SDK2[拉卡拉 / 乐刷
富友 / 海科融通 等]
P --> DB[(PostgreSQL)]
P --> R[(Redis)]
P --> MQ[(Artemis)]
```
子应用是主项目结构的**轻量子集**:platform 仅保留 core + common (i18n/json 等),不含 capability/service。通用契约 (DTO/接口/异常) 放入 `platform-core`,便于后续通道子应用复用。各子应用独立 git、独立版本,无 maven 依赖,仅结构对标。
---
# 业务术语
**源**: https://doc.open.daxpay.cn/business/glossary.md
# 业务术语
> **上半部分为 DaxPay 对外统一词汇表**(菜单、运营配置、对接文档以本表为准)。
> 下半部分为行业通用术语,供参考;若与上半部分冲突,**以 DaxPay 词汇表为准**。
---
## DaxPay 对外统一词汇表
### 如何区分「渠道」和「通道」
| 字 | 站在哪一端 | 一句话 |
| -- | ---------- | ------ |
| **渠道** | 付款用户(C 端) | 钱从哪个钱包出(微信、支付宝…) |
| **通道** | 平台对接(B 端) | 跟哪家支付机构/通道方对接(微信、拉卡拉、银联商务…) |
二者不要混用:配置里「选微信」常常同时涉及「用户用微信付」和「走微信或某间连通道进件」,必须结合下表看清层级。
### 核心对象
| 术语 | 代码/字段 | 说明 |
| ---- | --------- | ---- |
| **商户** | Merchant / `mchNo` | 接入 DaxPay 的收款主体(租户)。 |
| **应用** / **商户应用** | MchApp / `appId` | 商户下的业务应用;通道路由、聚合、收银台等配置挂在应用上。口语可简称「应用」,首次说明时建议用「商户应用」。 |
| **支付渠道** | PayProvider / `provider` | C 端钱包或付款品牌:微信、支付宝、银联、抖音等。管「钱从哪个钱包出」。 |
| **支付方式** | PayMethod / `method` | 用户怎么付:扫码、JSAPI、小程序、H5、付款码等。每个方式归属一个支付渠道。管「用户怎么操作」。 |
| **支付通道** | Channel / `channel` | B 端对接的支付机构/通道方:微信支付、支付宝、拉卡拉、银联商务等。管「跟谁家对接」。 |
| **支付产品** | Product / `product` | 某通道下的对接形态,如微信直连、微信服务商、银联商务 C 扫 B 等。一个通道可挂多个产品。管「用哪家的哪个型号」。 |
| **支付能力** | Capability / `capability` | 某支付产品实际支持的发起形态;常与支付方式对应,但以产品策略声明为准。管「这个型号能做哪些事」。配置页若可自动推断,可对用户弱化展示。 |
| **通道商户** | ChannelMerchant / `channelMchNo` | 商户在某一支付产品下的进件/开户实体;**唯一绑定一个支付产品**,是收款路径的锚点。 |
| **通道应用配置** | 通道侧 App(如微信/支付宝 AppId) | 通道侧应用号、密钥、授权等;**不是**商户应用 `appId`。菜单中「微信应用」「支付宝应用」等均属此类。 |
### 编码约定(code,与枚举一致)
| 层 | 规则 | 示例 |
| -- | ---- | ---- |
| Provider / ClientEnv | C 端品牌;env 与 provider 同码 | `wechat` / `alipay` / `douyin` / `union_pay` |
| Channel | B 端机构;直连品牌一般无 `_pay`;间连可 `xxx_pay` | `wechat` / `alipay` / `douyin` / **`huifu`** / `lakala_pay` |
| Product | 通道下型号;可与 channel 不同 | 微信直连 `wechat_pay`、抖音直连 `douyin_pay`、汇付 `ada_pay`/`dougong_pay` |
| Method / Capability | **同码**;`{品牌}_{形态}`(如 `wechat_qr`、`union_qr`) | 勿用 `union_pay_qr`;勿把 product 的 `wechat_pay` 当 env |
**勿混用**:`wechat_pay` 仅支付产品;`wechat` 为渠道/通道/微信宿主环境。支付宝业务 code 为 `alipay`(无下划线),`ali_pay` 是已废弃的历史资源文件名,项目中已清理。
### 通道路由
| 术语 | 代码/字段 | 说明 |
| ---- | --------- | ---- |
| **通道路由** | PayRoute | 在**商户应用**上配置:各支付渠道/支付方式收款时使用哪个**通道商户**(进而落到支付产品与能力)。当前实现为**确定性绑定**,不是按成本/成功率做多候选智能分流。业务说明可写作「收款通道配置」。 |
| **按渠道默认** | `mode = basic` | 为每个支付渠道指定一个默认通道商户;支付能力由产品策略按支付方式自动取默认。代码历史名「基础模式」。 |
| **按支付方式** | `mode = scene` | 为每个支付方式单独指定通道商户与支付能力。代码历史名「场景模式」,**不是**扫码环境/收银台业务场景。 |
| **直接指定** | 请求已传 `channelMchNo` + `capability` | 跳过应用通道路由策略,直接按传入的通道商户与支付能力发起。完整说法可写「直接指定通道商户」。历史文案「直定 / 直传 / 精确模式 / 指定通道商户」均指本概念。 |
| **跟随通道路由** | 聚合/收银 AUTO 等 | 不单独绑通道商户,按应用通道路由解析。 |
配置与下单关系:
**配置侧**(商户应用):
```mermaid
flowchart TD
M[商户] --> APP[应用 appId]
APP --> ROUTE[通道路由]
ROUTE -->|渠道 / 方式| CM[通道商户]
CM --> PROD[产品]
PROD --> CAP[能力]
APP -.-> AGG[聚合 / 码牌 / 收银台]
APP -.-> NOTIFY[异步通知]
```
**下单侧**(交易链路):
```mermaid
flowchart TD
ORDER[下单 method 或直接指定 channelMchNo] --> PARSE[解析 product + channelMchNo + capability]
PARSE --> IMPL[走对应通道实现]
```
### 网关与展示
| 术语 | 说明 |
| ---- | ---- |
| **聚合支付** / **聚合收款配置** | 一码多付等:同一入口按环境推导或配置支付方式,再解析通道商户。 |
| **码牌** | 线下收款码牌(设备资产在「码牌管理」;扫码规则常与聚合配置关联)。 |
| **收银台** | 面向用户的收银展示页及支付项配置。 |
| **打开环境** | 用户从微信/支付宝/浏览器等打开时的环境(勿与通道路由历史名「场景模式」混淆)。 |
### 配置与凭证
| 术语 | 代码/字段 | 说明 |
| ---- | --------- | ---- |
| **对接配置** | Credential | 商户调用开放 API 的密钥、验签与通信加密配置。 |
| **异步通知配置** | Notify(商户回调) | 业务事件回调 URL 与订阅;区别于系统「通知公告」。 |
| **门店** | Store | 商户线下门店。 |
### 与业内「渠道路由」的差异
行业资料中的「渠道路由」常指:在多条可用通道中按成功率、成本、金额等因子**择优**。
DaxPay 当前「通道路由」是应用级 **1:1 路径绑定**(可选按渠道默认或按支付方式),**不含**权重分流与失败自动换通道。阅读外部资料时请勿直接等同。
---
## 交易类
| 术语 | 说明 |
| ---- | ---- |
| 支付 (Payment) | 用户通过在线支付系统将资金转移给收款方 |
| 退款 (Refund) | 支付系统将钱退还给用户,有全额退款和部分退款 |
| 撤销 (Cancel/Void) | 当天取消一笔交易(日切前),通常退手续费 |
| 冲正 | 与撤销类似,来源于 POS 机时代,用于取消超时交易 |
| 担保交易 | 用户先付款到平台,确认收货后再打款给商家 |
| 即时到账 | 付款资金直接转移到收款方,无需二次确认 |
## 资金类
| 术语 | 说明 |
| ---- | ---- |
| 充值 (Topup) | 往支付系统账户增加资金 |
| 转账 (Transfer) | 将资金从一个账户转到另一个账户 |
| 提现 (Withdraw) | 将账户余额提取到银行账户 |
| 代发 | 公司通过支付系统将资金直接转入个人账户 |
| T日 | 交易实际发生的日期 |
| T+N | 从交易日之后第 N 个工作日 |
| 会计日 | 标识一笔交易在会计层面的日期——可能与自然日不同 |
| 日切 | 会计日切换到下一天,之后需要批处理(清算/试算平衡等) |
| 结算 | 收单机构把交易资金结转给商户(结算到余额或银行卡) |
| 清算 | 机构之间交易资金的转移(通常由专门清算机构负责) |
| 轧差 | 把当天应收和应付金额相互抵消,仅转移净额(读 gá) |
| 计收费 | 支付平台针对手续费的记录和汇总 |
| 手续费 | 支付系统对交易处理或服务收取的费用 |
| 资损 | 因错误导致的资金损失 |
## 支付形态(行业通用)
| 术语 | 说明 |
| ---- | ---- |
| 快捷支付 | 提前绑定银行卡信息,快速完成后续支付 |
| 代扣 | 个人授权商户直接扣款(如水电煤代扣) |
| 卡支付 | 使用信用卡或借记卡支付 |
| 网银支付 | 跳转到银行支付页面输入账户信息完成支付 |
| 二维码支付 | 通过二维码发起支付交易 |
| 正扫 | 商户生成二维码,用户扫码支付 |
| 反扫 | 用户生成二维码,商户扫用户码收款 |
| 聚合扫码 | 一个二维码同时支持支付宝、微信等多种支付方式 |
## 商户与账户
| 术语 | 说明 |
| ---- | ---- |
| 商户入驻 | 商户进入支付系统需提交资料并签署协议的过程 |
| 会员 | 加入支付金融机构的个人 |
| 限额 | 账户在特定时间内允许交易的最大金额(单笔/日/月) |
| 冻结 / 解冻 | 因风险问题暂停/恢复账户交易或余额 |
| KYC (实名认证) | Know Your Customer,证实客户身份 |
| 签约 / 绑卡 | 会员绑定银行卡或第三方钱包,后续可快捷支付 |
| 解绑 | 取消已绑定的银行卡或钱包 |
## 资金账务
| 术语 | 说明 |
| ---- | ---- |
| 记账 | 交易记录到会计科目中 |
| 复式记账 | 每笔交易至少两个账目变动,借方和贷方金额相等 |
| 账户 | 记录特定类型财务交易的户头 |
| 科目 | 会计账簿中分类记录财务交易的项目(可多级) |
| 分录 | 记录交易在会计账簿中的具体方法——明确借方和贷方 |
| 内部户 | 不直接面向客户,用于内部会计和资金管理 |
| 中间户 | 一种特殊内部户,用于临时记账(如渠道扣款成功时) |
| 头寸 | 通俗地说就是余额情况 |
## 风控与合规
| 术语 | 说明 |
| ---- | ---- |
| 风控 | 交易的风险控制(欺诈检测/信用评估/合规检查等) |
| 反洗钱 (AML) | 预防、识别和打击将非法所得洗白的行为 |
| 反欺诈 | 预防、检测和遏制欺诈行为(信用卡盗用/账户盗用等) |
| 监管与合规 | 遵守所在国家相关法律、规章和行业标准,定期报告 |
## 交互与系统
| 术语 | 说明 |
| ---- | ---- |
| 信息流 | 交易过程中产生的非资金相关数据 |
| 资金流 | 资金的流转,分虚拟资金流(内部账户间)和实际资金流(银行账户间) |
| API 接口 | 系统间实时交互数据的一组协议(HTTP 请求/响应) |
| 文件接口 | 通过文件交换数据(清算文件/结算文件等),实时性较低 |
## 子系统分类(行业参考)
| 术语 | 说明 |
| ---- | ---- |
| 开放网关 | 对接商户的入口接口(下单/支付等),安全性要求最高 |
| 收单结算 | 负责收取商户订单并发起结算 |
| 收银核心 | 渲染可用支付方式供前端展示 |
| 支付引擎 | 负责真正的扣款或转账 |
| 渠道网关 | 行业说法;在 DaxPay 中请对照「支付通道 / 通道路由」 |
| 会员平台 | 管理会员的注册/登录/密码/实名认证 |
| 商户平台 | 管理商户的入驻/登录/交易管理 |
| 风控平台 | 针对账户和交易提供实时/离线风控 |
| 运营平台 | 订单管理/通道管理/产品管理等综合运营工具 |
---
# 通道与支付方式
**源**: https://doc.open.daxpay.cn/codes/channels.md
# 通道与支付方式
> 以下编码均取自开源版真实枚举类,以代码为准。
> 概念辨析(支付渠道 / 支付方式 / 支付通道 / 支付产品 / 支付能力)见 [业务术语](https://doc.open.daxpay.cn/business/glossary.md)。
## 支付通道 ChannelEnum
字典: `channel`。共定义 **17** 个通道枚举(按源码声明顺序)。
- **已实现** — 主应用 `daxpay-channel/` 下有完整策略实现(支付 / 关闭 / 同步 / 退款),其中部分通过通道子应用独立部署承载 SDK 调用。
- **预留** — 仅枚举定义,暂无实现代码,可按需扩展。
| code | 通道 | 状态 | 说明 |
| ---- | ---- | ---- | ---- |
| `alipay` | 支付宝 | 已实现 ✅ | 支持直连 + 服务商(ISV) |
| `wechat` | 微信支付 | 已实现 ✅ | 支持直连 + 服务商(ISV) |
| `union_pay` | 云闪付 | 预留 | — |
| `leshua_pay` | 乐刷 | 已实现 ✅ | — |
| `vbill_pay` | 随行付 | 已实现 ✅ | — |
| `huifu` | 汇付天下 | 已实现 ✅ | 下挂 `ada_pay` / `dougong_pay` 两个产品(见[产品表](#支付产品-productenum)) |
| `hkrt_pay` | 海科融通 | 已实现 ✅ | — |
| `lakala_pay` | 拉卡拉 | 已实现 ✅ | — |
| `fuyou_pay` | 富友 | 已实现 ✅ | — |
| `sheng_pay` | 盛付通 | 预留 | — |
| `ysep_pay` | 银盛 | 预留 | — |
| `quick_pay` | 快钱 | 预留 | — |
| `sand_pay` | 杉德 | 已实现 ✅ | 通过河马付(`hm_pay` 产品)间接对接(见[产品表](#支付产品-productenum)) |
| `yee_pay` | 易宝 | 已实现 ✅ | 通道子应用 `channel-two` 已实现,启动模块暂未启用 |
| `ums_pay` | 银联商务 | 已实现 ✅ | — |
| `douyin` | 抖音支付 | 已实现 ✅ | 直连品牌无 `_pay` 后缀 |
直连品牌通道一般无 `_pay` 后缀(`wechat` / `alipay` / `douyin`);间连 / 聚合通道可带 `xxx_pay`(`lakala_pay` / `huifu` 除外,详见 [业务术语](https://doc.open.daxpay.cn/business/glossary.md) 的「编码约定」小节)。
## 支付产品 ProductEnum
字典: `pay_product`。共定义 **24** 个支付产品(按源码声明顺序)。每个产品绑定一个支付通道(通过 `ProductEnum.getChannel()` 映射),通道路由的真实锚点是产品而非通道(详见 [业务术语](https://doc.open.daxpay.cn/business/glossary.md))。
- **已实现** — 有对应的 `daxpay-channel-*` 策略实现(支付 / 关闭 / 同步 / 退款),共 20 个。
- **预留** — 仅枚举定义,暂无实现代码,共 4 个。
### 支付宝
| code | 含义 | 通道 |
| ---- | ---- | ---- |
| `alipay` | 支付宝(直连) | `alipay` |
| `alipay_isv` | 支付宝(服务商) | `alipay` |
### 微信支付
| code | 含义 | 通道 |
| ---- | ---- | ---- |
| `wechat_pay` | 微信支付(直连) | `wechat` |
| `wechat_isv` | 微信支付(服务商) | `wechat` |
### 抖音支付
| code | 含义 | 通道 |
| ---- | ---- | ---- |
| `douyin_pay` | 抖音支付 | `douyin` |
### 银联商务
| code | 含义 | 通道 |
| ---- | ---- | ---- |
| `ums_qrcode` | 银联商务(C扫B) | `ums_pay` |
| `ums_jsapi` | 银联商务(公众号) | `ums_pay` |
| `ums_app` | 银联商务(APP) | `ums_pay` |
| `ums_mini` | 银联商务(小程序) | `ums_pay` |
| `ums_h5` | 银联商务(H5) | `ums_pay` |
| `ums_barcode` | 银联商务(B扫C) | `ums_pay` |
### 第三方聚合通道
| code | 含义 | 通道 | 状态 |
| ---- | ---- | ---- | ---- |
| `lakala_pay` | 拉卡拉 | `lakala_pay` | 已实现 ✅ |
| `leshua_pay` | 乐刷 | `leshua_pay` | 已实现 ✅ |
| `ada_pay` | Adapay | `huifu` | 已实现 ✅ |
| `dougong_pay` | 斗拱 | `huifu` | 已实现 ✅ |
| `hkrt_pay` | 海科融通 | `hkrt_pay` | 已实现 ✅ |
| `vbill_pay` | 随行付 | `vbill_pay` | 已实现 ✅ |
| `fuyou_pay` | 富友 | `fuyou_pay` | 已实现 ✅ |
| `hm_pay` | 河马付(杉德旗下) | `sand_pay` | 已实现 ✅ |
| `yee_pay` | 易宝 | `yee_pay` | 已实现 ✅ |
| `sheng_pay` | 盛付通 | `sheng_pay` | 预留 |
| `ysep_pay` | 银盛 | `ysep_pay` | 预留 |
| `quick_pay` | 快钱 | `quick_pay` | 预留 |
部分通道下挂多个产品,是通道路由的关键设计:
- **`huifu`**(汇付天下)→ `ada_pay` + `dougong_pay` — 两个产品共用一条汇付通道
- **`ums_pay`**(银联商务)→ 6 个产品 — C扫B / 公众号 / APP / 小程序 / H5 / B扫C 分别独立进件
- **`sand_pay`**(杉德)→ `hm_pay` — 河马付底层走杉德通道
- **`alipay`** / **`wechat`** → 各 2 个产品 — 直连 + 服务商(ISV)
## 支付方式 PayMethodEnum
字典: `pay_method`。`code` 全局唯一,每个支付方式绑定一个支付渠道(`provider`)。
> 付款码**不再**提供聚合 `aggregate_pay_barcode`。被扫时由平台按 `authCode` 前缀识别后映射为 `wechat_barcode` / `alipay_barcode` / `union_barcode`,再走通道路由。
> 规则:微信 `10–15`、支付宝 `25–30`、银联 `62`。商户可只传 `authCode`、不传 `method`。
### 聚合支付
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `aggregate_pay_qrcode` | 聚合扫码支付 | 通道原生通扫码 |
### 微信支付
| code | 含义 |
| ---- | ---- |
| `wechat_cashier` | 微信小程序收银台 |
| `wechat_qr` | 微信扫码(Native) |
| `wechat_jsapi` | 微信 JSAPI |
| `wechat_mini` | 微信小程序 |
| `wechat_h5` | 微信 H5 |
| `wechat_app` | 微信应用支付 |
| `wechat_barcode` | 微信付款码 |
### 支付宝
| code | 含义 |
| ---- | ---- |
| `alipay_qr` | 支付宝扫码 |
| `alipay_jsapi` | 支付宝 JSAPI(含小程序,官方产品码 JSAPI_PAY) |
| `alipay_pc` | 支付宝电脑支付 |
| `alipay_h5` | 支付宝 H5 |
| `alipay_app` | 支付宝应用支付 |
| `alipay_barcode` | 支付宝付款码 |
### 银联
| code | 含义 |
| ---- | ---- |
| `union_qr` | 银联扫码 |
| `union_jsapi` | 银联 JSAPI |
| `union_h5` | 银联 H5 |
| `union_barcode` | 银联付款码 |
### 抖音
| code | 含义 |
| ---- | ---- |
| `douyin_qr` | 抖音扫码支付 |
| `douyin_jsapi` | 抖音 JSAPI 支付 |
| `douyin_h5` | 抖音 H5 支付 |
| `douyin_app` | 抖音 APP 支付 |
### 卡组 (Visa / MasterCard)
| code | 含义 |
| ---- | ---- |
| `visa_card_gateway` | Visa 网关支付 |
| `visa_card_present` | Visa 刷卡支付 |
| `mastercard_card_gateway` | 万事达网关支付 |
| `mastercard_card_present` | 万事达刷卡支付 |
### 其他
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `other` | 其他支付方式 | 无固定渠道归属,`provider` 为 null |
## 通道实现架构
主应用通过 HTTP 调用独立部署的通道子应用,隔离第三方 SDK 依赖、支持独立升级与弹性伸缩。通道与子应用的对应关系、端口、SDK 版本等详见 [应用介绍](https://doc.open.daxpay.cn/architecture/apps.md)。
- **通道策略层** — 统一在主应用 `daxpay-channel/` 下(支付 / 关闭 / 同步 / 退款策略编排,不含 SDK)
- **通道子应用** — `dax-pay-channel-one`(支付宝/微信/抖音/银联商务,端口 20100)、`dax-pay-channel-two`(拉卡拉/海科融通/斗拱/乐刷/随行付/河马付/Adapay/富友,端口 20200)
新增通道可参照 `dax-pay-channel-one` / `dax-pay-channel-two` 创建独立子应用。
---
# 交易状态
**源**: https://doc.open.daxpay.cn/codes/trade-status.md
# 交易状态
> 以下编码均取自开源版真实枚举类,以代码为准。
## 支付状态 PayStatusEnum
字典: `pay_status`
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `wait` | 待支付 | 未指定通道和支付方式等信息 |
| `progress` | 支付中 | 选中通道和支付方式后发起调用 |
| `success` | 成功 | 支付成功 |
| `close` | 关闭 | 支付关闭 |
| `cancel` | 撤销 | 支付撤销 |
| `timeout` | 超时 | 订单超时后设置的中间流转状态 |
| `fail` | 失败 | 支付失败 |
## 支付状态机
```mermaid
stateDiagram-v2
[*] --> wait: 创建订单
wait --> progress: 选定通道并发起支付
progress --> success: 支付成功
progress --> fail: 支付失败
progress --> timeout: 订单超时(中间流转)
timeout --> close: 超时关单
wait --> close: 主动关单
wait --> cancel: 撤销订单
success --> [*]
close --> [*]
cancel --> [*]
fail --> [*]
```
## 交易状态 TradeStatusEnum
字典: `trade_status`
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `progress` | 执行中 | 交易处理中 |
| `success` | 成功 | 交易成功完成 |
| `fail` | 失败 | 交易失败 |
| `closed` | 关闭 | 交易已关闭 |
| `revoked` | 撤销 | 交易已撤销 |
| `exception` | 异常 | 交易出现异常 |
## 退款状态 PayRefundStatusEnum
字典: `pay_refund_status`
支付订单维度的退款进度:
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `no_refund` | 未退款 | 尚无退款操作 |
| `refunding` | 退款中 | 存在处理中的退款 |
| `partial_refund` | 部分退款 | 已完成部分退款 |
| `refunded` | 全部退款 | 支付金额已全额退回 |
## 交易类型 TradeTypeEnum
字典: `trade_type`
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `pay` | 支付 | 支付交易 |
| `cashouts` | 提现 | 提现交易 |
| `settle` | 结算 | 分润结算 |
## 普通支付业务单状态 NormalPayOrderStatusEnum
字典: `normal_order_status`
`pay_normal_order` 容器的业务状态:
| code | 含义 | 说明 |
| ---- | ---- | ---- |
| `wait_pay` | 待支付 | — |
| `paid` | 已支付 | — |
| `failed` | 支付失败 | 资金态失败,与主动关单 `closed` 区分 |
| `closed` | 已关闭 | 主动关单 / 撤销 |
| `expired` | 已过期 | 超时关单 |
---
# 项目构建
**源**: https://doc.open.daxpay.cn/deployment/build.md
# 项目构建
本页详细说明 DaxPay **每个应用**的编译、构建产物与启动方式。按后端应用、前端应用两条线组织,每个应用独立成节,包含环境要求、构建命令、产物路径与启动验证。
只想快速跑起来体验功能,建议直接走 [Docker Compose](https://doc.open.daxpay.cn/deployment/docker.md),无需本地编译。本页面向需要**二次开发或定制部署**的场景。
> 📷 **[配图]**:整体编译流程图 —— 展示从源码到可运行产物的全链路(后端 jar / 前端 dist / 小程序包),标注各应用之间的依赖关系与启动顺序
## 环境准备
各应用共同依赖与各自专属依赖汇总如下,按需安装。
| 环境 | 版本要求 | 适用应用 | 说明 |
|------|---------|---------|------|
| JDK | 25+ | 所有 Java 后端 | Java 运行环境(容器化部署可不装,镜像自带) |
| mvnd | 最新 | 所有 Java 后端 | Maven Daemon,加速编译 |
| Go | 1.26+ | dax-pay-channel-one-go | Go 通道子应用 |
| Node.js | ^22.13.0 \|\| ^24.0.0 | 所有前端 + 文档站 | 前端构建环境 |
| pnpm | >=10.0.0 | 所有前端 + 文档站 | 包管理器(强制,preinstall 会拦截 npm/yarn) |
| PostgreSQL | 14+ | 后端运行依赖 | 主数据库(编译不需要,运行需要) |
| Redis | 7+ | 后端运行依赖 | 分布式缓存 |
| Apache Artemis | 最新 | 后端运行依赖 | JMS 消息队列,支付延时通知 |
- `-DskipTests` 不再跳过测试的 AOT 处理,必须改用 `-Dmaven.test.skip=true`
- **PowerShell** 下含 `=` 的 `-D` 参数必须加引号(如 `"-Dmaven.test.skip=true"`),否则会被空格拆分
## 数据库准备
数据库需提前创建(UTF8 编码,`public` 模式)。各应用使用的库:
| 应用 | dev 库名 | prod 库名 |
|------|---------|----------|
| 主应用 dax-pay-open | `daxpay-dev` | `daxpay-prod` |
| 通道子应用(channel-one / channel-two) | 与主应用同库 `daxpay-dev` | 与主应用同库 `daxpay-prod` |
通道子应用与主应用共享同一数据库,无需单独建库。详细连接配置见 [配置说明](https://doc.open.daxpay.cn/deployment/configuration.md)。
---
## 后端应用构建
### 主应用 dax-pay-open
支付核心后端,承载支付业务、通道路由编排、风控与系统管理。
**技术栈**:Java 25 · Spring Boot 4.1.0 · PostgreSQL · Redis · Apache Artemis · MyBatis-Plus · Sa-Token · MapStruct
**端口**:9999
#### 编译
```bash
cd dax-pay-open
# 完整打包(产出可运行 jar)
mvnd clean package "-Dmaven.test.skip=true" -T 4
```
`mvnd install` 会触发全量打包并写入本地 Maven 仓库,输出庞大、耗时长,且经 PowerShell 管道易阻塞卡死。**日常构建验证只使用 `compile`,生产打包使用 `package`**。
**单模块快速编译**(只验证改动涉及的模块,比全量快很多):
```bash
cd dax-pay-open
# -pl 指定模块路径,-am 同时编译其依赖模块
mvnd compile -pl daxpay-payment/daxpay-payment-core -am "-Dmaven.test.skip=true"
```
**产物路径**:`dax-pay-open/daxpay-start/target/daxpay-union.jar`
#### 启动
```bash
# 开发模式(端口 9999)
cd dax-pay-open/daxpay-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# 生产模式(通过 jar 启动)
java -jar daxpay-start/target/daxpay-union.jar --spring.profiles.active=prod
```
生产环境凭证通过环境变量注入,详见 [配置说明 - 生产环境变量清单](https://doc.open.daxpay.cn/deployment/configuration.md#生产环境变量清单)。
#### 验证
```bash
curl http://127.0.0.1:9999/actuator/health
# 预期 {"status":"UP"}
```
启动成功后控制台输出 `应用 'dax-pay-open' 运行成功!`,dev 环境 API 文档:`http://127.0.0.1:9999/swagger-ui/index.html`
> 📷 **[配图]**:主应用模块结构 —— 展示 daxpay-platform / daxpay-payment / daxpay-channel / daxpay-plugin / daxpay-demo / daxpay-start 六大模块的职责与依赖关系
---
### 通道子应用 dax-pay-channel-one
对接支付宝、微信、抖音、银联商务等**直连通道**的独立部署微服务,承载第三方 SDK 的直接调用。
**技术栈**:Java 25 · Spring Boot 4.1.0 · 各通道官方 SDK(alipay-sdk / weixin-java-pay / douyinpay / UMS 自研 HTTP)
**端口**:20100
#### 编译
```bash
cd dax-pay-channel-one
mvnd clean package "-Dmaven.test.skip=true" -T 4
```
**产物路径**:`dax-pay-channel-one/daxpay-channel-start/target/daxpay-channel-one.jar`
#### 启动
```bash
# 开发模式(端口 20100)
cd dax-pay-channel-one/daxpay-channel-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# 生产模式
java -jar daxpay-channel-start/target/daxpay-channel-one.jar --spring.profiles.active=prod
```
#### 验证
```bash
curl http://127.0.0.1:20100/actuator/health
# 预期 {"status":"UP"}
```
主应用通过 `@HttpExchange` 声明式客户端调用本子应用,链路 AES-GCM 加密。需先启动主应用或确保主应用可达。
---
### 通道子应用 dax-pay-channel-two
对接**聚合通道**(拉卡拉、海科融通、斗拱、乐刷、富友等)的独立部署微服务,架构与 `channel-one` 完全相同,区别在于承载的通道集合。
**技术栈**:Java 25 · Spring Boot 4.1.0 · 各聚合通道 SDK
**端口**:20200
#### 编译
```bash
cd dax-pay-channel-two
mvnd clean package "-Dmaven.test.skip=true" -T 4
```
**产物路径**:`dax-pay-channel-two/daxpay-channel-start/target/daxpay-channel-two.jar`
#### 启动
```bash
# 开发模式(端口 20200)
cd dax-pay-channel-two/daxpay-channel-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# 生产模式
java -jar daxpay-channel-start/target/daxpay-channel-two.jar --spring.profiles.active=prod
```
#### 验证
```bash
curl http://127.0.0.1:20200/actuator/health
# 预期 {"status":"UP"}
```
主应用默认路由配置中 `channel-two` 为注释状态,如需启用需在 `application.yml` 的 `daxpay.channel.two.base-url` 取消注释,详见 [配置说明 - 通道子应用路由](https://doc.open.daxpay.cn/deployment/configuration.md#通道子应用路由)。
---
### 通道子应用 dax-pay-channel-one-go(Go 版)
与 Java 版 `channel-one` **完全对等**的 Go 实现,端口、路由、响应契约一致,作为通道对接层的另一种语言选择。
**技术栈**:Go 1.26 · Gin · OpenTelemetry(进程内)· 嵌入式 i18n(10 语种)
**端口**:20100(与 Java 版相同)
Go 版与 Java 版端口、路由完全重叠,同时启动会冲突。部署时二选一。
#### 编译
```bash
cd dax-pay-channel-one-go
# 编译二进制
go build -o daxpay-channel-one-go ./cmd/server/
```
#### 启动
```bash
# 方式一:直接运行二进制
./daxpay-channel-one-go
# 方式二:go run(开发期)
go run ./cmd/server/
```
**配置加载**:默认读取 `configs/config.yaml`,可通过环境变量 `DAXPAY_CONFIG` 指定其他路径。
#### 验证
```bash
curl http://127.0.0.1:20100/actuator/health
# 预期 {"status":"UP"}
```
> 📷 **[配图]**:Go 版与 Java 版对照 —— 展示两者端口、路由、响应契约的对等关系,以及选型建议(高吞吐低内存 vs 生态完整)
---
## 前端应用构建
所有前端应用均要求 Node.js ^22.13.0 \|\| ^24.0.0、pnpm >=10.0.0。首次构建前在各应用目录执行 `pnpm install`。
### Web 管理端 dax-pay-ui
基于 Vue Vben Admin 5 的 monorepo,**同源编译出运营端与商户端两个独立应用**,共用 `packages/` 框架包与 i18n 架构。
**技术栈**:Vue 3.5 · Vite 8 · TypeScript · antdv-next · vxe-table 4 · TailwindCSS 4 · vue-i18n · pnpm + Turbo
**子应用**:
| 子应用 | 定位 | dev 端口 | `VITE_APP_CLIENT_CODE` |
|--------|------|----------|----------------------|
| `apps/daxpay-admin` | 运营(管理)端 | 6999 | `admin` |
| `apps/daxpay-merchant` | 商户端 | 7999 | `merchant` |
#### 安装与开发
```bash
cd dax-pay-ui
pnpm install
# 运营端开发(端口 6999)
pnpm run dev:admin
# 商户端开发(端口 7999)
pnpm run dev:merchant
```
#### 构建
```bash
cd dax-pay-ui
# 构建全部应用(turbo 并行)
pnpm run build
# 单独构建运营端
pnpm -F daxpay-admin run build
# 单独构建商户端
pnpm -F daxpay-merchant run build
```
**产物路径**:
| 子应用 | 产物 |
|--------|------|
| 运营端 | `dax-pay-ui/apps/daxpay-admin/dist/` |
| 商户端 | `dax-pay-ui/apps/daxpay-merchant/dist/` |
#### 类型检查与代码规范
```bash
pnpm run check:type # turbo run typecheck (vue-tsc)
pnpm run lint # ESLint
```
> 📷 **[配图]**:Web 管理端 monorepo 结构 —— 展示 apps/daxpay-admin 与 apps/daxpay-merchant 共用 packages/ 框架包,通过 client_code 实现端级隔离
---
### 移动 H5 端 dax-pay-h5
单应用同时承载 **PC 与移动两套完全独立的页面**,由入口设备探测分发;移动端使用 `postcss-mobile-forever` 做 vw 适配。
**技术栈**:Vue 3.5 · Vite 8 · Vue Router · Vant 4(移动端)· UnoCSS · Pinia · vue-i18n
**端口**(dev):9500
#### 安装与开发
```bash
cd dax-pay-h5
pnpm install
# 开发(端口 9500,支持 ?device=pc|mobile 强制切换设备视图)
pnpm run dev
```
#### 构建
```bash
cd dax-pay-h5
pnpm run build
```
**产物路径**:`dax-pay-h5/dist/vant-mobile/`(注意产物目录为 `vant-mobile`,非默认 `dist/`)
H5 端单一产物同时包含 PC 与移动页面,由运行时设备探测分发,无需分别构建。开发期可用 `?device=pc|mobile` 查询参数强制指定。
---
### 小程序管理端 dax-pay-app-admin
面向平台运营方的**管理类小程序**(unibest 4 + uni-app + Vue 3),一次开发多端编译。UI 使用 `@wot-ui/ui`(wot-ui v2),列表用 z-paging。
**技术栈**:uni-app · Vue 3.4 · @wot-ui/ui v2 · z-paging · UnoCSS · vue-i18n
**编译目标**:H5 / 微信小程序 / 支付宝小程序 / 抖音小程序 / App(Android / iOS)
**端口**(H5 dev):9000
#### 安装与开发
```bash
cd dax-pay-app-admin
pnpm install
```
| 用途 | 命令 | 说明 |
|------|------|------|
| H5 开发 | `pnpm run dev` | 端口 9000 |
| 微信小程序开发 | `pnpm run dev:mp` | 需微信开发者工具 |
| 支付宝小程序开发 | `pnpm run dev:mp-alipay` | 需支付宝小程序 IDE |
| 抖音小程序开发 | `pnpm run dev:mp-toutiao` | 需抖音开发者工具 |
| App 开发 | `pnpm run dev:app` | uni-app CLI |
#### 构建
| 编译目标 | 命令 |
|---------|------|
| H5 | `pnpm run build:h5` |
| 微信小程序 | `pnpm run build:mp-weixin` |
| 支付宝小程序 | `pnpm run build:mp-alipay` |
| 抖音小程序 | `pnpm run build:mp-toutiao` |
| App | `pnpm run build:app` |
**产物路径**:`dax-pay-app-admin/dist/build/<平台>/`(如 `dist/build/h5/`、`dist/build/mp-weixin/`)
构建后可通过 `pnpm run upload:mp` 调用 `miniprogram-ci` 自动上传微信小程序(需配置上传密钥)。
---
### 收银小程序 dax-pay-cashier
面向最终消费者的**收银类小程序**,技术栈与 `dax-pay-app-admin` 一致,但定位极简收银,无 H5 / App 编译目标。
**技术栈**:uni-app · Vue 3.4 · @wot-ui/ui v2 · vue-i18n
**编译目标**:微信小程序 / 支付宝小程序 / 抖音小程序(无 H5 / App)
#### 安装与开发
```bash
cd dax-pay-cashier
pnpm install
```
| 用途 | 命令 | 说明 |
|------|------|------|
| 微信小程序开发 | `pnpm run dev` | 默认即微信小程序 |
| 支付宝小程序开发 | `pnpm run dev:mp-alipay` | 需支付宝小程序 IDE |
| 抖音小程序开发 | `pnpm run dev:mp-toutiao` | 需抖音开发者工具 |
#### 构建
| 编译目标 | 命令 |
|---------|------|
| 微信小程序 | `pnpm run build`(默认) |
| 支付宝小程序 | `pnpm run build:mp-alipay` |
| 抖音小程序 | `pnpm run build:mp-toutiao` |
**产物路径**:`dax-pay-cashier/dist/build/<平台>/`(如 `dist/build/mp-weixin/`)
---
### 商户端小程序 dax-pay-app-merchant(规划中)
> 🚧 **规划中**:`dax-pay-app-merchant`(商户端管理小程序)尚未实现。计划参照 `dax-pay-app-admin` 的工程结构与页面骨架,技术栈一致(unibest 4 + wot-ui v2),面向商户自助管理。待开发完成后补充本节。
---
### 文档站 dax-pay-doc
本站,基于 VitePress 2.0 构建,中英双语,支持 mermaid 图表与 markmap 思维导图。
**技术栈**:VitePress 2.0 · Vue 3.5 · mermaid 11 · medium-zoom · 阅读增强插件
**端口**(dev):5173(VitePress 默认)
#### 安装与开发
```bash
cd dax-pay-doc
pnpm install
pnpm run dev
```
#### 构建
```bash
cd dax-pay-doc
pnpm run build # 构建并生成 llms.txt / llms-full.txt
pnpm run preview # 本地预览构建产物
```
**产物路径**:`dax-pay-doc/dist/`
---
## 静态部署
前端应用构建后产物为静态文件,部署至 Nginx 或其他静态服务器即可。以下以 Web 管理端 + H5 端 + API 反向代理为例:
```nginx
# Web 管理端(运营端)
server {
listen 80;
server_name admin.daxpay.example.com;
root /var/www/daxpay-admin; # 运营端 dist 产物
location / {
try_files $uri $uri/ /index.html; # SPA history 路由
}
# API 反向代理到主应用
location /server/ {
proxy_pass http://127.0.0.1:9999/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# H5 端
server {
listen 80;
server_name h5.daxpay.example.com;
root /var/www/daxpay-h5/vant-mobile; # 注意 H5 产物在 vant-mobile 子目录
location / {
try_files $uri $uri/ /index.html;
}
location /server/ {
proxy_pass http://127.0.0.1:9999/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
商户端 `apps/daxpay-merchant/dist/` 部署方式与运营端一致,单独配置一个 server 即可。
## 构建验证
各应用启动成功后的验证方式汇总:
| 应用 | 验证方式 |
|------|---------|
| 主应用 dax-pay-open | 控制台输出 `应用 'dax-pay-open' 运行成功!` · `http://127.0.0.1:9999/actuator/health` |
| channel-one | `http://127.0.0.1:20100/actuator/health` |
| channel-two | `http://127.0.0.1:20200/actuator/health` |
| channel-one-go | `http://127.0.0.1:20100/actuator/health` |
| Web 运营端(dev) | `http://127.0.0.1:6999` |
| Web 商户端(dev) | `http://127.0.0.1:7999` |
| H5 端(dev) | `http://127.0.0.1:9500` |
| 小程序管理端(H5 dev) | `http://127.0.0.1:9000` |
| 文档站(dev) | `http://127.0.0.1:5173` |
## 下一步
- [项目运行](https://doc.open.daxpay.cn/deployment/run.md):按场景选择运行方式的总入口
- [配置说明](https://doc.open.daxpay.cn/deployment/configuration.md):Profile 切换、数据库、Redis、密钥与生产环境变量(按应用分单元)
- [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md):镜像构建与 docker-compose 完整模板
---
# 配置说明
**源**: https://doc.open.daxpay.cn/deployment/configuration.md
# 配置说明
本页按应用分单元说明 DaxPay 各应用的配置体系。**主应用配置最丰富**(Profile、数据库、Redis、消息队列、密钥、监控等),通道子应用与前端应用列出各自配置文件位置与关键差异。
首次部署只需关注 [主应用配置](#主应用-dax-pay-open-配置) 与 [生产环境变量清单](#生产环境变量清单);其余应用按需查阅。
> 📷 **[配图]**:配置文件全景图 —— 展示各应用配置文件在工作区中的位置分布,以及主应用与通道子应用、前端的配置依赖关系
## 配置文件位置一览
| 应用 | 配置文件位置 | 说明 |
|------|-------------|------|
| 主应用 dax-pay-open | `dax-pay-open/daxpay-start/src/main/resources/` | `application.yml` + `application-dev.yml` + `application-prod.yml` |
| dax-pay-channel-one | `dax-pay-channel-one/daxpay-channel-start/src/main/resources/` | 同上 Profile 结构 |
| dax-pay-channel-two | `dax-pay-channel-two/daxpay-channel-start/src/main/resources/` | 同上 Profile 结构 |
| dax-pay-channel-one-go | `dax-pay-channel-one-go/configs/config.yaml` | YAML 配置,可用 `DAXPAY_CONFIG` 环境变量指定路径 |
| Web 管理端(运营端) | `dax-pay-ui/apps/daxpay-admin/.env*` | `.env` / `.env.development` / `.env.production` |
| Web 管理端(商户端) | `dax-pay-ui/apps/daxpay-merchant/.env*` | 同上,`VITE_APP_CLIENT_CODE=merchant` |
| H5 端 | `dax-pay-h5/.env*` | `.env` / `.env.development` |
| 小程序管理端 | `dax-pay-app-admin/env/.env*` | unibest 约定的 `env/` 目录 |
| 收银小程序 | `dax-pay-cashier/env/.env*` | 同上 |
---
## 主应用 dax-pay-open 配置
主应用通过 Spring Profile 区分环境,核心配置集中在 `daxpay-start/src/main/resources/`。
### Profile 体系
| Profile | 说明 | 监控端点 | 日志级别 | API 文档 | 超管 |
|---------|------|---------|---------|---------|------|
| `dev`(默认) | 本地开发,排障友好 | 全开 | 业务包 DEBUG | 开启 | 开启 |
| `prod` | 生产,凭证强制环境变量注入,优雅停机 | 收紧(health/info/metrics) | 业务包 INFO | 关闭 | 关闭 |
切换方式:
```bash
# 命令行
mvnd spring-boot:run -Dspring-boot.run.profiles=prod
# 环境变量
SPRING_PROFILES_ACTIVE=prod
# 环境变量(Spring Boot 风格)
export SPRING_PROFILES_ACTIVE=prod
```
### 各应用端口
| 应用 | 端口 | Health |
|------|------|--------|
| 主应用 dax-pay-open | **9999** | `http://127.0.0.1:9999/actuator/health` |
| 通道子应用 dax-pay-channel-one | 20100 | `http://127.0.0.1:20100/actuator/health` |
| 通道子应用 dax-pay-channel-two | 20200 | `http://127.0.0.1:20200/actuator/health` |
| Web 运营端(dev) | 6999 | — |
| Web 商户端(dev) | 7999 | — |
| H5 端(dev) | 9500 | — |
| 小程序管理端(H5 dev) | 9000 | — |
| 文档站(dev) | 5173 | — |
### 数据库配置
#### PostgreSQL + HikariCP
开发环境 `application-dev.yml`:
```yaml
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/daxpay-dev?autoReconnect=true&reWriteBatchedInserts=true
username: your_username
password: your_password
hikari:
minimumIdle: 5 # 最小连接数
maximumPoolSize: 50 # 最大连接数
leak-detection-threshold: 5000 # 连接泄漏检测(毫秒)
connection-timeout: 30000 # 获取连接超时(毫秒)
idle-timeout: 600000 # 空闲连接超时(毫秒)
max-lifetime: 1800000 # 连接最大存活时间(毫秒)
```
### Redis 配置
```yaml
spring:
data:
redis:
host: localhost
port: 6379
database: 0
password: your_password
lettuce:
pool:
max-wait: 1000ms
```
### Artemis 消息队列
Artemis 用于支付延时通知等 JMS 消息场景,Docker 部署参考 [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md#artemis-容器):
```yaml
spring:
artemis:
mode: native # 连接外部独立 broker(非嵌入式)
broker-url: tcp://localhost:61616 # broker 连接地址
user: admin
password: admin
pool:
enabled: true
max-connections: 10 # 生产环境建议 20
idle-timeout: 30s
jms:
cache:
enabled: true
session-cache-size: 10 # 生产环境建议 20
pub-sub-domain: false # 默认点对点 queue
listener:
auto-startup: true
```
### 通道子应用路由
主应用通过 HTTP 调用通道子应用,路由配置:
```yaml
daxpay:
channel:
# 子应用1: 支付宝 + 微信支付(已启用)
one:
base-url: http://127.0.0.1:20100
# 子应用2: 银联 + 拉卡拉(可扩展,取消注释启用)
# two:
# base-url: http://127.0.0.1:20200
# 子应用3: 抖音 + 其他通道(未来扩展,取消注释启用)
# three:
# base-url: http://127.0.0.1:20300
```
子应用编号(`one`/`two`/`three`)固定不可改名,与路由策略中的通道分配一一对应。
### DaxPay 平台配置
命名空间 `daxpay.platform.*`:
#### 超级管理员
```yaml
daxpay:
platform:
starter:
auth:
enable-admin: true # 是否开启超级管理员(生产必须关闭)
admin-in-list: true # 用户列表中是否显示超管
```
#### RSA 证书
用于 API 接口请求/响应签名:
```yaml
daxpay:
platform:
config:
key-config:
private-key: '-----BEGIN PRIVATE KEY-----
...your private key...
-----END PRIVATE KEY-----'
public-key: '-----BEGIN PUBLIC KEY-----
...your public key...
-----END PUBLIC KEY-----'
```
生产环境通过环境变量注入:
```bash
RSA_PRIVATE_KEY='-----BEGIN PRIVATE KEY-----...'
RSA_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----...'
```
#### 数据加密
业务敏感字段(通道密钥、凭据、社交登录配置等)采用 **AES-256-GCM** 透明加密存储,由 MyBatis-Plus `TypeHandler` 在读写时自动加解密,业务层无感。
```yaml
daxpay:
platform:
config:
encrypt:
enable: true # 启用后敏感字段写入自动加密、读取自动解密
keys: # 密钥列表(支持滚动密钥,列表内版本号唯一)
- key: your-current-32-byte-aes-key # 当前密钥(加密新数据),32 字符
version: 2
- key: your-legacy-32-byte-aes-key # 历史密钥(仅解密旧数据),32 字符
version: 1
```
**滚动密钥机制**:
- 密文以 `v{版本号}:{base64(IV + AES-GCM 密文)}` 格式存储,解密时按版本前缀匹配对应密钥
- 列表**第一项**为当前密钥,负责加密新写入数据;其余为历史密钥,仅用于解密旧密文
- **轮换密钥**:生成新 32 字符密钥 → 用更大的 `version` 置于列表首位 → 保留旧密钥 → 重启应用;此后新数据用新密钥加密,历史密文仍可正常解密
- **不可删除**仍有对应密文的历史密钥,否则那部分历史数据将无法解密
- **启用后不要关闭** `enable`:关闭后已写入的密文读取时不再自动解密,会以密文原文返回
- **密钥不支持在线热切换**:配置在启动时加载为 Bean,修改 `keys` 列表后需重启生效;系统不提供管理端轮换入口,也不提供历史数据重新加密服务
#### 异常信息显示
```yaml
daxpay:
platform:
common:
exception:
show-full-message: true # dev 开启 / prod 关闭
```
### API 文档控制
```yaml
# 系统默认使用 springdoc,dev 开启 / prod 关闭
springdoc:
api-docs:
enabled: true # dev: true / prod: false
swagger-ui:
enabled: true # dev: true / prod: false
default-flat-param-object: true # 展开 GET 参数对象类型
```
dev 环境文档地址:`http://127.0.0.1:9999/swagger-ui/index.html`
### 监控端点
```yaml
# dev: 全景端点(排障友好)
management:
endpoints:
web:
exposure:
include: >
health,info,httpexchanges,
metrics,loggers,threaddump,
beans,mappings,scheduledtasks,
caches,conditions,startup
endpoint:
health:
show-details: always
```
```yaml
# prod: 严格收紧
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: never
probes:
enabled: true # k8s liveness/readiness
group:
liveness:
include: ping # 仅进程存活,不级联 DB
readiness:
include: db,redis # DB/Redis 就绪后才接流量
```
### Sa-Token 认证
安全认证基于 **Sa-Token**。yml 仅配置启动期固定项,**会话与安全策略由管理端「安全配置」菜单动态管理**:
```yaml
sa-token:
token-name: Accesstoken # token 名称(也是 cookie/请求头名),前端 SDK 硬依赖,不可变更
timeout: 259200 # token 有效期兜底(秒),仅会话管理未启用时生效;启用后以数据库配置为准
is-log: false # Sa-Token 调试日志
is-print: false # 启动 Banner
```
**会话与安全策略由管理端配置**(系统管理 → 安全配置,权限码 `system:security-config`,API 前缀 `/platform/config/security`),存储在 `system_platform_config` 表,登录时注入 Sa-Token:
| 配置组 | 可配项 | 说明 |
|--------|--------|------|
| 会话管理 | Token 有效期 / 活跃超时 / 最大并发会话数 / 并发策略 / 并发范围 | 替代 yml `timeout` / `active-timeout` / `is-concurrent`,默认有效期 72h、活跃超时 24h、并发 5 |
| 登录安全 | 登录失败锁定 / 验证码触发 | 失败次数阈值、锁定时长、验证码触发次数 |
| 密码策略 | 密码强度 / 轮换周期 / 历史次数 | 最小长度、大小写/数字/特殊字符要求 |
| 双因素认证 | 2FA (TOTP) 开关 / 发行者 / 备用码 | 配合 Authenticator App |
| API 安全 | 开放接口防重放 | Nonce 校验、请求时间窗口 |
| 支付安全 | 支付风控 | 黑名单阻断、OpenID 拦截级别、海外 IP |
| IAM 防重放 | 管理端接口防重放 | Nonce 有效期、时间戳容差 |
管理端会话配置**仅对新创建的登录会话生效**,已登录用户的 token 保留原有超时/并发属性。`is-share` 固定为 `false`(按终端隔离会话),不可配。
接口请求/响应支持 RSA 签名,公钥通过 `key-config` 配置。
### 时区与时间
- 数据库时间字段统一使用 `timestamptz(6)`(`timestamp with time zone`)
- 实体类使用 `java.time.OffsetDateTime`
- 序列化全局时区 UTC,Jackson `OffsetDateTime` → ISO UTC
- **禁止**使用 `timestamp`/`timestamp without time zone` 及 `java.util.Date`/`LocalDateTime`
### 生产环境变量清单
生产环境所有凭证通过环境变量注入,以下为 `application-prod.yml` 中定义的全部占位符:
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `SERVER_PORT` | 服务端口 | `9999` |
| `DB_HOST` | 数据库主机 | `postgresql` |
| `DB_PORT` | 数据库端口 | `5432` |
| `DB_NAME` | 数据库名 | `daxpay-prod` |
| `DB_USERNAME` | 数据库账号 | (必填) |
| `DB_PASSWORD` | 数据库密码 | (必填) |
| `REDIS_HOST` | Redis 主机 | `redis` |
| `REDIS_PORT` | Redis 端口 | `6379` |
| `REDIS_DATABASE` | Redis 库编号 | `0` |
| `REDIS_PASSWORD` | Redis 密码 | (必填) |
| `ARTEMIS_BROKER_URL` | Artemis broker 地址 | `tcp://artemis:61616` |
| `ARTEMIS_USER` | Artemis 账号 | (必填) |
| `ARTEMIS_PASSWORD` | Artemis 密码 | (必填) |
| `RSA_PRIVATE_KEY` | RSA 私钥(PEM) | (必填) |
| `RSA_PUBLIC_KEY` | RSA 公钥(PEM) | (必填) |
| `ENCRYPT_KEY` | AES 加密密钥(32 字节) | (必填) |
| `IP2REGION_FILE_PATH` | IP 地址库路径 | `/data/ip/ip2region_v4.xdb` |
| `CHANNEL_ONE_BASE_URL` | 通道子应用 1 地址 | `http://channel-one:20100` |
| `CHANNEL_TWO_BASE_URL` | 通道子应用 2 地址 | `http://channel-two:20200` |
---
## 通道子应用配置
通道子应用与主应用**共享同一数据库**,无需单独配置数据源库。各自配置文件位于 `daxpay-channel-start/src/main/resources/`,Profile 结构与主应用一致(`dev` / `prod`)。
### dax-pay-channel-one
| 配置项 | 值 | 说明 |
|--------|-----|------|
| 端口 | 20100 | `application.yml` 中 `server.port` |
| 数据库 | 与主应用同库 | dev `daxpay-dev` / prod `daxpay-prod` |
| Profile | `dev` / `prod` | 同主应用切换方式 |
通道子应用的生产环境凭证(DB / Redis 等)同样通过环境变量注入,变量名与主应用一致。Docker 部署时通过 `env_file` 共享同一份 `.env`。
### dax-pay-channel-two
| 配置项 | 值 | 说明 |
|--------|-----|------|
| 端口 | 20200 | `application.yml` 中 `server.port` |
| 数据库 | 与主应用同库 | dev `daxpay-dev` / prod `daxpay-prod` |
| Profile | `dev` / `prod` | 同主应用切换方式 |
启用 `channel-two` 时,需在主应用 `application.yml` 取消 `daxpay.channel.two.base-url` 的注释,并通过 `CHANNEL_TWO_BASE_URL` 环境变量注入地址。
### dax-pay-channel-one-go(Go 版)
Go 版配置文件为 `configs/config.yaml`,YAML 格式,对标 Java 版 `application.yml`。可用环境变量 `DAXPAY_CONFIG` 指定其他路径。
```yaml
# dax-pay-channel-one-go 配置(对标 Boot application.yml)
server:
port: 20100
tracing:
# 全采样,便于本地排障(对标 management.tracing.sampling.probability: 1.0)
sample_ratio: 1.0
# 默认不导出 OTLP(对标 otlp.enabled: false),仅进程内 span + 日志关联
otlp_enabled: false
```
Go 版端口、路由与 Java 版 `channel-one` 完全重叠,部署时二选一,切勿同时启动。
---
## 前端应用配置
前端应用配置以 Vite 环境变量(`.env*` 文件)为主,构建期注入。
### Web 管理端 dax-pay-ui
运营端与商户端共用同一 monorepo,通过环境变量 `VITE_APP_CLIENT_CODE` 区分端身份。
**运营端**(`apps/daxpay-admin/.env`):
| 变量 | 说明 | 运营端值 |
|------|------|---------|
| `VITE_APP_TITLE` | 应用标题 | `DaxPay Admin` |
| `VITE_APP_NAMESPACE` | 命名空间(缓存/store 前缀,隔离) | `daxpay-web-admin` |
| `VITE_APP_CLIENT_CODE` | 客户端身份码(对齐后端 `ClientEnum`) | `admin` |
| `VITE_APP_STORE_SECURE_KEY` | store 持久化加密密钥 | 自定义 |
**开发环境**(`.env.development`)补充:
| 变量 | 说明 | 值 |
|------|------|-----|
| `VITE_PORT` | dev 端口 | 运营端 `6999` / 商户端 `7999` |
| `VITE_GLOB_API_URL` | 接口地址前缀 | `/api` |
| `VITE_NITRO_MOCK` | 是否开启 Mock 服务 | `true` |
| `VITE_INJECT_APP_LOADING` | 注入全局 loading | `true` |
商户端(`apps/daxpay-merchant/.env`)结构相同,差异:
| 变量 | 商户端值 |
|------|---------|
| `VITE_APP_TITLE` | `DaxPay Merchant` |
| `VITE_APP_NAMESPACE` | `daxpay-web-merchant` |
| `VITE_APP_CLIENT_CODE` | `merchant` |
| `VITE_PORT`(dev) | `7999` |
两端共用 `packages/` 框架包,通过 `VITE_APP_CLIENT_CODE` 构建期注入请求头与登录参数,配合后端 `iam_perm_menu.client_code` 实现菜单/数据端级隔离。
> 📷 **[配图]**:Web 管理端双端配置对照 —— 展示运营端与商户端 .env 差异、client_code 注入链路与后端端级隔离机制
### 移动 H5 端 dax-pay-h5
配置文件位于 `dax-pay-h5/.env` / `.env.development`。
| 变量 | 说明 | 值 |
|------|------|-----|
| `VITE_PORT` | dev 端口 | `9500` |
H5 端单一产物同时包含 PC 与移动页面,由运行时设备探测分发,无需按设备分别配置。
### 小程序管理端 dax-pay-app-admin
配置文件位于 `dax-pay-app-admin/env/`(unibest 约定目录),按 `unibest.platforms` 字段决定可编译目标。
| 配置 | 说明 |
|------|------|
| `env/.env` | 基础环境变量(`VITE_APP_PORT=9000` 等) |
| 编译目标 | H5 / 微信小程序 / 支付宝小程序 / 抖音小程序 / App |
| 国际化 | 全端 10 语种;**小程序端条件编译仅中英** |
构建命令详见 [项目构建 - 小程序管理端](https://doc.open.daxpay.cn/deployment/build.md#小程序管理端-dax-pay-app-admin)。
### 收银小程序 dax-pay-cashier
配置文件位于 `dax-pay-cashier/env/`,结构与小程序管理端一致。
| 配置 | 说明 |
|------|------|
| 编译目标 | 微信小程序 / 支付宝小程序 / 抖音小程序(无 H5 / App) |
| 国际化 | 仅中英 |
构建命令详见 [项目构建 - 收银小程序](https://doc.open.daxpay.cn/deployment/build.md#收银小程序-dax-pay-cashier)。
---
## 下一步
- [项目运行](https://doc.open.daxpay.cn/deployment/run.md):按场景选择运行方式的总入口
- [项目构建](https://doc.open.daxpay.cn/deployment/build.md):各应用源码编译与产物路径(按应用分单元)
- [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md):镜像构建与 docker-compose 完整模板
---
# Docker 部署
**源**: https://doc.open.daxpay.cn/deployment/docker.md
# Docker 部署
DaxPay 各后端应用均可容器化部署。
## 后端镜像构建
基础镜像建议使用 `eclipse-temurin:25-jre`:
```dockerfile
FROM eclipse-temurin:25-jre
# 时区设置
ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
# 复制 jar 包
COPY daxpay-start/target/daxpay-union.jar app.jar
# 暴露端口
EXPOSE 9999
# JVM 选项
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8"
ENTRYPOINT exec java $JAVA_OPTS -jar app.jar --spring.profiles.active=prod
```
> **注意**: 仓库现有 `Dockerfile` 使用 `eclipse-temurin:21.0.4_7-jdk-alpine`(Java 21),项目实际要求 **Java 25**,部署时需替换为基础镜像。
### 通道子应用 channel-one
```dockerfile
FROM eclipse-temurin:25-jre
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY daxpay-channel-start/target/daxpay-channel-one.jar app.jar
EXPOSE 20100
ENTRYPOINT exec java $JAVA_OPTS -jar app.jar --spring.profiles.active=prod
```
### 通道子应用 channel-two
```dockerfile
FROM eclipse-temurin:25-jre
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY daxpay-channel-start/target/daxpay-channel-two.jar app.jar
EXPOSE 20200
ENTRYPOINT exec java $JAVA_OPTS -jar app.jar --spring.profiles.active=prod
```
## 前端镜像构建
### Web 管理端
```dockerfile
FROM node:22-slim AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_OPTIONS=--max-old-space-size=8192
RUN npm i -g corepack
WORKDIR /app
COPY . /app
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build
FROM nginx:stable-alpine AS production
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/apps/daxpay-admin/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
```
上述示例构建运营端(产物 `apps/daxpay-admin/dist`)。商户端将 COPY 路径改为 `apps/daxpay-merchant/dist`,或单独构建:`pnpm -F daxpay-merchant run build`。
### H5 端
H5 端构建产物在 `dist/vant-mobile/`(非默认 `dist/`),COPY 时注意路径:
```dockerfile
FROM node:22-slim AS builder
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
ENV NODE_OPTIONS=--max-old-space-size=8192
RUN npm i -g corepack
WORKDIR /app
COPY . /app
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build
FROM nginx:stable-alpine AS production
RUN rm -rf /etc/nginx/conf.d/default.conf
# H5 产物在 dist/vant-mobile/ 子目录
COPY --from=builder /app/dist/vant-mobile /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
```
### Nginx 配置示例
```nginx
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
listen 8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
# SPA 路由 history 模式
location / {
try_files $uri $uri/ /index.html;
}
# API 反向代理到后端
location /server/ {
proxy_pass http://daxpay-open:9999/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
```
## 环境变量
生产环境通过环境变量注入所有凭证,参考 [配置说明 - 生产环境变量清单](https://doc.open.daxpay.cn/deployment/configuration.md#生产环境变量清单)。
可通过 `env_file` 注入:
```ini
# .env
SPRING_PROFILES_ACTIVE=prod
DB_HOST=postgresql
DB_PORT=5432
DB_NAME=daxpay-prod
DB_USERNAME=admin
DB_PASSWORD=secure_password
REDIS_HOST=redis
REDIS_PASSWORD=redis_password
ARTEMIS_BROKER_URL=tcp://artemis:61616
ARTEMIS_USER=admin
ARTEMIS_PASSWORD=artemis_password
RSA_PRIVATE_KEY='-----BEGIN PRIVATE KEY-----...'
RSA_PUBLIC_KEY='-----BEGIN PUBLIC KEY-----...'
ENCRYPT_KEY=your-32-byte-aes-key-here!
CHANNEL_ONE_BASE_URL=http://channel-one:20100
CHANNEL_TWO_BASE_URL=http://channel-two:20200
```
## Artemis 容器
支付延时通知依赖 Apache Artemis 消息队列:
```yaml
# docker-compose.yml (partial)
services:
artemis:
image: apache/artemis:latest-alpine
container_name: artemis
restart: unless-stopped
ports:
- "61616:61616" # Core/JMS 端口
- "8161:8161" # Web 管理控制台(仅内网)
environment:
ARTEMIS_USER: ${ARTEMIS_USER}
ARTEMIS_PASSWORD: ${ARTEMIS_PASSWORD}
ANONYMOUS_LOGIN: "false"
TZ: Asia/Shanghai
JAVA_OPTS_APPEND: "-Xms128m -Xmx512m -XX:MaxRAMPercentage=75"
volumes:
- artemis-data:/var/lib/artemis-instance
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://localhost:8161/ || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 40s
volumes:
artemis-data:
```
## docker-compose 编排
完整的本地 Docker Compose 编排模板:
```yaml
services:
# PostgreSQL
postgresql:
image: postgres:16-alpine
container_name: postgresql
restart: unless-stopped
environment:
POSTGRES_DB: daxpay-prod
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
TZ: Asia/Shanghai
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME} -d daxpay-prod"]
interval: 10s
timeout: 5s
retries: 5
# Redis
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
command: redis-server --requirepass ${REDIS_PASSWORD}
ports:
- "6379:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# Artemis
artemis:
image: apache/artemis:latest-alpine
container_name: artemis
restart: unless-stopped
ports:
- "61616:61616"
- "8161:8161"
environment:
ARTEMIS_USER: ${ARTEMIS_USER}
ARTEMIS_PASSWORD: ${ARTEMIS_PASSWORD}
ANONYMOUS_LOGIN: "false"
TZ: Asia/Shanghai
JAVA_OPTS_APPEND: "-Xms128m -Xmx512m"
volumes:
- artemis-data:/var/lib/artemis-instance
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://localhost:8161/ || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 40s
# 主应用
daxpay-open:
build:
context: ./dax-pay-open
dockerfile: Dockerfile.prod # Java 25 基础镜像
container_name: daxpay-open
restart: unless-stopped
ports:
- "9999:9999"
env_file:
- .env
environment:
SPRING_PROFILES_ACTIVE: prod
DB_HOST: postgresql
REDIS_HOST: redis
ARTEMIS_BROKER_URL: tcp://artemis:61616
CHANNEL_ONE_BASE_URL: http://channel-one:20100
CHANNEL_TWO_BASE_URL: http://channel-two:20200
depends_on:
postgresql:
condition: service_healthy
redis:
condition: service_healthy
artemis:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget --spider -q http://localhost:9999/actuator/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# 通道子应用 1
channel-one:
build:
context: ./dax-pay-channel-one
dockerfile: Dockerfile.product
container_name: channel-one
restart: unless-stopped
ports:
- "20100:20100"
env_file:
- .env
environment:
SPRING_PROFILES_ACTIVE: prod
DB_HOST: postgresql
depends_on:
postgresql:
condition: service_healthy
daxpay-open:
condition: service_healthy
# 通道子应用 2(可选,需主应用启用 daxpay.channel.two)
channel-two:
build:
context: ./dax-pay-channel-two
dockerfile: Dockerfile.product
container_name: channel-two
restart: unless-stopped
ports:
- "20200:20200"
env_file:
- .env
environment:
SPRING_PROFILES_ACTIVE: prod
DB_HOST: postgresql
depends_on:
postgresql:
condition: service_healthy
daxpay-open:
condition: service_healthy
volumes:
pgdata:
redis-data:
artemis-data:
```
## 启动与停止
```bash
# 启动全部服务
docker compose --env-file .env up -d
# 查看日志
docker compose logs -f daxpay-open
docker compose logs -f channel-one
docker compose logs -f channel-two
# 停止全部服务
docker compose down
```
## 验证
```bash
# 主应用健康检查
curl http://localhost:9999/actuator/health
# 通道子应用健康检查
curl http://localhost:20100/actuator/health
curl http://localhost:20200/actuator/health
```
预期返回 `{"status":"UP"}`。
---
# 项目运行
**源**: https://doc.open.daxpay.cn/deployment/run.md
# 项目运行
本页是运行 DaxPay 的总入口,帮你按场景选择最合适的运行方式,并给出前置依赖与启动后的验证方法。
## 运行方式速览
| 方式 | 适用场景 | 说明 |
|------|---------|------|
| [Docker Compose](https://doc.open.daxpay.cn/deployment/docker.md) | 最快体验、本地联调 | 一条命令拉起 PostgreSQL / Redis / Artemis / 主应用 / 通道子应用,推荐首次试用 |
| [项目构建](https://doc.open.daxpay.cn/deployment/build.md) | 二次开发、定制部署 | clone 源码后 mvnd / pnpm 编译,适合需要修改源码的场景 |
| [配置说明](https://doc.open.daxpay.cn/deployment/configuration.md) | 调整 Profile、端口、数据库、密钥等 | 生产部署与凭证注入必读 |
首次接触 DaxPay 建议直接走 [Docker Compose](https://doc.open.daxpay.cn/deployment/docker.md),几分钟即可在本地跑起完整链路。
## 前置依赖
| 环境 | 版本要求 | 说明 |
|------|---------|------|
| JDK | 25+ | Java 运行环境(容器化部署可不装,镜像自带) |
| mvnd | 最新 | Maven Daemon,加速源码编译 |
| Node.js | ^22.13.0 \|\| ^24.0.0 | 前端构建环境 |
| pnpm | >=10.0.0 | 包管理器(强制,禁用 npm/yarn) |
| PostgreSQL | 14+ | 主数据库 |
| Redis | 7+ | 分布式缓存 |
| Apache Artemis | 最新 | JMS 消息队列,用于支付延时通知 |
数据库需提前创建(UTF8 编码,`public` 模式),库名约定与详细要求见 [项目构建 - 数据库准备](https://doc.open.daxpay.cn/deployment/build.md#数据库准备)。
## 各应用端口
| 应用 | 端口 | 健康检查 |
|------|------|---------|
| 主应用 dax-pay-open | 9999 | `http://127.0.0.1:9999/actuator/health` |
| 通道子应用 dax-pay-channel-one | 20100 | `http://127.0.0.1:20100/actuator/health` |
| 通道子应用 dax-pay-channel-two | 20200 | `http://127.0.0.1:20200/actuator/health` |
| Web 运营端(dev) | 6999 | — |
| Web 商户端(dev) | 7999 | — |
| H5 端(dev) | 9500 | — |
| 小程序管理端(H5 dev) | 9000 | — |
| 文档站(dev) | 5173 | — |
通道子应用另有 Go 版本 `dax-pay-channel-one-go`,端口同为 20100,与 Java 版二选一,切勿同时启动。
## 最快路径:Docker Compose
准备好 `.env`(数据库 / Redis / Artemis / RSA / AES 等凭证,详见 [配置说明 - 生产环境变量清单](https://doc.open.daxpay.cn/deployment/configuration.md#生产环境变量清单))后:
```bash
# 拉起全部服务
docker compose --env-file .env up -d
# 查看主应用日志
docker compose logs -f daxpay-open
```
完整的 `docker-compose.yml` 编排模板见 [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md)。
## 启动后验证
```bash
# 主应用健康检查,预期 {"status":"UP"}
curl http://localhost:9999/actuator/health
# 通道子应用
curl http://localhost:20100/actuator/health
```
启动成功后可访问:
- 主应用控制台输出 `应用 'dax-pay-open' 运行成功!`
- API 文档(dev):`http://127.0.0.1:9999/swagger-ui/index.html`
- Web 运营端(dev):`http://127.0.0.1:6999`
- Web 商户端(dev):`http://127.0.0.1:7999`
- H5 端(dev):`http://127.0.0.1:9500`
## 下一步
- [项目构建](https://doc.open.daxpay.cn/deployment/build.md):各应用源码编译与产物路径(按应用分单元)
- [配置说明](https://doc.open.daxpay.cn/deployment/configuration.md):Profile 切换、数据库、Redis、密钥与生产环境变量(按应用分单元)
- [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md):镜像构建与 docker-compose 完整模板
---
# 架构总览
**源**: https://doc.open.daxpay.cn/getting-started/architecture-overview.md
# 架构总览
DaxPay 由多个独立 git 仓库的子项目协同构成,主应用通过 HTTP 调用各独立通道子服务,实现通道 SDK 隔离、独立升级与弹性伸缩。前端三端 (Web / H5 / 小程序) 通过 RESTful API 接入主应用。
> 各子项目均为**独立 git 仓库**、独立版本号,仅本地联调时可聚合到同一工作区;生产部署各自独立打包、独立发布。
## 调用关系
```mermaid
graph LR
BIZ[业务系统] -->|HTTP 签名| P[dax-pay-open
主应用 9999]
UI[Web 管理端] -->|RESTful| P
H5[H5 / 小程序] -->|RESTful| P
P -->|HTTP AES-GCM| C1[channel-one / one-go
直连通道 20100]
P -->|HTTP AES-GCM| C2[channel-two
聚合通道 20200]
C1 --> TP1[第三方支付
支付宝/微信/抖音/银联]
C2 --> TP2[第三方支付
拉卡拉/乐刷/富友等]
P --> DB[(PostgreSQL)]
P --> R[(Redis)]
P --> MQ[(Artemis)]
```
## 子项目职责
| 子项目 | 端口 | 职责 |
| ------ | ---- | ---- |
| `dax-pay-open` | 9999 | 支付核心、通道路由编排、风控、IAM 权限、系统管理 |
| `dax-pay-channel-one` | 20100 | 对接支付宝/微信/抖音/银联商务直连通道 (Java) |
| `dax-pay-channel-one-go` | 20100 | 与 Java 版对等的 Go/Gin 实现,按需选用 |
| `dax-pay-channel-two` | 20200 | 对接拉卡拉/海科融通/乐刷等聚合通道 (Java) |
| `dax-pay-ui` | 6999 / 7999 | 运营端 (admin) / 商户端 (merchant) 管理后台 |
| `dax-pay-h5` | 9500 | 收银台、移动端网关 (PC + Mobile 双端) |
| `dax-pay-app-admin` | — | 运营端应用小程序 (H5/微信/支付宝/抖音/App) |
| `dax-pay-app-merchant` | — | 商户端应用小程序 (规划中,参照 dax-pay-app-admin) |
| `dax-pay-cashier` | — | 收银小程序 (微信/支付宝/抖音) |
| `dax-pay-doc` | 5173 | VitePress 文档站 |
## 技术栈一览
| 层级 | 技术 |
| ---- | ---- |
| 主应用 | Java 25 · Spring Boot 4.1.0 · PostgreSQL 14+ · Redis 7+ · Apache Artemis · MyBatis-Plus 3.5 · Sa-Token 1.45 · SpringDoc 3.0 · MapStruct 1.6 |
| 通道子应用 | Java 25 · Spring Boot 4.1.0 (同主应用) / Go 1.26 · Gin 1.10 |
| Web 管理端 | Vue 3.5 · Vite 8 · antdv-next · Vben Admin 5 · vxe-table 4 · TailwindCSS 4 · pnpm + Turbo |
| H5 端 | Vue 3.5 · Vite 8 · Vant 4 · UnoCSS · postcss-mobile-forever |
| 小程序端 | uni-app · unibest 4 · wot-ui v2 · Vue 3.4 |
| 文档站 | VitePress 2.0 · Vue 3.5 · mermaid |
| 权限 | Sa-Token (token name: `Accesstoken`) · RBAC |
| 接口 | RESTful (kebab-case) · RSA 签名 · AES-GCM 加密 |
详细的子项目架构见 [整体架构](https://doc.open.daxpay.cn/architecture/overview.md) 与 [应用介绍](https://doc.open.daxpay.cn/architecture/apps.md)。
---
# 交流群
**源**: https://doc.open.daxpay.cn/getting-started/community.md
# 交流群
欢迎加入 DaxPay 社区交流,获取使用帮助、版本更新通知与技术讨论。
## QQ 交流群
扫码加入 QQ 交流群,群号:**839738244**
> 📷 **[配图]**:QQ 群二维码 —— QQ 群 839738244 的加群二维码
## 微信交流群
微信扫码添加小助手,由小助手邀请加入微信交流群,小助手微信号:`sdcit2020`
> 📷 **[配图]**:微信小助手二维码 —— 小助手 sdcit2020 的微信二维码
## 微信公众号
关注微信公众号,定期更新使用教程、版本更新记录和各种活动信息。
> 📷 **[配图]**:微信公众号二维码 —— 公众号关注二维码
公众号名称待补充,扫码即可关注。
## 代码仓库
DaxPay 在 GitHub 与 Gitee 同步开源,欢迎 Star 支持项目发展。
| 平台 | 仓库 | 说明 |
|------|------|------|
| GitHub | [dromara/dax-pay](https://github.com/dromara/dax-pay) | 主仓库,优先更新 |
| Gitee | [dromara/dax-pay](https://gitee.com/dromara/dax-pay) | 国内镜像 |
## 问题反馈
| 渠道 | 适用场景 |
|------|---------|
| [GitHub Issues](https://github.com/dromara/dax-pay/issues) | Bug 报告、功能建议 |
| [交流群](#qq-交流群) | 使用疑问、技术讨论 |
| [FAQ](https://doc.open.daxpay.cn/getting-started/faq.md) | 常见问题自查 |
提交 Bug 时请附复现步骤、环境信息(系统 / Java 版本 / 浏览器)与日志,有助于快速定位。
## 贡献代码
DaxPay 是开源项目,欢迎提交 Pull Request 贡献代码。贡献前请:
1. Fork 仓库并创建特性分支
2. 遵循项目编码规范(详见各端开发约定)
3. 提交清晰的 Commit 说明
4. 发起 Pull Request 并描述改动内容
> 📷 **[配图]**:贡献流程 —— 展示 Fork → Clone → Branch → Commit → PR 的协作流程示意
---
# 系统演示
**源**: https://doc.open.daxpay.cn/getting-started/demo.md
# 系统演示
在线演示环境正在筹备,敬请期待。在演示环境上线前,推荐通过以下方式体验 DaxPay 全部功能。
## 本地快速体验
无需在线演示环境,通过 Docker Compose 几分钟即可在本地跑起完整支付链路(主应用 + 通道子应用 + PostgreSQL + Redis + Artemis):
```bash
# 准备 .env 后一键启动
docker compose --env-file .env up -d
```
详细步骤见 [项目运行](https://doc.open.daxpay.cn/deployment/run.md) 与 [Docker 部署](https://doc.open.daxpay.cn/deployment/docker.md)。
启动后访问:
| 应用 | 地址 |
|------|------|
| 运营端(管理后台) | `http://127.0.0.1:6999` |
| 商户端 | `http://127.0.0.1:7999` |
| H5 端 | `http://127.0.0.1:9500` |
| API 文档(dev) | `http://127.0.0.1:9999/swagger-ui/index.html` |
## 在线演示(规划中)
在线演示环境将提供运营端、商户端的体验入口,无需本地部署即可在线操作。
> 📷 **[配图]**:演示环境总览 —— 展示运营端管理后台首页截图,包含工作台、数据概览等核心界面
### 演示账号
> 📷 **[配图]**:演示账号登录页 —— 展示登录界面与演示账号输入
演示环境账号将在上线后公布:
| 端 | 角色 | 账号 | 密码 |
|----|------|------|------|
| 运营端 | 超级管理员 | (待公布) | (待公布) |
| 运营端 | 运营人员 | (待公布) | (待公布) |
| 商户端 | 商户管理员 | (待公布) | (待公布) |
演示环境数据每日重置,请勿录入真实业务数据与敏感信息。
### 功能演示
演示环境覆盖 DaxPay 核心功能模块:
> 📷 **[配图]**:功能模块导览 —— 多张截图组合,展示支付配置、通道管理、交易订单、退款管理等核心页面
- **商户与应用管理** — 商户进件、多应用配置、支付参数
- **通道路由** — 多通道路由策略、支付产品配置
- **交易订单** — 支付、退款、查询、回调记录
- **系统管理** — 用户、角色、权限、菜单
- **多端管理** — 运营端 / 商户端 / H5 / 小程序
## 反馈与交流
演示过程中如有疑问或建议,欢迎到 [GitHub Issues](https://github.com/dromara/dax-pay/issues) 反馈或加入 [交流群](https://doc.open.daxpay.cn/getting-started/community.md) 讨论。
---
# 常见问题
**源**: https://doc.open.daxpay.cn/getting-started/faq.md
# 常见问题
汇总 DaxPay 使用、部署、二次开发中高频出现的疑问。未覆盖的问题可至 [GitHub Issues](https://github.com/dromara/dax-pay/issues) 或 [交流群](https://doc.open.daxpay.cn/getting-started/community.md) 反馈。
## 基础概念
### DaxPay 是什么
DaxPay 是一款开源支付系统,提供支付、退款、查询、回调等支付核心能力,将支付宝、微信、银联等多种支付通道封装为**统一的 HTTP 接口**,业务系统只需对接一套标准协议即可接入多种支付方式。详见 [项目介绍](https://doc.open.daxpay.cn/getting-started/introduction.md)。
### 开源版和商业版有什么区别
**开源版**(本项目)交付完整的支付核心链路与多端管理界面,基于 `LGPL v3.0` 协议开源。
**商业版**(dax-pay-plus)在开源版基础上扩展:
- **更多聚合通道** — 20+ 渠道子模块
- **分账与结算**、**国际支付通道**等增强能力
> 分账结算为商业版能力,**不在开源版交付范围内**。
### LGPL v3.0 协议可以商用吗
可以。LGPL v3.0 允许商业使用。你的业务系统可以通过接口调用或动态链接方式使用 DaxPay,无需开源你的业务代码。详见 [开源协议](https://doc.open.daxpay.cn/resources/license.md)。
## 部署运行
### 后端编译必须用 mvnd 吗
项目约定使用 [mvnd](https://github.com/apache/maven-mvnd)(Maven Daemon)加速编译。普通 `mvn` 也能编译,但 mvnd 自带守护进程,增量编译速度显著更快,推荐使用。
### Apache Artemis 能否替换为其他消息队列
当前版本**强依赖 Artemis**(用于支付延时通知等 JMS 场景),不支持直接替换为 RabbitMQ / Kafka。如需替换需自行改造消息中间件适配层。
### 支持哪些数据库
仅支持 **PostgreSQL 14+**。时间字段统一使用 `timestamptz(6)`,实体类使用 `OffsetDateTime`,不支持 MySQL / Oracle 等。
### 容器化部署最低配置
建议最低 **2 核 4G**(含 PostgreSQL / Redis / Artemis / 主应用 / 通道子应用全部容器化)。生产环境建议 **4 核 8G** 起步,并根据交易量水平扩展通道子应用实例。
### PowerShell 下 mvnd 编译参数报错
PowerShell 下含 `=` 的 `-D` 参数会被空格拆分,必须加引号:
```powershell
# 错误 — 会被拆分
mvnd compile -Dmaven.test.skip=true
# 正确 — 加引号
mvnd compile "-Dmaven.test.skip=true"
```
详见 [项目构建](https://doc.open.daxpay.cn/deployment/build.md)。
## 通道对接
### 开源版已支持哪些支付通道
已对接 **12 个**国内支付通道:
- **直连通道**(`channel-one`)— 支付宝、微信、抖音、银联商务
- **聚合通道**(`channel-two`)— 拉卡拉、海科融通、斗拱(汇付天下)、乐刷、随行付、河马付(杉德)、Adapay、富友
详见 [特色功能 - 通道总数与分布](https://doc.open.daxpay.cn/getting-started/features.md#通道总数与分布)。
### 如何新增一个支付通道
1. 在对应通道子应用(直连走 `channel-one`,聚合走 `channel-two`)的 `daxpay-channel-impl` 下实现 SDK 调用与签名/验签
2. 在主应用 `daxpay-channel` 注册通道策略与配置数据 CRUD
3. 在 `ChannelEnum` 补充通道枚举
新增通道只需实现 SDK 调用并注册策略,不影响主链路。
### channel-one 和 channel-two 有什么区别
两者架构完全相同,区别在于**承载的通道集合**:
- `channel-one` — 对接支付宝、微信等**直连通道**(官方 SDK)
- `channel-two` — 对接拉卡拉、富友等**聚合通道**(聚合 SDK)
主应用通过 `daxpay.channel.one.base-url` / `daxpay.channel.two.base-url` 路由,子应用编号固定不可改名。
### 通道子应用的 Java 版和 Go 版怎么选
`channel-one` 同时提供 Java(Spring Boot)与 Go(Gin)两套**完全对等**的实现,端口、路由、响应契约一致:
- **Java 版** — 生态完整,通道官方 SDK 现成,适合快速对接
- **Go 版** — 更高吞吐、更低内存占用,全部自研 HTTP 签名对接(无第三方 SDK)
按团队技术栈与性能诉求选用,**两者二选一,端口冲突不可同时启动**。
### 通道子应用必须独立部署吗
是的。通道子应用独立部署是 DaxPay 的核心设计 —— 将第三方 SDK 隔离到子应用,避免 SDK 依赖污染主应用,支持独立升级与弹性伸缩。主应用通过 `@HttpExchange` 声明式 HTTP 客户端调用子应用,链路 AES-GCM 加密。
## 功能边界
### 是否支持分账 / 提现
分账与结算是**后续规划**能力,当前开源版尚未实现。提现(代付)同理。这些属于商业版的增强方向。
### 是否支持国际支付(PayPal / Stripe)
国际支付通道(PayPal / Stripe 等)为**后续规划**,当前开源版聚焦国内支付通道。预留了 `境外卡支付` 枚举与扩展点。
### 沙箱环境怎么用
DaxPay 采用**部署级沙箱隔离**:
- 测试 / 开发环境配置 `daxpay.platform.config.sandbox-enabled=true`,允许沙箱联调
- **生产环境必须配置** `sandbox-enabled=false`,启动时会强制将所有 `activeEnv=sandbox` 的产品重置为 `prod`,保证生产数据纯净
沙箱联调请走独立的测试环境部署,生产数据库严禁从测试环境导入数据。详见 [配置说明](https://doc.open.daxpay.cn/deployment/configuration.md)。
### 是否支持多商户 / 多商户隔离
支持。DaxPay 原生支持多商户模式:
- 运营端 + 商户端双入口,数据行级隔离(商户编号自动隔离)
- 单商户可配置多个支付应用,独立凭证与回调地址
## 二次开发
### 能否修改源码用于自己的项目
可以。基于 LGPL v3.0,你可以自由修改、使用源码。若你**修改了 DaxPay 库本身**(而非通过接口调用),需以 LGPL 协议开源你的修改;若仅通过接口调用或动态链接,你的业务代码无需开源。
### 前端如何对接后端接口
前端通过 RESTful HTTP 接口对接主应用(端口 9999),接口请求 / 响应支持 **RSA 签名**防篡改,认证基于 **Sa-Token**(token name: `Accesstoken`)。详细接入方式见 [接口文档](https://doc.open.daxpay.cn/api/overview.md)。
### 如何新增一种界面语言(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 脚本位于 `dax-pay-open/_config/sql/`,全新安装顺序为 `tables.sql`(建表)→ `datas.sql`(初始数据)。仓内另提供升级脚本 `update-tables.sql` → `update-datas.sql` 与菜单种子 `iam_perm_menu.sql`。
全量 `tables.sql` / `datas.sql` **不在仓库内**(体积大),需从飞书安装包或历史版本获取。仓内 `README.md` 有说明。
---
未找到答案?欢迎到 [GitHub Issues](https://github.com/dromara/dax-pay/issues) 提问或加入 [交流群](https://doc.open.daxpay.cn/getting-started/community.md) 讨论。
---
# 特色功能
**源**: https://doc.open.daxpay.cn/getting-started/features.md
# 特色功能
以下为 DaxPay 开源版已实现的核心功能亮点,涵盖支付能力、通道统一封装、支付方式、安全机制与国际化时区。
## 支付核心能力
DaxPay 覆盖支付交易的完整生命周期:
- **支付** — 统一下单,支持主流支付渠道与多种支付方式
- **退款** — 全额 / 部分退款,支持退款同步与差错处理
- **查询** — 订单状态、交易明细、通道流水查询
- **回调** — 异步通知机制,保证最终一致性
- **同步** — 主动向通道查询订单状态,补偿回调丢失
- **关闭** — 订单超时关闭、网关超时兜底
- **商户通知** — 商户回调消息分发、重试策略、通知任务调度
## 通道架构:编排与对接分离
DaxPay 的通道体系采用**主应用编排 + 子应用对接**的分层架构,这是其区别于单体支付系统的核心设计:
| 层级 | 职责 | 实现 |
| ---- | ---- | ---- |
| **编排层** (主应用 `daxpay-channel`) | 通道声明、通道路由、支付策略编排、配置数据 CRUD、回调组装 | 不含第三方 SDK |
| **对接层** (子应用 `channel-one` / `channel-two`) | 第三方 SDK 直接调用、签名/验签、通道专属协议适配 | 独立部署 |
主应用通过声明式 HTTP 客户端 (`@HttpExchange`) 调用子应用,链路全程 **AES-GCM 传输加密**,响应统一 `{code, msg, data}` 契约。这样设计的收益:
- **SDK 依赖隔离** — 第三方 SDK 不污染主应用,避免版本冲突
- **独立升级** — 子应用可按通道单独发版,不影响主链路
- **弹性伸缩** — 高频通道(支付宝、微信)可多实例独立扩缩容
- **双语言实现** — 通道子应用同时提供 **Java (Spring Boot)** 与 **Go (Gin)** 两套对等实现,按需选用
### 通道总数与分布
DaxPay 已对接 **12 个**国内支付通道模块,涵盖直连与聚合两类:
- **直连通道** (`channel-one`) — 支付宝、微信、抖音、银联商务
- **聚合通道** (`channel-two`) — 拉卡拉、海科融通、斗拱 (汇付天下)、乐刷、随行付、河马付 (杉德)、Adapay、富友,以及易宝 (待启用)
此外 `ChannelEnum` 还预定义了银联、盛付通、银盛、快钱、杉德 等通道枚举,可按需扩展对接。新增通道只需在对应子应用实现 SDK 调用并在主应用注册策略。
## 支付方式
覆盖主流支付场景:
- **聚合支付** — 一码多付,自动路由到用户钱包
- **扫码支付** — 主扫、被扫
- **JSAPI 支付** — 微信 / 支付宝 / 抖音公众号、小程序内调起
- **H5 支付** — 手机浏览器调起钱包
- **APP 支付** — 原生 SDK 拉起
- **小程序支付** — 微信 / 支付宝 / 抖音
- **付款码支付** — 商户扫用户动态码
- **抖音支付** — 扫码 / JSAPI / H5 / APP
- **境外卡支付** — Visa / MasterCard 网关与刷卡 (预留)
## 多商户与多端管理
- **双入口架构** — 运营端 (平台运营方使用) 与商户端 (商户自助使用) 同源编译,菜单与数据按 `client_code` 隔离
- **多应用管理** — 单商户可配置多个支付应用,独立凭证与回调地址
- **行级数据隔离** — 每个商户的数据通过商户编号自动隔离,彼此互不可见
## 通道路由与风控
- **动态路由** — 按支付产品、通道可用性、成本策略动态匹配最优通道
- **产品策略** — `ProductStrategySupport` 策略模式,支持按支付方式 (扫码/JSAPI/...) 选路
- **环境一致性校验** — 路由层兜底校验商户环境与产品当前环境 (沙箱/生产) 一致
- **风控插件** — `daxpay-plugin-risk` 黑名单 + 命中记录,支持交易前风险检查
## 安全机制
DaxPay 在接口、传输、存储、认证多个层面构建安全防护:
- **签名防篡改** — 接口请求与响应支持 RSA 签名
- **字段级加密** — 敏感字段 AES-256-GCM 加密存储
- **传输加密** — 主应用与通道子应用之间全程 AES-GCM 加密
- **权限认证** — Sa-Token (token name: `Accesstoken`),RBAC 角色权限码 + 菜单数据隔离
- **两步验证** — TOTP 一次性密码 + 备份码,支持 Google Authenticator
- **社交登录** — 微信 / 支付宝 / 抖音开放平台扫码登录
- **沙箱 / 生产隔离** — 部署级隔离,`sandbox-enabled=false` 时启动期强制重置所有产品为生产环境
## 国际化与时区
- **10 语种支持** — 简体中文、英文、繁体中文 (台 / 港)、日文、韩文,以及东盟四语 (印尼 / 越南 / 泰 / 马来)
- **JSON 资源源** — 自定义 `JsonMessageSource`,按 locale 目录 + 业务模块拆分,枚举翻译通过 `I18nSupport` 接口驱动
- **时区统一** — 数据库时间字段统一 `timestamptz(6)`,实体统一 `OffsetDateTime`,UTC 存储
- **回退链** — 当前 locale → `zh-CN` → 语言码,缺 key 自动回退
## 全端覆盖
| 端 | 应用 | 技术栈 |
| -- | ---- | ------ |
| 运营 Web | `daxpay-admin` | Vue 3.5 · Vite 8 · antdv-next · Vben Admin 5 |
| 商户 Web | `daxpay-merchant` | 同上,同源编译 |
| 移动 H5 | `dax-pay-h5` | Vue 3.5 · Vant 4 · UnoCSS (PC + Mobile 双端) |
| 运营端应用(小程序) | `dax-pay-app-admin` | uni-app · wot-ui v2 (H5 / 微信 / 支付宝 / 抖音 / App) |
| 商户端应用(小程序) | 规划中(参照 dax-pay-app-admin) | uni-app · wot-ui v2 |
| 收银小程序 | `dax-pay-cashier` | uni-app · wot-ui v2 (微信 / 支付宝 / 抖音) |
## 可观测性与运维
- **链路追踪** — OpenTelemetry 集成,日志关联 traceId (不导出 OTLP,仅本地关联)
- **审计日志** — `capability-audit-log` 关键操作审计,支持 IP 定位 (`ip2region`)
- **站内通知** — 公告、个人消息、SSE 实时推送
- **Docker 部署** — 官方镜像与 Compose 编排,一键启动
- **优雅停机** — 生产环境配置 graceful shutdown
---
# 项目介绍
**源**: https://doc.open.daxpay.cn/getting-started/introduction.md
# DaxPay 开源支付系统
`DaxPay` 开源版是一款基于 `GNU LGPL v3.0` 协议分发的开源支付系统,提供支付、退款等支付相关的核心能力,面向支付服务商、多商户平台与跨境业务团队。
## 它解决什么问题
业务系统对接多种支付方式(支付宝、微信、银联等)通常面临:
- 各通道接口规范、签名算法、回调机制各不相同,对接成本高
- 多通道的运维、升级、故障切换难以统一管理
- 通道 SDK 依赖冲突、版本锁定,与主业务耦合严重
- 多渠道资金对账、风控、终端设备管理分散
DaxPay 将各通道封装为**统一的 HTTP 接口**,业务系统只需对接一套标准协议,即可接入多种支付方式;同时把第三方 SDK 隔离到**独立部署的通道子应用**中,显著降低对接、运维与升级的复杂度。
## 核心特性
- **支付核心能力** — 覆盖支付、退款、查询、回调、同步、关闭、商户通知等完整交易闭环
- **多商户模式** — 运营端 + 商户端双入口,数据行级隔离
- **统一 HTTP 接口** — 各通道封装为 RESTful 标准协议,业务系统一次对接、多通道通用
- **通道编排与对接分离** — 主应用负责通道路由、策略编排与配置管理;第三方 SDK 对接下沉到独立子应用,支持**独立部署、独立升级、弹性伸缩**
- **Java + Go 双实现** — 通道子应用同时提供 Java (Spring Boot) 与 Go (Gin) 两套对等实现,按团队技术栈与性能诉求按需选用
- **安全签名** — 接口请求与响应支持 RSA 签名防篡改,字段级 AES-GCM 加密,传输层全程加密
- **全端覆盖** — 运营/商户 Web 管理端、PC 与移动双端 H5 网关、商户管理小程序、收银小程序多端编译
- **国际化与时区** — 中日韩 + 东盟 10 语种国际化,时间字段统一 `timestamptz` + `OffsetDateTime`,UTC 存储
- **沙箱 / 生产隔离** — 部署级环境隔离,生产数据天然纯净,启动期强制对齐
## 项目组成
DaxPay 由多个独立 git 仓库的子项目协同构成:
- **主后端应用** — 支付核心、通道路由编排、商户/服务商/系统管理
- **通道适配子应用** — 对接第三方支付通道的独立部署微服务,同时提供 Java 与 Go 两套对等实现,按需选用
- **管理前端** — 运营/商户 Web 管理端、移动 H5 (PC + Mobile 双端)、商户管理小程序与收银小程序
- **文档站** — 基于 VitePress 的官方文档站
## 适用场景
- **支付服务商 / 收单外包** — 统一收银、多通道兜底、多商户进件与数据隔离
- **多商户平台 / SaaS** — 为每个入驻商户分配独立支付配置与账单
- **跨境与国际化业务** — 多语种管理后台、多时区数据存储、预留国际通道接入
- **独立软件供应商 (ISV)** — 通过统一 HTTP 接口集成支付能力,降低多通道对接成本
## 已交付与后续规划
开源版已交付完整的支付核心链路与多端管理界面:
- **已交付** — 运营端 Web、商户端 Web、移动 H5 (PC + Mobile 双端)、商户管理小程序 (H5 / 微信 / 支付宝 / 抖音 / App)、收银小程序 (微信 / 支付宝 / 抖音)、12 个国内支付通道
- **后续规划** — 国际支付通道 (PayPal / Stripe 等)、分账与结算、更多聚合通道接入
## 开源协议
基于 [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.html) 协议开源,受中华人民共和国相关法律法规的保护和限制。使用前请阅读用户授权使用协议与开源协议,如不同意请勿使用。
---
# 授权码认证
**源**: https://doc.open.daxpay.cn/api/assist/auth.md
# 授权码认证
提供两个接口,均使用 `AuthCodeParam`:
| 接口 | 地址 | 返回 | 用途 |
| --- | --- | --- | --- |
| 获取认证结果 | `POST /unipay/assist/channel/auth/auth` | `Result` | 通过授权码换取 openId/userId,**返回**给调用方 |
| 获取并设置 | `POST /unipay/assist/channel/auth/auth-and-set` | `Result` | 换取后**直接写入会话**(不返回 openId),供后续支付复用 |
这两个接口返回的是平台级 `Result`(字段 `message`),**不是** `DaxResult`(无 `sign`/`resTime`/`reqId`)。详见 [错误码 - 响应结构](https://doc.open.daxpay.cn/api/error-codes.md#错误码体系)。
## AuthCodeParam 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| authCode | string | 是 | — | 三方通道 OAuth 授权码(换 openId/userId),亦可直接写入已拿到的 openId |
| authType | string | 否 | 32 | 认证类型(多类型通道必填:`wechat`/`alipay`/`union_pay`/`douyin`) |
| authToken | string | 否 | 64 | 认证会话码(H5 授权重定向场景下由 [生成授权链接](https://doc.open.daxpay.cn/api/assist/generate-auth-url.md) 下发,凭此恢复上下文) |
| product | string | 否 | 32 | 支付产品编码(小程序直连场景无会话码时必传) |
| capability | string | 否 | 32 | 支付能力编码(小程序场景需要) |
| channelAppId | string | 否 | 128 | 指定认证应用 AppId(会话码恢复时可空) |
| accessToken | string | 否 | — | AccessToken(通道直接返回时填入) |
| unionIdentifier | string | 否 | — | 云闪付 App 标识(从 UA 的 `UnionPay/<版本> <标识>` 截取) |
| queryCode | string | 否 | — | 查询 Code(用于关联生成授权链接时返回的标识) |
## 接口一:获取认证结果
### 请求地址
`POST /unipay/assist/channel/auth/auth`
- 认证:**无** `@PaymentVerify`(注意:此接口不验签,依赖网关层防护)
- 响应:`Result`
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"authCode": "061XYYxxx0xxx",
"authType": "wechat",
"authToken": "AT20241201020"
}
```
### 响应参数 `AuthResult`
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| openId | string | OpenId(微信场景) |
| userId | string | 用户 ID(支付宝存量商户部分返回) |
| accessToken | string | AccessToken(微信会返回,用于获取用户信息) |
| status | string | 状态(`ChannelAuthStatusEnum`:`waiting`/`success`/`not_exist`) |
| returnPath | string | 来源回跳路径(会话恢复时回填) |
### 响应示例
```json
{
"code": 0,
"message": "success",
"data": {
"openId": "oXxX_xxxxxxxxxxxxx",
"status": "success",
"returnPath": "/pay/result"
}
}
```
## 接口二:获取并设置
### 请求地址
`POST /unipay/assist/channel/auth/auth-and-set`
- 认证:无 `@PaymentVerify`
- 响应:`Result`
与「获取认证结果」入参相同,区别在于:换取后直接写入会话上下文,**不返回 openId**。适用于前端轮询场景——调用方只关心授权是否完成(HTTP 200 + `code=0`),openId 由后续支付请求自动复用。
### 响应示例
```json
{
"code": 0,
"message": "success",
"data": null
}
```
---
# 获取授权链接
**源**: https://doc.open.daxpay.cn/api/assist/generate-auth-url.md
# 获取授权链接
## 接口说明
用于微信 JSAPI、支付宝生活号、银联云闪付等场景下,**获取用户 openId / userId 的 OAuth 授权链接**。
业务流程:
1. 商户后端调用本接口,获得 `authUrl`(带会话码)和 `queryCode`。
2. 商户前端引导用户浏览器跳转到 `authUrl`,由通道完成 OAuth 授权。
3. 授权完成后,通道回调平台,平台通过 `queryCode` 关联回商户会话。
4. 商户通过 [授权码认证](https://doc.open.daxpay.cn/api/assist/auth.md) 或凭 `queryCode` 轮询获取 openId。
本接口用于在支付前获取通道用户标识(openId/userId),不涉及商户系统的登录态。
## 请求地址
`POST /unipay/assist/channel/auth/generate-auth-url`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| authType | string | 否 | 32 | 认证类型(`wechat`/`alipay`/`union_pay`/`douyin`,默认 `wechat`) |
| product | string | 否 | 32 | 支付产品编码(决定走哪个产品的认证策略;缺失时由 `channelMchNo` 反查) |
| channelAppId | string | 否 | 128 | 指定认证使用的应用 AppId(优先级高于自动解析,须预先配置) |
| returnPath | string | 否 | 200 | 来源回跳路径(授权完成后前端回跳的目标路径,会随会话码保存) |
| capability | string | 否 | 32 | 支付能力编码(用于解析具体应用:公众号/小程序) |
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201020",
"reqTime": "2024-12-01 12:00:00",
"sign": "Base64签名值",
"authType": "wechat",
"returnPath": "/pay/result"
}
```
## 响应参数
`DaxResult`,`data` 字段结构:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| authUrl | string | 授权访问链接(前端跳转到此地址完成授权) |
| queryCode | string | 查询标识码(用于后续 [授权码认证](https://doc.open.daxpay.cn/api/assist/auth.md) 恢复上下文) |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"authUrl": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=...&state=...",
"queryCode": "QC20241201020"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:00:00Z",
"reqId": "REQ20241201020"
}
```
---
# 易支付对接
**源**: https://doc.open.daxpay.cn/api/epay.md
# 易支付对接
## 概述
易支付(EasyPay)是 DaxPay 内置的通用商户支付接入模块,兼容主流易支付协议,适用于小微商户和个人开发者快速接入。
DaxPay 同时提供两套 API:
| 版本 | 路径前缀 | 签名方式 | 接口能力 |
| --- | --- | --- | --- |
| **V1**(兼容旧版) | `/epay/api/v1/*` | 固定 **MD5** | 仅下单(submit/mapi)+ 查单(api),**不支持退款/关单** |
| **V2**(推荐) | `/epay/api/v2/api/pay/*` | 固定 **RSA**(`SHA256withRSA`) | 下单、查单、退款、退款查询、关单 |
- V2 接口的 `sign_type` 固定为 `RSA`,不接受 `MD5`
- V1 接口的 `sign_type` 固定为 `MD5`,不接受 `RSA`
- 不存在「V2 任选 MD5/RSA」的说法
易支付协议的金额字段是 **`money`(String 类型,单位元)**,**不是** 标准 API 的 `amount`(Long,单位分)。例如 `1.00` 表示 1 元。
## 接口列表(V2)
| 接口名称 | 接口地址 | 方法 | 描述 |
| --- | --- | --- | --- |
| 易支付下单 | `/epay/api/v2/api/pay/create` | GET/POST | 创建易支付订单 |
| 易支付查询 | `/epay/api/v2/api/pay/query` | GET/POST | 查询易支付订单状态 |
| 易支付退款 | `/epay/api/v2/api/pay/refund` | GET/POST | 发起退款 |
| 易支付退款查询 | `/epay/api/v2/api/pay/refund_query` | GET/POST | 查询退款状态 |
| 易支付关闭 | `/epay/api/v2/api/pay/close` | GET/POST | 关闭订单 |
退款查询同时接受 `/api/pay/refund_query`(下划线)和 `/api/pay/refundquery`(无下划线)两个路径,兼容不同易支付实现。
## V2 下单
### 请求地址
`GET/POST /epay/api/v2/api/pay/create`
### 请求参数
字段名遵循易支付协议的 **snake_case** 风格:
| 参数 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| pid | string | 是 | 易支付商户号(对应 `mchNo`) |
| type | string | 是 | 接口类型:`web`(跳转)/ `jump`(直接跳转通道)/ `jsapi` |
| method | string | 否 | 支付方式:`alipay` / `wxpay` 等 |
| out_trade_no | string | 是 | 商户订单号(对应 `bizOrderNo`) |
| name | string | 是 | 商品名称(对应 `title`) |
| money | string | 是 | 金额,**单位元**(如 `"1.00"`) |
| timestamp | string | 是 | 当前时间戳(秒) |
| notify_url | string | 否 | 异步通知地址 |
| return_url | string | 否 | 同步跳转地址 |
| sign | string | 是 | RSA 签名值(Base64) |
| sign_type | string | 是 | 签名类型,固定 `RSA` |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderId": 1853123456789012345,
"orderNo": "P2024120112345700001",
"payBody": "weixin://wxpay/bizpayurl?pr=xxxxx",
"payBodyType": "qr_code"
}
}
```
## V2 查询
### 请求地址
`GET/POST /epay/api/v2/api/pay/query`
### 请求参数
| 参数 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| pid | string | 是 | 易支付商户号 |
| out_trade_no | string | 是 | 商户订单号 |
| sign | string | 是 | RSA 签名值 |
| sign_type | string | 是 | 固定 `RSA` |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderNo": "P2024120112345700001",
"status": "success",
"realAmount": 100,
"payTime": "2024-12-01 12:00:00"
}
}
```
## V2 退款
### 请求地址
`GET/POST /epay/api/v2/api/pay/refund`
### 请求参数
| 参数 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| pid | string | 是 | 易支付商户号 |
| out_trade_no | string | 是 | 原商户订单号 |
| money | string | 是 | 退款金额,**单位元** |
| out_refund_no | string | 否 | 商户退款号(不传由系统生成) |
| sign | string | 是 | RSA 签名值 |
| sign_type | string | 是 | 固定 `RSA` |
## V2 签名规则(RSA)
1. 获取所有非空参数,**排除 `sign` 与 `sign_type`** 两个字段。
2. 按 key 的 ASCII 字典序升序排列。
3. 拼接为 `key1=value1&key2=value2` 格式(无分隔符、无 `&key=` 后缀)。
4. 使用**商户私钥**以 `SHA256withRSA` 签名,Base64 编码后填入 `sign`。
- 标准 API(`/unipay/*`):参数名为 camelCase(`bizOrderNo`),签名字段含 `reqTime`/`nonceStr` 等
- 易支付 V2:参数名为 snake_case(`out_trade_no`),签名字段含 `timestamp`,且**排除** `sign_type`
验签使用平台公钥,规则与 [签名机制](https://doc.open.daxpay.cn/api/signature.md) 一致。
## V1 接口(兼容旧版)
V1 接口兼容传统易支付协议路径,**仅支持 MD5 签名**:
| 接口名称 | 接口地址 | 方法 |
| --- | --- | --- |
| 提交(跳转) | `/epay/api/v1/submit.php` | GET/POST |
| 创建(API) | `/epay/api/v1/mapi.php` | GET/POST |
| 查询 | `/epay/api/v1/api.php` | GET/POST |
### V1 限制
- **仅下单与查单**:V1 不提供退款、退款查询、关单接口。如需退款请使用 V2 或商户端管理 API。
- **签名固定 MD5**:`sign_type=MD5`,使用商户 MD5 密钥拼接末尾后取 MD5(小写十六进制)。
- **查单弱鉴权**:V1 查单使用 `key=md5Key` 直接比对(query 参数),与 V2 的 RSA 验签完全不同,仅适用于低风险场景。
### V1 MD5 签名规则
1. 获取所有非空参数,排除 `sign` 与 `sign_type`。
2. 按 key 的 ASCII 字典序排列,拼接为 `key1=value1&key2=value2`。
3. 在末尾拼接商户密钥:`...&key={md5Key}`(或视具体实现直接拼接)。
4. 对整个字符串取 MD5,输出**小写**十六进制。
## 异步回调
易支付订单的回调走 `protocol=easy_pay`(**GET + URL query 参数**),与标准支付的 `system` 协议(POST JSON)不同。详见 [异步回调 - 两套通知协议](https://doc.open.daxpay.cn/api/notice/callback.md#两套通知协议)。
---
# 错误码
**源**: https://doc.open.daxpay.cn/api/error-codes.md
# 错误码
## 错误码体系
DaxPay 有两层 API,响应结构略有不同:
**支付 API**(`/unipay/*`)— `DaxResult`:
```json
{
"code": 0,
"msg": "success",
"data": { }
}
```
**管理 API**(`/mch/*`)— `Result`:
```json
{
"code": 0,
"message": "success",
"data": { }
}
```
| 字段 | 类型 | 支付 API | 管理 API | 说明 |
| ---- | ---- | -------- | -------- | ---- |
| `code` | `int` | ✓ | ✓ | 业务状态码。`0` 表示成功,非 `0` 表示失败 |
| `msg` | `string` | ✓ | — | 提示信息(`DaxResult` 字段名) |
| `message` | `string` | — | ✓ | 已按 `Accept-Language` 翻译的可读文案(`Result` 字段名) |
| `data` | `object\|null` | ✓ | ✓ | 业务数据,失败时通常为 `null` |
| `sign` | `string` | ✓ | — | RSA 响应签名(仅支付 API) |
| `resTime` | `string` | ✓ | — | 响应时间 UTC(仅支付 API) |
| `reqId` | `string` | ✓ | — | 请求 ID 回显(仅支付 API) |
- 成功: `{"code": 0, "msg": "success", ...}`
- 失败: `{"code": 10506, "msg": "通道路由未找到匹配通道", "data": null}`
错误文案支持 10 语种国际化(zh-CN / en-US / zh-TW / zh-HK / ja-JP / ko-KR / id-ID / vi-VN / th-TH / ms-MY),由请求头 `Accept-Language` 决定返回语言。`code` 是数字分类码,与文案独立 —— 同一文案可能用不同 `code` 抛出,定位问题时以 `code` 为准。
## HTTP 状态码对照
| HTTP 状态码 | 说明 |
| ----------- | ---- |
| 200 | 请求成功,具体业务结果见响应体 `code` |
| 400 | 请求参数格式错误 |
| 401 | 未授权(`Accesstoken` 缺失或无效) |
| 403 | 禁止访问(权限不足) |
| 404 | 接口不存在 |
| 429 | 请求频率超限 |
| 500 | 服务器内部错误 |
## 错误码字典
错误码由后端常量类定义,按业务域分段。以下取自开源版真实源码:
### 基础码 CommonCode
| 状态码 | 常量 | 含义 |
| ------ | ---- | ---- |
| `0` | `SUCCESS_CODE` | 成功 |
| `1` | `FAIL_CODE` | 失败(未细分类的通用失败兜底码) |
### 通用错误码 CommonErrorCode(10000-19999)
| 状态码 | 常量 | 含义 |
| ------ | ---- | ---- |
| `10401` | `AUTHENTICATION_FAIL` | 认证失败(Token 过期 / 无效) |
| `10404` | `SOURCES_NOT_EXIST` | 资源不存在 |
| `10405` | `DATA_NOT_EXIST` | 数据不存在 |
| `10408` | `NONCE_MISSING` | Nonce 缺失 |
| `10409` | `NONCE_INVALID` | Nonce 无效或已过期 |
| `10410` | `TIMESTAMP_EXPIRED` | 请求时间戳超出允许范围 |
| `10415` | `UN_SUPPORTED_OPERATE` | 不支持的操作 |
| `10500` | `SYSTEM_ERROR` | 系统错误 |
| `10505` | `PARSE_PARAMETERS_ERROR` | 参数解析失败 |
| `10506` | `VALIDATE_PARAMETERS_ERROR` | 参数校验失败 |
| `10507` | `REPETITIVE_OPERATION_ERROR` | 重复操作 |
| `10512` | `DANGER_SQL` | 危险 SQL 异常 |
### 支付错误码 PayErrorCode(20000-29999)
| 状态码 | 常量 | 含义 |
| ------ | ---- | ---- |
| `20000` | `UNCLASSIFIED_ERROR` | 未归类的支付错误 |
| `20011` | `CHANNEL_NOT_EXIST` | 支付通道不存在 |
| `20012` | `METHOD_NOT_EXIST` | 支付方式不存在 |
| `20013` | `STATUS_NOT_EXIST` | 支付状态不存在 |
| `20021` | `CHANNEL_NOT_ENABLE` | 支付通道未启用 |
| `20022` | `METHOD_NOT_ENABLE` | 支付方式未启用 |
| `20023` | `CONFIG_NOT_ENABLE` | 配置未启用 |
| `20024` | `CONFIG_ERROR` | 配置错误 |
| `20025` | `CONFIG_NOT_EXIST` | 配置不存在 |
| `20030` | `UNSUPPORTED_ABILITY` | 不支持该支付能力 |
| `20041` | `TRADE_NOT_EXIST` | 交易不存在 |
| `20042` | `TRADE_CLOSED` | 交易已关闭 |
| `20043` | `TRADE_PROCESSING` | 交易处理中,请勿重复操作 |
| `20044` | `TRADE_STATUS_ERROR` | 交易状态错误 |
| `20045` | `TRADE_FAIL` | 交易失败 |
| `20052` | `VERIFY_SIGN_FAILED` | 验签失败 |
| `20060` | `AMOUNT_EXCEED_LIMIT` | 金额超过限额 |
| `20080` | `OPERATION_FAIL` | 操作失败 |
| `20081` | `OPERATION_PROCESSING` | 操作处理中,请勿重复操作 |
| `20082` | `OPERATION_UNSUPPORTED` | 不支持的操作 |
| `20091` | `DATA_ERROR` | 数据错误 |
### 系统未知错误(越界码)
`SYSTEM_UNKNOWN_ERROR` 虽定义在 `PayErrorCode` 类中,但其 code 值 `30000` 已超出该类的 20000-29999 段,作为「未知异常」单独存在。对接时遇到此码表示发生了未预期的系统级异常,需联系平台排查。
| 状态码 | 常量 | 含义 |
| ------ | ---- | ---- |
| `30000` | `SYSTEM_UNKNOWN_ERROR` | 未知异常,系统无法处理 |
### 用户中心错误码 IamErrorCode(21000-21999)
主要出现在管理端 / 商户端的登录、用户、角色、权限场景。
| 状态码 | 常量 | 含义 |
| ------ | ---- | ---- |
| `21014` | `USER_EMAIL_ALREADY_EXISTED` | 用户 Email 已存在 |
| `21015` | `USER_PHONE_ALREADY_EXISTED` | 用户手机号已存在 |
| `21020` | `USER_INFO_NOT_EXISTS` | 用户信息不存在 |
| `21022` | `DUPLICATE_PHONE_NUMBER` | 手机号重复(批量导入) |
| `21023` | `DUPLICATE_EMAIL_ADDRESS` | 邮箱重复(批量导入) |
| `21024` | `NONE_PHONE_AND_EMAIL` | 邮箱和手机号均为空 |
| `21025` | `ROLE_ALREADY_EXISTED` | 角色已存在 |
| `21026` | `ROLE_NOT_EXISTED` | 角色不存在 |
| `21027` | `ROLE_ALREADY_USED` | 角色已被使用 |
| `21028` | `ROLE_HAS_CHILD` / `PERMISSION_DB_ERROR` | 含有下级角色 / 权限操作错误 |
| `21029` | `PERMISSION_NOT_EXIST` | 没有访问权限 |
| `22016` | `USER_PASSWORD_INVALID` | 密码不正确 |
## 业务异常机制
后端业务异常通过 `BizInfoException` 抛出,构造时同时传入**数字 code**(决定响应 `code` 字段)与 **messageKey**(决定 `message` 文案):
```java
// 指定 code + messageKey
throw new BizInfoException(PayErrorCode.TRADE_STATUS_ERROR, "pay.order.status.invalid");
// 仅 messageKey,code 取默认 FAIL_CODE = 1
throw new BizInfoException("pay.route.error.noMatch");
```
- **code** 来自上述常量类,决定错误分类
- **messageKey** 对应 `i18n/{locale}/` 下资源文件中的文案 key,决定 `message` 显示内容
二者独立:同一 `messageKey` 可被不同 `code` 抛出(如 `pay.route.error.noMatch` 多处用 `VALIDATE_PARAMETERS_ERROR=10506` 抛出,也可能用 `FAIL_CODE=1`)。对接排错时以响应体的 `code` 定位错误分类,以 `message` 理解具体原因。
### 常见 messageKey 文案
完整 messageKey 字典见后端 `daxpay-platform-common/common-i18n/src/main/resources/i18n/{locale}/`(按业务模块分文件组织,共数百条)。下表列出对接高频项:
| messageKey | 含义 |
| ---------- | ---- |
| `pay.route.error.noMatch` | 通道路由无匹配 |
| `pay.error.methodNotExist` | 不存在的支付方式 |
| `error.common.payStatusNotExist` | 支付状态不存在 |
| `error.common.tradeStatusNotExist` | 交易状态不存在 |
| `error.common.payRefundStatusNotExist` | 退款状态不存在 |
| `error.common.normalOrderStatusNotExist` | 订单状态不存在 |
## 字段校验错误
支付通道相关的参数校验遵循以下 messageKey 命名规则:
```
validation.field.{字段名}.{约束}
```
例如 `validation.field.bizOrderNo.notBlank` 表示「业务订单号不能为空」。
对应 i18n 文件位置(各语种结构相同,仅 `{locale}` 目录不同):
- 简体中文: `i18n/zh-CN/validation/field.json`
- 英文: `i18n/en-US/validation/field.json`
- 繁体中文 / 日 / 韩 / 东盟四语同结构,位于对应 `{locale}` 目录下
字段校验失败时,响应 `code` 为 `CommonErrorCode.VALIDATE_PARAMETERS_ERROR`(`10506`)。
---
# 接入指南
**源**: https://doc.open.daxpay.cn/api/getting-started.md
# 接入指南
## 接入步骤
### 1. 注册商户
联系 DaxPay 运营方注册商户,获取以下核心凭证:
| 参数 | 描述 |
| --- | --- |
| mchNo | 商户号,唯一标识接入商户 |
| appId | 应用 ID,商户下创建的应用标识 |
### 2. 生成 RSA 密钥对
DaxPay 支付 API 使用 **RSA 非对称加密**进行签名验签。商户需自行生成 RSA 密钥对(推荐 2048 位):
- **商户私钥**:保管在商户服务器,用于对请求签名
- **商户公钥**:注册到 DaxPay 平台,供平台验证请求签名
- **平台公钥**:从 DaxPay 平台获取,用于商户验证响应/回调签名
私钥是敏感信息,禁止提交到代码仓库,建议通过环境变量或安全配置中心管理。
### 3. 环境信息
| 环境 | 基础地址 |
| --- | --- |
| 沙箱环境 | `https://sandbox.daxpay.cn`(测试用,不影响生产数据) |
| 生产环境 | `https://your-domain.com` |
建议先在沙箱环境完成联调,验证通过后再切换到生产环境。
### 4. 首次调用
以下示例展示一个完整的支付请求流程:
#### 1) 构造请求参数
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201001",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"reqTime": "2024-12-01 12:00:00",
"bizOrderNo": "ORDER20241201001",
"title": "测试商品",
"amount": 100,
"method": "wechat_qr",
"notifyUrl": "https://your-domain.com/notify",
"returnUrl": "https://your-domain.com/return"
}
```
#### 2) 生成签名
将请求参数(不含 `sign` 字段)按 key 升序排列,拼接为 `key=value&key=value` 格式,使用商户私钥以 `SHA256withRSA` 签名,Base64 编码后填入 `sign` 字段。
签名细节参见 [签名机制](https://doc.open.daxpay.cn/api/signature.md)。
#### 3) 发送请求
```http
POST /unipay/pay HTTP/1.1
Host: your-domain.com
Content-Type: application/json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201001",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"reqTime": "2024-12-01 12:00:00",
"sign": "Base64签名值",
"bizOrderNo": "ORDER20241201001",
"title": "测试商品",
"amount": 100,
"method": "wechat_qr",
"notifyUrl": "https://your-domain.com/notify"
}
```
#### 4) 处理响应
```json
{
"code": 0,
"msg": "success",
"data": {
"orderId": 1853123456789012345,
"bizOrderNo": "ORDER20241201001",
"orderNo": "P2024120112345700001",
"tradeNo": "T2024120112345700001",
"status": "progress",
"payBody": "weixin://wxpay/bizpayurl?pr=xxxxx",
"payBodyType": "code_url"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:00:00Z",
"reqId": "REQ20241201001"
}
```
- `data.payBody`:支付参数体,根据支付方式不同返回不同内容(二维码链接、调起参数等)
- `data.payBodyType`:支付参数体类型(如 `code_url`、`pay_info`、`redirect_url`)
- `sign`:平台对整个响应的 RSA 签名,可使用平台公钥验签
## 安全配置
接入时必须遵循以下安全规范:
- **HTTPS**:生产环境强制使用 HTTPS,禁止明文传输
- **密钥保管**:商户私钥为敏感信息,禁止提交到代码仓库
- **签名验签**:请求需签名,响应/回调需验签,防止数据篡改
- **回调验签**:接收异步通知时必须先验签再处理业务,防止伪造通知
- **防重放**:每次请求使用不同的 `reqId` 和 `nonceStr`,平台会校验唯一性
## 常见问题
### Q: 签名验证失败?
检查签名参数排序是否正确(ASCII 字典序),签名字符串格式是否为 `key=value&key=value`,使用的密钥是否匹配(请求用商户私钥签名,验签用平台公钥)。
### Q: 请求被拒绝?
确认请求体中包含所有必填字段:`mchNo`、`appId`、`reqId`、`reqTime`、`sign`,以及业务参数。
### Q: 测试环境与生产环境差异?
沙箱环境不产生真实资金流动,用于接口联调和流程验证。生产环境配置与沙箱一致,仅基础地址和凭证不同。
---
# 异步回调
**源**: https://doc.open.daxpay.cn/api/notice/callback.md
# 异步回调
## 概述
当订单状态发生变更时(如支付成功、支付失败、关闭、退款成功),DaxPay 系统会主动向商户在支付请求中传入的 `notifyUrl` 发送异步通知。
## 两套通知协议
平台根据订单的支付来源选择通知协议,**请求方式、报文格式、验签方式均不同**:
| 协议 | `protocol` 值 | 适用场景 | 请求方式 | 报文格式 | 验签方式 |
| --- | --- | --- | --- | --- | --- |
| 系统协议 | `system` | 标准支付 API(`/unipay/*`)发起的订单 | **POST** | JSON body | RSA(`SHA256withRSA`) |
| 易支付协议 | `easy_pay` | 易支付插件(`/epay/*`)发起的订单 | **GET** | URL query 参数 | MD5 / RSA(取决于 V1/V2) |
易支付兼容协议(`protocol=easy_pay`)的回调走 **GET + URL query 参数**,**不是 POST JSON**。对接易支付时需用 `request.getParameter()` 接收,而非 `request.getReader()`。
## 通知流程(system 协议)
1. 商户在发起支付请求时传入 `notifyUrl` 参数。
2. 系统处理完业务后,向 `notifyUrl` 发送 **POST** 请求(JSON 格式)。
3. 商户系统接收通知,**先验签,再处理业务逻辑**。
4. 商户系统处理后,返回 `SUCCESS` 字符串(大小写不敏感,前后空格会被 trim)。
5. 如果商户系统返回非 `SUCCESS` 或 HTTP 状态非 2xx 或超时未响应,系统按策略重试。
## 重试策略
固定 16 次重试,间隔递增(实现于 `NoticeRetryPolicy`,通过 Artemis 延时队列调度):
| 重试次数 | 间隔 | 累计耗时 |
| --- | --- | --- |
| 1 | 15s | 15s |
| 2 | 15s | 30s |
| 3 | 30s | 1min |
| 4 | 3min | 4min |
| 5 | 10min | 14min |
| 6 | 20min | 34min |
| 7~9 | 30min × 3 | ~2h4min |
| 10 | 60min | ~3h4min |
| 11~13 | 3h × 3 | ~12h4min |
| 14~16 | 6h × 3 | ~30h4min |
- **最大重试次数**:16 次(超过后停止,标记为发送失败)
- **仅自动发送路径会重试**:商户在管理端「手动重发通知」失败后**不会**自动重试,需再次手动触发
- **ACK 判定**:HTTP 状态 2xx **且** 响应体 trim 后忽略大小写等于 `SUCCESS`,两者缺一即视为失败并重试
## 回调消息格式
请求方式:`POST`
Content-Type:`application/json`
### 报文结构(DaxNoticeResult)
回调报文继承 `DaxResult`,增加事件与商户字段:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| event | string | 通知事件码(见下方事件类型) |
| protocol | string | 通知协议(`system` / `easy_pay`) |
| mchNo | string | 商户号 |
| appId | string | 应用 ID |
| code | int | 状态码(0 = 成功) |
| msg | string | 提示信息 |
| data | object | 业务数据(订单/退款单快照) |
| sign | string | 平台 RSA 签名(Base64) |
| resTime | string | 通知时间(UTC,ISO 8601) |
| reqId | string | 请求 ID |
### 事件类型(NoticeEventEnum)
| event | 说明 |
| --- | --- |
| pay.success | 支付成功 |
| pay.fail | 支付失败 |
| pay.close | 支付关闭 |
| refund.success | 退款成功 |
| refund.close | 退款关闭 |
### 回调示例:支付成功
```json
{
"event": "pay.success",
"protocol": "system",
"mchNo": "M200000001",
"appId": "APP001",
"code": 0,
"msg": "success",
"data": {
"orderNo": "P2024120112345700001",
"bizOrderNo": "ORDER20241201001",
"tradeNo": "T2024120112345700001",
"amount": 100,
"realAmount": 100,
"status": "success",
"method": "wechat_qr",
"payTime": "2024-12-01 12:00:00",
"attach": "{\"orderId\": 123}"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:00:00Z",
"reqId": "NTF20241201001"
}
```
### 回调示例:退款成功
```json
{
"event": "refund.success",
"protocol": "system",
"mchNo": "M200000001",
"appId": "APP001",
"code": 0,
"msg": "success",
"data": {
"refundNo": "R2024120112345700001",
"bizRefundNo": "REFUND20241201001",
"bizOrderNo": "ORDER20241201001",
"amount": 100,
"status": "success",
"finishTime": "2024-12-01 14:00:00"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T06:00:00Z",
"reqId": "NTF20241201002"
}
```
## 签名验证
商户接收回调后,**必须**验证 `sign` 字段,确保消息由 DaxPay 平台发出且未被篡改。
### 验签步骤
1. 获取回调 JSON 中的所有字段。
2. 移除 `sign` 字段。
3. 排除值为空的字段。
4. 将剩余字段按 key 的 ASCII 码升序排列。
5. 拼接为 `key1=value1&key2=value2` 格式。
6. 使用**平台公钥**以 `SHA256withRSA` 验签。
务必先验签通过后再处理业务逻辑,避免伪造通知导致数据不一致。
验签代码示例参见 [签名机制](https://doc.open.daxpay.cn/api/signature.md#java-验签响应回调)。
## 商户响应
验签通过且业务处理成功后,商户系统应返回:
- HTTP 状态码:2xx(200-299)
- 响应体:`SUCCESS`(大小写不敏感,前后空格会被自动 trim)
```text
SUCCESS
```
返回非 `SUCCESS` 或 HTTP 非 2xx 或超时(15 秒),系统将按上述 [重试策略](#重试策略) 重新发送通知。
---
# 获取用户标识(通用认证)
**源**: https://doc.open.daxpay.cn/api/open/get-openid.md
# 获取用户标识(通用认证)
## 接口说明
对外提供获取用户标识(openId / userId)的**重定向式**接口。对接方构建签名 URL 引导用户浏览器访问,系统完成第三方 OAuth 后,**重定向回对接方回调地址**并携带用户标识和签名。
适用场景:对接方需要通过 DaxPay 获取微信 openId / 支付宝 userId / 抖音 openId,用于自有业务(非支付场景)。
[获取授权链接](https://doc.open.daxpay.cn/api/assist/generate-auth-url.md) 是 POST JSON 接口,返回 authUrl 由前端自行跳转,用于支付前取 openId。
本接口是 GET 重定向接口,系统自动完成 OAuth 全流程并重定向回对接方,用于非支付场景获取用户标识。
## 请求地址
`GET /unipay/open/auth/get-openid`
- 认证:RSA 签名(所有参数参与签名)
- 响应:302 重定向(非 JSON)
## 请求参数
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| mchNo | string | 是 | 32 | 商户号 |
| appId | string | 否 | 32 | 应用号 |
| authType | string | 是 | 32 | 认证类型(`wechat` / `alipay` / `douyin`) |
| redirectUrl | string | 是 | 500 | 回调地址(获取到用户标识后重定向的目标地址,RESTful 风格,不要拼接 query 参数) |
| channelMchNo | string | 否 | 32 | 通道商户号(微信/抖音场景用于定位通道应用) |
| reqId | string | 是 | 64 | 请求 ID(商户侧生成,参与签名) |
| reqTime | string | 是 | - | 请求时间(北京时间,格式 `yyyy-MM-dd HH:mm:ss`,参与签名) |
| nonceStr | string | 否 | 32 | 随机数(参与签名) |
| sign | string | 是 | 1024 | 商户签名(使用商户私钥签名,所有非空参数按 ASCII 字典序排列) |
### 请求示例
```
GET /unipay/open/auth/get-openid?mchNo=M200000001&appId=APP001&authType=wechat&redirectUrl=https%3A%2F%2Fwww.merchant.com%2Fcallback&reqId=REQ20241201020&reqTime=2024-12-01+12%3A00%3A00&nonceStr=abc123&sign=Base64签名值
```
## 响应方式
### 第一步:302 重定向到第三方 OAuth
验签通过后,系统返回 302 重定向到第三方(微信/支付宝/抖音)的 OAuth 授权页面。
### 第二步:OAuth 回调
用户授权后,第三方回调到 `/unipay/open/auth/callback?code=xxx&state=authToken`,系统用 code 换取用户标识。
### 第三步:302 重定向到对接方回调地址
系统将用户标识和签名拼接为 query 参数,302 重定向到对接方的 `redirectUrl`:
```
https://www.merchant.com/callback?return_code=10000&return_msg=成功&openid=oUpF8uMuAJO_M2pxb1Q9zNjWeS6o&sign=Base64签名值
```
## 回调参数
重定向到对接方 `redirectUrl` 时携带的参数:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| return_code | string | 状态码:`10000`=成功,`10001`=失败 |
| return_msg | string | 状态描述 |
| openid | string | 用户标识(微信/抖音场景返回) |
| userid | string | 用户标识(支付宝场景返回) |
| sign | string | 平台签名(对接方使用平台公钥验签) |
### 成功回调示例
```
https://www.merchant.com/callback?return_code=10000&return_msg=成功&openid=oUpF8uMuAJO_M2pxb1Q9zNjWeS6o&sign=953A3CE8C278BB7A8BA277419724C3FD
```
### 失败回调示例
```
https://www.merchant.com/callback?return_code=10001&return_msg=获取openId失败&sign=...
```
## 三通道说明
| authType | 认证方式 | 配置来源 | 返回标识 |
| --- | --- | --- | --- |
| wechat | 公众号 OAuth(snsapi_base 静默授权) | 商户通道绑定的微信应用(WxAppFacade 解析) | openid |
| alipay | auth_base 静默授权 | 平台级支付宝配置(PlatformAlipayAuthConfig) | userid |
| douyin | H5 silent_auth 静默授权 | 商户通道绑定的抖音应用(DouyinDirectApp) | openid |
抖音 silent_auth 仅在抖音 App 内 WebView 中可用。对接方需确保用户在抖音 App 内打开授权链接。
## 验签说明
回调参数的签名规则与支付接口一致:
1. 参数名按 ASCII 字典序排序
2. 空值参数不参与签名
3. 使用平台公钥验签
详见 [签名说明](https://doc.open.daxpay.cn/api/signature.md)。
---
# 接口概览
**源**: https://doc.open.daxpay.cn/api/overview.md
# 接口概览
## 接口风格
- **RESTful** 风格,接口命名 **kebab-case**(如 `pay-order` 而非 `payOrder`)
- 基于 HTTP 协议,请求与响应均为 `JSON` 格式
## 两层 API 架构
DaxPay 对外提供两层 API,认证方式与响应格式不同:
| 层级 | 路径前缀 | 认证方式 | 响应类 | 用途 |
| --- | --- | --- | --- | --- |
| **支付 API** | `/unipay/*` | RSA 签名验签 | `DaxResult` | 服务器对服务器调用(下单、查询、关闭等) |
| **管理 API** | `/mch/*` | Sa-Token 会话 | `Result` | 商户端 Web 面板操作(退款、列表、同步等) |
支付 API 面向商户后端系统,通过 RSA 签名认证,无需登录态;管理 API 面向商户 Web 面板,通过 `Accesstoken` 请求头(Sa-Token)认证。
## 支付 API 的三类接口
`/unipay/*` 下按业务场景细分为三类:
| 类别 | 路径前缀 | 场景 | 文档 |
| --- | --- | --- | --- |
| **直连支付** | `/unipay/pay`、`/unipay/close`、`/unipay/query/*`、`/unipay/sync/*` | 商户后端已确定通道与支付方式 | [统一支付](https://doc.open.daxpay.cn/api/payment/create.md) |
| **网关支付** | `/unipay/gateway/*` | 由平台收银台/聚合页选择支付方式 | [网关预下单](https://doc.open.daxpay.cn/api/payment/pre-pay.md) |
| **通道认证** | `/unipay/assist/channel/auth/*` | 获取用户 openId/userId(OAuth 授权) | [获取授权链接](https://doc.open.daxpay.cn/api/assist/generate-auth-url.md) |
## 基础地址
```
http://{系统域名}:{端口}
```
示例:`https://your-domain.com`(生产环境),本地开发默认端口 `9999`。
## 对接流程
1. **注册商户**:在管理平台注册商户,获取商户号(mchNo)和应用 ID(appId)。
2. **配置密钥**:生成 RSA 密钥对,将**商户公钥**注册到平台;平台分配**平台公钥**用于验签响应。
3. **接口调用**:按本文档定义的规范构造请求(含签名),发起支付、查询、关闭等请求。
4. **接收回调**:配置异步通知地址(`notifyUrl`),接收支付/退款结果通知。
## 通用请求头
| 参数名 | 必填 | 描述 |
| --- | --- | --- |
| Content-Type | 是 | `application/json`,所有请求均为 JSON 格式 |
| Accesstoken | 管理API必填 | Sa-Token 会话令牌(仅 `/mch/*` 管理接口需要;支付 API `/unipay/*` 不需要) |
## 签名机制
支付 API(`/unipay/*`)使用 RSA 签名认证,**签名字段在请求体内**(非请求头):
| 字段 | 位置 | 描述 |
| --- | --- | --- |
| sign | 请求体 | RSA 签名值(Base64 编码) |
| reqTime | 请求体 | 请求时间(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
| reqId | 请求体 | 请求唯一标识,防重放 |
| nonceStr | 请求体 | 随机字符串,防重放 |
签名生成细节参见 [签名机制](https://doc.open.daxpay.cn/api/signature.md)。
## 通用响应体(支付 API)
`DaxResult` 结构:
```json
{
"code": 0,
"msg": "success",
"data": {},
"sign": "Base64签名值",
"resTime": "2024-12-01T12:00:00Z",
"reqId": "REQ20241201001"
}
```
| 字段 | 类型 | 描述 |
| --- | --- | --- |
| code | int | 业务状态码,0 表示成功 |
| msg | string | 提示信息 |
| data | object | 业务数据 |
| sign | string | 平台对响应的 RSA 签名,商户可验签 |
| resTime | string | 响应时间(UTC,ISO 8601) |
| reqId | string | 请求 ID(回显入参 reqId) |
支付 API 响应字段为 `msg`(非 `message`)。管理 API(`Result`)使用 `message`。
## 通用约定
### 请求方式
支付 API 接口使用 `POST` 方式请求,请求体为 JSON 格式。管理 API 查询接口使用 `GET`,操作接口使用 `POST`。
### 日期格式
所有日期时间字段使用 `OffsetDateTime`,序列化为 ISO 8601 带 UTC 偏移:
- 请求/响应中的时间字段:`yyyy-MM-dd HH:mm:ss`(GMT+8)
- 响应中的 UTC 时间(如 `resTime`):ISO 8601 格式
### 金额单位
所有金额字段类型为 `Long`,单位为**分**,避免浮点数精度丢失。
例如:`1元` → `100`
### 状态值
状态字段类型为 `String`(非数字),使用语义化的英文小写编码:
- 支付状态(`PayStatusEnum`):`wait` / `progress` / `success` / `close` / `cancel` / `fail` / `timeout`
- 退款状态(`RefundOrderStatusEnum`):`progress` / `success` / `fail` / `close`
- 退款标记(`PayRefundStatusEnum`):`no_refund` / `refunding` / `partial_refund` / `refunded`
## 术语表
| 术语 | 描述 |
| --- | --- |
| mchNo | 商户号(Merchant Number),唯一标识接入商户 |
| appId | 应用 ID,商户下创建的应用标识 |
| RSA 密钥对 | 商户生成 RSA 密钥对,公钥注册到平台,私钥用于签名请求 |
| method | 支付方式,如 `wechat_qr`、`alipay_pc`(见 [PayMethodEnum](https://doc.open.daxpay.cn/api/payment/create.md#支付方式-method)) |
| product | 支付产品,如 `alipay_pc`、`wechat_native`(见 [通道码表](https://doc.open.daxpay.cn/codes/channels.md)) |
| orderNo | 系统订单号 |
| bizOrderNo | 商户业务订单号 |
| tradeNo | 交易号(一笔订单可多次尝试,每次生成新交易号) |
---
# 关闭撤销订单
**源**: https://doc.open.daxpay.cn/api/payment/close.md
# 关闭撤销订单
## 接口说明
关闭指定订单。只有未支付(`wait` / `progress`)的订单可以被关闭。
部分通道支持**撤销**方式(如微信、银联的当天撤销),通过 `useCancel=true` 触发;不支持的通道会忽略该参数并统一走关单逻辑。
- **关闭(close)**:订单未支付时主动终止,资金未发生,幂等。
- **撤销(cancel)**:针对当日已扣款但未最终确认的交易,触发通道撤销(如银联当日撤销),资金会退回买家。
## 请求地址
`POST /unipay/close`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| orderNo | string | 否* | 100 | 平台业务单号 |
| bizOrderNo | string | 否* | 100 | 商户订单号 |
| useCancel | boolean | 否 | — | 是否使用撤销方式关闭(部分通道支持,默认 `false`) |
> *`orderNo`、`bizOrderNo` 至少传一个,优先级:orderNo > bizOrderNo
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201002",
"reqTime": "2024-12-01 12:05:00",
"sign": "Base64签名值",
"orderNo": "P2024120112345700001",
"useCancel": false
}
```
## 响应参数
`DaxResult`,`data` 为 `null`。
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": null,
"sign": "Base64签名值",
"resTime": "2024-12-01T04:05:00Z",
"reqId": "REQ20241201002"
}
```
## 支持撤销的通道
| 通道 | 关闭 | 撤销 |
| --- | --- | --- |
| 支付宝 | ✓ | ✓ |
| 微信支付 | ✓ | ✗(V3 仅关单) |
| 银联商务 | ✓ | ✓ |
| 拉卡拉 | ✓ | 视签约 |
| 富友 | ✓ | ✗ |
| 杉德 | ✓ | ✗ |
当通道不支持撤销时,`useCancel=true` 会被静默忽略,请求仍以关单方式处理,不会返回错误。生产对接时请按上表确认通道是否支持撤销。
---
# 统一支付
**源**: https://doc.open.daxpay.cn/api/payment/create.md
# 统一支付
## 接口说明
商户系统通过该接口发起支付请求,系统根据支付产品和方式返回对应的支付参数体(`payBody`),商户前端据此调起支付或展示二维码。
适用于商户后端已确定通道与支付方式的「直连支付」场景;若需由平台收银台/聚合页选择支付方式,请使用 [网关预下单](https://doc.open.daxpay.cn/api/payment/pre-pay.md)。
## 请求地址
`POST /unipay/pay`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
### 基础参数(所有 `/unipay/*` 接口通用)
继承自 `PaymentCommonParam` / `MerchantPaymentCommonParam`:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| mchNo | string | 是 | 32 | 商户号 |
| appId | string | 否 | 32 | 应用 ID |
| channelMchNo | string | 否 | 32 | 通道商户号(调试或直接指定通道时传入,正常路由场景留空) |
| reqId | string | 是 | 64 | 请求唯一标识 |
| nonceStr | string | 否 | 32 | 随机字符串 |
| sign | string | 是 | 1024 | RSA 签名(Base64) |
| reqTime | string | 是 | — | 请求时间(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
| clientIp | string | 否 | 64 | 客户端 IP |
### 业务参数
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| bizOrderNo | string | 是 | 100 | 商户订单号,商户系统唯一 |
| title | string | 是 | 100 | 订单标题 |
| description | string | 否 | 50 | 订单描述 |
| amount | long | 是 | — | 订单金额,单位分(最小 1,最大 9999999999) |
| product | string | 否 | 32 | 支付产品编码(为空时由路由引擎自动选择) |
| method | string | 否 | 32 | 支付方式,如 `wechat_qr`、`alipay_pc`(见下方码表) |
| capability | string | 否 | 32 | 支付能力编码(直接指定通道时作为输入参与校验) |
| openId | string | 否 | 128 | 用户标识(微信 jsapi/mini 场景必填) |
| channelAppId | string | 否 | 128 | 通道应用 ID(非空则强制使用,须预先配置) |
| authCode | string | 否 | 128 | 授权码(付款码/被扫支付必填) |
| limitPay | string[] | 否 | 10 | 限制支付的支付方式列表(如 `no_credit` 禁用信用卡) |
| extraParam | string | 否 | 2048 | 通道扩展参数(JSON) |
| goodsDetail | object[] | 否 | 50 | 订单商品明细列表(用于单品营销、电子发票等) |
| notifyUrl | string | 否 | 200 | 异步通知地址 |
| returnUrl | string | 否 | 200 | 同步跳转地址 |
| attach | string | 否 | 500 | 附加数据,回调时原样返回 |
| expiredTime | string | 否 | — | 订单过期时间(`yyyy-MM-dd HH:mm:ss`,GMT+8,空则默认 30 分钟) |
| terminal | object | 否 | — | 终端信息(线下 POS/收银台场景) |
跟随通道路由时一般必填;被扫场景可仅传 `authCode`(平台按前缀识别回填);已直接指定 `channelMchNo` + `capability` 时可空(按能力反推)。
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201001",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"reqTime": "2024-12-01 12:00:00",
"sign": "Base64签名值",
"bizOrderNo": "ORDER20241201001",
"title": "测试商品",
"amount": 100,
"method": "wechat_qr",
"notifyUrl": "https://your-domain.com/notify",
"returnUrl": "https://your-domain.com/return"
}
```
## 响应参数
`DaxResult`,`data` 字段结构:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| orderId | long | 订单 ID |
| bizOrderNo | string | 商户订单号 |
| orderNo | string | 平台业务单号 |
| tradeNo | string | 资金交易号 |
| status | string | 支付状态([PayStatusEnum](#支付状态-paystatusenum)) |
| payBody | string | 支付参数体(二维码内容、调起参数或跳转地址) |
| payBodyType | string | 支付参数体类型([PayBodyTypeEnum](#paybodytype-取值)) |
### payBodyType 取值
对应后端枚举 `PayBodyTypeEnum`:
| 类型 | 说明 | payBody 示例 |
| --- | --- | --- |
| `link` | 支付链接(跳转) | `https://open.weixin.qq.com/...` |
| `jsapi` | JSAPI 调起参数对象 | JSON 字符串,前端直接用于调起 SDK |
| `from` | 表单数据(自动提交表单 HTML) | `` |
| `identifier` | 标识码(如付款码场景的标识) | 通道返回的纯标识字符串 |
| `qr_code` | 二维码内容(前端渲染成二维码图片) | `weixin://wxpay/bizpayurl?pr=xxxxx` |
| `json` | JSON 对象(通道自定义结构) | 通道约定的 JSON 字符串 |
旧版文档曾使用 `code_url` / `pay_info` / `redirect_url`,**这些不是真实枚举值**。请以上表为准。
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderId": 1853123456789012345,
"bizOrderNo": "ORDER20241201001",
"orderNo": "P2024120112345700001",
"tradeNo": "T2024120112345700001",
"status": "progress",
"payBody": "weixin://wxpay/bizpayurl?pr=xxxxx",
"payBodyType": "qr_code"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:00:00Z",
"reqId": "REQ20241201001"
}
```
## 支付方式(method)
`method` 字段对应 `PayMethodEnum`,按渠道分组:
### 微信支付
| method | 说明 |
| --- | --- |
| wechat_qr | 微信扫码支付(Native) |
| wechat_jsapi | 微信 JSAPI 支付(公众号) |
| wechat_mini | 微信小程序支付 |
| wechat_h5 | 微信 H5 支付 |
| wechat_app | 微信 APP 支付 |
| wechat_barcode | 微信付款码支付(被扫) |
| wechat_cashier | 微信收银台支付 |
### 支付宝
| method | 说明 |
| --- | --- |
| alipay_qr | 支付宝扫码支付 |
| alipay_jsapi | 支付宝生活号支付(含小程序) |
| alipay_pc | 支付宝 PC 网站支付 |
| alipay_h5 | 支付宝 H5 支付 |
| alipay_app | 支付宝 APP 支付 |
| alipay_barcode | 支付宝付款码支付(被扫) |
### 银联
| method | 说明 |
| --- | --- |
| union_qr | 银联扫码支付 |
| union_jsapi | 银联 JSAPI 支付 |
| union_h5 | 银联 H5 支付 |
| union_barcode | 银联付款码支付(被扫) |
### 抖音支付
| method | 说明 |
| --- | --- |
| douyin_qr | 抖音扫码支付 |
| douyin_jsapi | 抖音 JSAPI 支付 |
| douyin_h5 | 抖音 H5 支付 |
| douyin_app | 抖音 APP 支付 |
### 聚合支付
| method | 说明 |
| --- | --- |
| aggregate_pay_qrcode | 聚合扫码支付(通道原生一码多付) |
### 境外卡(预留)
| method | 说明 |
| --- | --- |
| visa_card_gateway | Visa 网关支付 |
| visa_card_present | Visa 刷卡支付 |
| mastercard_card_gateway | Mastercard 网关支付 |
| mastercard_card_present | Mastercard 刷卡支付 |
## 支付状态(PayStatusEnum)
| status | 说明 |
| --- | --- |
| wait | 等待中(未指定通道和支付方式) |
| progress | 处理中(已发起通道调用) |
| success | 支付成功 |
| close | 已关闭 |
| cancel | 已撤销 |
| fail | 支付失败 |
| timeout | 已超时 |
---
# 网关预下单
**源**: https://doc.open.daxpay.cn/api/payment/pre-pay.md
# 网关预下单
## 接口说明
用于「网关支付」场景:商户后端不预先指定支付方式,而是先通过本接口创建网关订单并获得 **H5 落地页 URL** 与 **小程序映射 URL**,按用户设备引导用户进入平台收银台或聚合扫码页,由用户在前端选择支付方式后再发起真实支付。
适用于:
- **统一收银台(cashier)**:平台提供的多支付方式选择页面
- **聚合扫码(aggregate)**:一码多付,自动识别用户钱包
## 请求地址
`POST /unipay/gateway/pre-pay`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| bizOrderNo | string | 是 | 100 | 商户订单号 |
| title | string | 是 | 100 | 订单标题 |
| description | string | 否 | 50 | 订单描述 |
| amount | long | 是 | — | 订单金额(分,最小 1,最大 9999999999) |
| gatewayPayType | string | 是 | 32 | 网关类型:`cashier`(统一收银台)/ `aggregate`(聚合扫码) |
| notifyUrl | string | 否 | 256 | 异步通知地址 |
| returnUrl | string | 否 | 256 | 同步跳转地址 |
| attach | string | 否 | 512 | 商户附加参数,回调原样返回 |
| extraParam | string | 否 | 2048 | 通道扩展参数(JSON) |
| expiredTime | string | 否 | — | 过期时间(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
| storeNo | string | 否 | 64 | 门店号 |
| goodsDetail | object[] | 否 | — | 商品明细列表 |
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201010",
"reqTime": "2024-12-01 12:00:00",
"sign": "Base64签名值",
"bizOrderNo": "ORDER20241201001",
"title": "测试商品",
"amount": 100,
"gatewayPayType": "cashier",
"notifyUrl": "https://your-domain.com/notify",
"returnUrl": "https://your-domain.com/return"
}
```
## 响应参数
`DaxResult`,`data` 字段结构:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| orderNo | string | 平台网关单号(后续查询/同步用此号) |
| bizOrderNo | string | 商户业务单号 |
| status | string | 业务状态(`GatewayOrderStatusEnum`,初始为 `wait_pay`) |
| h5Url | string | H5 落地页 URL(cashier 为 `/cashier/{orderNo}`,aggregate 为 `/aggregate/{orderNo}`) |
| miniUrl | string | 小程序映射 URL(cashier 为 `/cm/{orderNo}`,aggregate 为 `/am/{orderNo}`;通过微信等平台普通链接二维码规则拉起小程序) |
| expiredTime | string | 过期时间(UTC) |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderNo": "G2024120112345700001",
"bizOrderNo": "ORDER20241201001",
"status": "wait_pay",
"h5Url": "https://your-domain.com/cashier/G2024120112345700001",
"miniUrl": "https://your-domain.com/cm/G2024120112345700001",
"expiredTime": "2024-12-01T04:30:00Z"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:00:00Z",
"reqId": "REQ20241201010"
}
```
## 后续流程
1. 商户后端拿到 `h5Url` 与 `miniUrl` 后按设备返回给前端:浏览器使用 `h5Url`,小程序普通链接二维码使用 `miniUrl`。
2. `cashier` 使用 `/cm/{orderNo}` 映射到统一收银台小程序;`aggregate` 使用 `/am/{orderNo}` 映射到聚合支付小程序。
3. 用户在网关页完成支付后,平台通过 `notifyUrl` 异步通知商户(事件 `pay.success`)。
4. 商户也可通过 [网关订单查询](https://doc.open.daxpay.cn/api/query/gateway-order.md) 主动查询订单状态。
## 微信普通链接二维码配置
在微信公众平台/小程序后台配置普通链接二维码规则:
- `/cm/*` → `pages-weixin/gateway-cashier/index`(统一收银台小程序)
- `/am/*` → `pages-weixin/aggregate-pay/index`(聚合支付小程序)
小程序从普通链接二维码进入时,微信会把完整 URL 放在 `options.q` 中;页面分别从 `/cm/{orderNo}` 或 `/am/{orderNo}` 提取平台网关单号。
---
# 退款同步
**源**: https://doc.open.daxpay.cn/api/payment/refund-sync.md
# 退款同步
## 接口说明
主动向支付通道同步退款状态。当退款状态为 `progress` 时调用,获取最新退款结果。适用于通道回调延迟或需要主动确认的场景。
## 请求地址
`POST /mch/order/refund/sync?id={退款单ID}`
- 认证:Sa-Token(请求头 `Accesstoken`)
- 响应:`Result`
`id` 是查询参数(`@RequestParam`),**不是** 请求体。请求体为空即可。
## 请求参数
| 参数 | 位置 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- | --- |
| id | query | long | 是 | 退款单 ID(数字) |
### 请求示例
```http
POST /mch/order/refund/sync?id=1853123456789012345 HTTP/1.1
Host: your-domain.com
Accesstoken: xxxx-xxxx-xxxx
Content-Type: application/json
```
## 响应参数
`Result`,`data` 字段结构同 [申请退款 - 响应参数](https://doc.open.daxpay.cn/api/payment/refund.md#响应参数),主要返回:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| id | long | 退款单 ID |
| refundNo | string | 系统退款号 |
| status | string | 同步后的退款状态([RefundOrderStatusEnum](https://doc.open.daxpay.cn/api/payment/refund.md#退款状态-refundorderstatusenum)) |
| finishTime | string | 退款完成时间(UTC) |
| errorMsg | string | 错误信息(失败时) |
### 响应示例
```json
{
"code": 0,
"message": "success",
"data": {
"id": "1853123456789012345",
"refundNo": "R2024120112345700001",
"status": "success",
"finishTime": "2024-12-01T06:00:00Z"
}
}
```
---
# 申请退款
**源**: https://doc.open.daxpay.cn/api/payment/refund.md
# 申请退款
## 接口说明
对已支付成功的订单发起退款。
**注意**:
- 支持部分退款和全额退款
- 退款金额不能超过订单可退款余额(查询订单返回的 `refundableBalance`)
- 同一笔订单的多次退款请求,`bizRefundNo` 必须唯一(不传则由系统生成)
## 接口列表
退款接口属于**管理 API**(`/mch/*`),通过 Sa-Token 会话认证,响应使用 `Result` 包装(字段名为 `message`,非 `msg`)。
支付 API(`/unipay/*`)使用 RSA 签名认证、`DaxResult` 响应;退款接口使用 `Accesstoken` 请求头认证、`Result` 响应。
## 请求地址
`POST /mch/order/refund/refund`
- 认证:Sa-Token(请求头 `Accesstoken`)
- 响应:`Result`
## 请求头
| 参数名 | 必填 | 描述 |
| --- | --- | --- |
| Accesstoken | 是 | Sa-Token 会话令牌 |
| Content-Type | 是 | `application/json` |
## 请求参数
`RefundParam`:
| 参数 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| tradeNo | string | 否* | 原支付资金交易号(平台 tradeNo) |
| bizOrderNo | string | 否* | 商户业务订单号 |
| amount | long | 是 | 退款金额,单位分(`@Positive`,必须大于 0) |
| bizRefundNo | string | 否 | 商户退款号(不传由系统生成) |
| reason | string | 否 | 退款原因 |
> *`tradeNo`、`bizOrderNo` 至少传一个,优先使用 `tradeNo`。`tradeNo` 解析时若按资金号查不到,会再尝试网关容器 `orderNo` 反查。
### 请求示例
```json
{
"bizOrderNo": "ORDER20241201001",
"amount": 100,
"bizRefundNo": "REFUND20241201001",
"reason": "用户申请退款"
}
```
## 响应参数
`Result`,`data` 字段结构(主要字段,完整 27 字段见源码 `RefundOrderResult`):
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| id | long | 退款单 ID |
| mchNo | string | 商户号 |
| mchName | string | 商户名称(翻译) |
| appId | string | 应用号 |
| refundNo | string | 系统退款号 |
| bizRefundNo | string | 商户退款号 |
| relationOrderNo | string | 实际上送通道的关联号 |
| title | string | 标题 |
| tradeNo | string | 原支付资金交易号 |
| tradeType | string | 原支付交易形态 |
| bizOrderNo | string | 原商户订单号 |
| outOrderNo | string | 通道支付订单号 |
| outRefundNo | string | 通道退款流水号 |
| amount | long | 退款金额(分) |
| orderAmount | long | 原订单总金额(分) |
| currency | string | 币种 |
| reason | string | 退款原因 |
| status | string | 退款状态([RefundOrderStatusEnum](#退款状态-refundorderstatusenum)) |
| finishTime | string | 退款完成时间(UTC) |
| channel | string | 支付通道 |
| product | string | 支付产品 |
| channelMchNo | string | 通道商户号 |
| channelAppId | string | 通道应用 AppId |
| notifyUrl | string | 异步通知地址 |
| attach | string | 商户附加参数 |
| clientIp | string | 客户端 IP |
| storeNo | string | 门店号 |
| errorMsg | string | 错误信息(失败时) |
### 退款状态(RefundOrderStatusEnum)
| status | 说明 |
| --- | --- |
| progress | 退款中(已创建并调用通道,等待结果) |
| success | 退款成功 |
| fail | 退款失败 |
| close | 退款关闭(超时未确认等) |
### 响应示例
```json
{
"code": 0,
"message": "success",
"data": {
"id": "1853123456789012345",
"refundNo": "R2024120112345700001",
"bizRefundNo": "REFUND20241201001",
"bizOrderNo": "ORDER20241201001",
"tradeNo": "T2024120112345700001",
"amount": 100,
"orderAmount": 100,
"status": "progress",
"reason": "用户申请退款"
}
}
```
## 退款回调
退款成功后,平台会向**原支付订单的 `notifyUrl`** 发送 `event=refund.success` 的异步通知,报文结构见 [异步回调](https://doc.open.daxpay.cn/api/notice/callback.md)。
---
# 同步支付订单
**源**: https://doc.open.daxpay.cn/api/payment/sync.md
# 同步支付订单
## 接口说明
当订单状态为 `progress`(处理中)时,商户可主动调用本接口向支付通道发起状态同步,获取最新的支付结果。适用于回调延迟或商户需要主动确认状态的场景。
## 请求地址
`POST /unipay/sync/order/pay`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| orderNo | string | 否* | 100 | 平台业务单号 |
| bizOrderNo | string | 否* | 100 | 商户订单号 |
| outOrderNo | string | 否* | 150 | 通道订单号 |
> *三个订单号至少传一个,优先级:orderNo > bizOrderNo > outOrderNo
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201004",
"reqTime": "2024-12-01 12:15:00",
"sign": "Base64签名值",
"orderNo": "P2024120112345700001"
}
```
## 响应参数
`DaxResult`,`data` 字段结构:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| orderStatus | string | 同步后的订单状态([PayStatusEnum](https://doc.open.daxpay.cn/api/payment/create.md#支付状态-paystatusenum)) |
| adjust | boolean | 是否触发了状态调整(同步前后状态是否变化) |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderStatus": "success",
"adjust": true
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:15:00Z",
"reqId": "REQ20241201004"
}
```
## 使用建议
- 同步是**幂等**操作,可重复调用,不会重复扣款或重复通知。
- 同步触发状态变更后,平台会按 [异步回调](https://doc.open.daxpay.cn/api/notice/callback.md) 流程重新发送通知。
- 若通道返回「订单不存在」,平台会按规则将本地订单置为 `fail` 或 `timeout`,需结合 `adjust` 判断。
---
# 网关订单查询
**源**: https://doc.open.daxpay.cn/api/query/gateway-order.md
# 网关订单查询
## 接口说明
查询通过 [网关预下单](https://doc.open.daxpay.cn/api/payment/pre-pay.md) 创建的网关订单详情。
## 请求地址
`POST /unipay/gateway/query`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数继承自 `PaymentCommonParam`(无需 `mchNo` 签名外的字段,但 `mchNo` 必填):
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| mchNo | string | 是 | 32 | 商户号 |
| appId | string | 否 | 32 | 应用号 |
| reqId / nonceStr / sign / reqTime | — | — | — | 见 [签名机制](https://doc.open.daxpay.cn/api/signature.md) |
| orderNo | string | 否* | 64 | 平台网关单号 |
| bizOrderNo | string | 否* | 100 | 商户业务单号 |
> *`orderNo`、`bizOrderNo` 至少传一个,优先级:orderNo > bizOrderNo
### 请求示例
```json
{
"mchNo": "M200000001",
"reqId": "REQ20241201011",
"reqTime": "2024-12-01 12:20:00",
"sign": "Base64签名值",
"orderNo": "G2024120112345700001"
}
```
## 响应参数
`DaxResult`,`data` 字段结构(18 字段):
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| orderNo | string | 平台网关单号 |
| bizOrderNo | string | 商户业务单号 |
| gatewayType | string | 网关类型(`cashier` / `aggregate`) |
| title | string | 标题 |
| description | string | 描述 |
| amount | long | 金额(分) |
| currency | string | 币种 |
| status | string | 业务状态(`GatewayOrderStatusEnum`) |
| expiredTime | string | 过期时间(UTC) |
| payTime | string | 支付成功时间(UTC) |
| channel | string | 支付通道(用户最终选择的通道) |
| method | string | 支付方式 |
| product | string | 支付产品 |
| tradeNo | string | 资金交易号 |
| outOrderNo | string | 通道订单号 |
| fundStatus | string | 资金状态(`PayFundStatusEnum`) |
| attach | string | 商户附加参数(原样返回) |
| returnUrl | string | 同步跳转地址 |
### 网关订单状态(GatewayOrderStatusEnum)
| status | 说明 |
| --- | --- |
| wait_pay | 待支付 |
| paying | 支付中 |
| paid | 已支付 |
| failed | 支付失败 |
| closed | 已关闭 |
| expired | 已过期 |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderNo": "G2024120112345700001",
"bizOrderNo": "ORDER20241201001",
"gatewayType": "cashier",
"title": "测试商品",
"amount": 100,
"currency": "CNY",
"status": "paid",
"payTime": "2024-12-01T04:05:00Z",
"channel": "wechat",
"method": "wechat_jsapi",
"tradeNo": "T2024120112345700001",
"fundStatus": "success",
"attach": "{\"orderId\": 123}",
"returnUrl": "https://your-domain.com/return"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:20:00Z",
"reqId": "REQ20241201011"
}
```
---
# 查询支付订单
**源**: https://doc.open.daxpay.cn/api/query/pay-order.md
# 查询支付订单
## 接口说明
通过订单号查询系统订单详情,包含当前支付状态、金额等信息。
## 请求地址
`POST /unipay/query/pay-order`
- 认证:RSA 签名(`@PaymentVerify`)
- 响应:`DaxResult`
## 请求参数
基础参数同 [统一支付 - 基础参数](https://doc.open.daxpay.cn/api/payment/create.md#基础参数所有-unipay-接口通用),业务参数:
| 参数 | 类型 | 必填 | 最大长度 | 描述 |
| --- | --- | --- | --- | --- |
| orderNo | string | 否* | 100 | 平台业务单号 |
| bizOrderNo | string | 否* | 100 | 商户订单号 |
> *`orderNo`、`bizOrderNo` 至少传一个,优先级:orderNo > bizOrderNo
### 请求示例
```json
{
"mchNo": "M200000001",
"appId": "APP001",
"reqId": "REQ20241201003",
"reqTime": "2024-12-01 12:10:00",
"sign": "Base64签名值",
"orderNo": "P2024120112345700001"
}
```
## 响应参数
`DaxResult`,`data` 字段结构:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| orderNo | string | 平台业务单号 |
| bizOrderNo | string | 商户订单号 |
| tradeNo | string | 资金交易号 |
| outOrderNo | string | 通道支付订单号 |
| title | string | 订单标题 |
| description | string | 订单描述 |
| channel | string | 支付通道(`ChannelEnum`) |
| method | string | 支付方式(`PayMethodEnum`) |
| limitPay | string | 限制支付类型(`PayLimitPayEnum`) |
| amount | long | 订单金额(分) |
| realAmount | long | 实际支付金额(分) |
| refundableBalance | long | 可退款余额(分) |
| status | string | 支付状态([PayStatusEnum](https://doc.open.daxpay.cn/api/payment/create.md#支付状态-paystatusenum)) |
| refundStatus | string | 退款状态([PayRefundStatusEnum](#退款状态-payrefundstatusenum)) |
| provider | string | 支付渠道(`PayProviderEnum`,如 `WECHAT`/`ALIPAY`) |
| payTime | string | 支付时间(UTC) |
| closeTime | string | 关闭时间(UTC) |
| expiredTime | string | 过期时间(UTC) |
| terminalNo | string | 终端设备编码 |
| storeNo | string | 门店号 |
| buyerId | string | 付款用户 ID |
| attach | string | 附加数据(原样返回) |
| errorMsg | string | 错误信息 |
### 退款状态(PayRefundStatusEnum)
支付订单维度的退款标记:
| refundStatus | 说明 |
| --- | --- |
| no_refund | 未退款 |
| refunding | 退款中 |
| partial_refund | 部分退款 |
| refunded | 全部退款 |
### 响应示例
```json
{
"code": 0,
"msg": "success",
"data": {
"orderNo": "P2024120112345700001",
"bizOrderNo": "ORDER20241201001",
"tradeNo": "T2024120112345700001",
"outOrderNo": "WX2024120100001",
"title": "测试商品",
"channel": "wechat",
"method": "wechat_qr",
"amount": 100,
"realAmount": 100,
"refundableBalance": 100,
"status": "success",
"refundStatus": "no_refund",
"provider": "WECHAT",
"payTime": "2024-12-01T04:00:00Z",
"expiredTime": "2024-12-01T04:30:00Z",
"attach": "{\"orderId\": 123}"
},
"sign": "Base64签名值",
"resTime": "2024-12-01T04:10:00Z",
"reqId": "REQ20241201003"
}
```
---
# 退款列表与详情
**源**: https://doc.open.daxpay.cn/api/query/refund-list.md
# 退款列表与详情
提供退款订单的查询能力,均属管理 API(`/mch/*`),Sa-Token 认证。
## 接口列表
| 接口名称 | 接口地址 | 方法 | 描述 |
| --- | --- | --- | --- |
| 退款分页 | `/mch/order/refund/page` | GET | 分页查询退款单 |
| 退款详情 | `/mch/order/refund/get-by-id` | GET | 根据 ID 查询退款单详情 |
## 退款分页
### 请求地址
`GET /mch/order/refund/page`
- 认证:Sa-Token(请求头 `Accesstoken`)
- 响应:`Result>`
### 请求参数
通过查询字符串传递,分页参数 + 查询条件:
**分页参数(`PageParam`):**
| 参数 | 类型 | 默认 | 描述 |
| --- | --- | --- | --- |
| current | int | 1 | 当前页码 |
| size | int | 10 | 每页条数 |
**查询条件(`RefundOrderQuery`,均可选):**
| 参数 | 类型 | 匹配方式 | 描述 |
| --- | --- | --- | --- |
| mchNo | string | EQ | 商户号 |
| appId | string | EQ | 应用号 |
| refundNo | string | LIKE | 系统退款号(模糊匹配) |
| bizRefundNo | string | LIKE | 商户退款号(模糊匹配) |
| tradeNo | string | LIKE | 原支付资金交易号(模糊匹配) |
| tradeType | string | EQ | 交易类型(原支付形态) |
| bizOrderNo | string | LIKE | 商户业务订单号(模糊匹配) |
| status | string | EQ | 退款状态(`RefundOrderStatusEnum`) |
| product | string | EQ | 支付产品 |
| storeNo | string | EQ | 门店号 |
| createTimeStart | string | GE | 创建时间起始(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
| createTimeEnd | string | LE | 创建时间结束(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
### 请求示例
```http
GET /mch/order/refund/page?current=1&size=20&status=progress&createTimeStart=2024-12-01%2000:00:00 HTTP/1.1
Host: your-domain.com
Accesstoken: xxxx-xxxx-xxxx
```
### 响应参数
`Result>`:
| 参数 | 类型 | 描述 |
| --- | --- | --- |
| records | object[] | 退款单列表(每项结构同 [申请退款 - 响应参数](https://doc.open.daxpay.cn/api/payment/refund.md#响应参数)) |
| total | long | 总记录数 |
| size | long | 每页条数 |
| current | long | 当前页码 |
### 响应示例
```json
{
"code": 0,
"message": "success",
"data": {
"records": [
{
"id": "1853123456789012345",
"refundNo": "R2024120112345700001",
"bizRefundNo": "REFUND20241201001",
"bizOrderNo": "ORDER20241201001",
"amount": 100,
"status": "progress",
"createTime": "2024-12-01T04:00:00Z"
}
],
"total": 1,
"size": 20,
"current": 1
}
}
```
## 退款详情
### 请求地址
`GET /mch/order/refund/get-by-id`
- 认证:Sa-Token(请求头 `Accesstoken`)
- 响应:`Result`
### 请求参数
| 参数 | 位置 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- | --- |
| id | query | long | 是 | 退款单 ID |
### 请求示例
```http
GET /mch/order/refund/get-by-id?id=1853123456789012345 HTTP/1.1
Host: your-domain.com
Accesstoken: xxxx-xxxx-xxxx
```
### 响应示例
返回完整的 `RefundOrderResult`(27 字段,结构同 [申请退款 - 响应参数](https://doc.open.daxpay.cn/api/payment/refund.md#响应参数)):
```json
{
"code": 0,
"message": "success",
"data": {
"id": "1853123456789012345",
"refundNo": "R2024120112345700001",
"bizRefundNo": "REFUND20241201001",
"bizOrderNo": "ORDER20241201001",
"tradeNo": "T2024120112345700001",
"amount": 100,
"orderAmount": 100,
"status": "success",
"finishTime": "2024-12-01T06:00:00Z",
"channel": "wechat",
"product": "WECHAT_PAY",
"reason": "用户申请退款",
"createTime": "2024-12-01T04:00:00Z"
}
}
```
---
# 签名机制
**源**: https://doc.open.daxpay.cn/api/signature.md
# 签名机制
为保证数据传输安全,DaxPay 支付 API 采用 **RSA 非对称加密**签名机制。请求、响应和异步回调均需签名验证,防止篡改。
## 密钥体系
DaxPay 使用 RSA 密钥对进行签名验签:
| 密钥 | 保管方 | 用途 |
| --- | --- | --- |
| 商户私钥 | 商户服务器 | 对**请求**签名 |
| 商户公钥 | DaxPay 平台 | 平台**验证请求**签名 |
| 平台私钥 | DaxPay 平台 | 对**响应/回调**签名 |
| 平台公钥 | 商户服务器 | 商户**验证响应/回调**签名 |
推荐使用 2048 位 RSA 密钥对。可使用 OpenSSL 或 Java KeyPairGenerator 生成。
## 签名字段位置
签名相关字段在**请求/响应 JSON 体内**,不在 HTTP 请求头:
| 字段 | 位置 | 说明 |
| --- | --- | --- |
| sign | JSON 体 | 签名值(Base64 编码) |
| reqId | JSON 体 | 请求唯一标识,防重放 |
| nonceStr | JSON 体 | 随机字符串,防重放 |
| reqTime | JSON 体 | 请求时间(`yyyy-MM-dd HH:mm:ss`,GMT+8) |
## 签名生成步骤
### 1. 构造待签名字符串
1. 获取请求 JSON 中的所有字段(含嵌套对象的扁平化展开)。
2. **排除 `sign` 字段本身**。
3. 排除值为空的字段(null 或空字符串)。
4. 将剩余字段按 key 的 **ASCII 字典序** 升序排列。
5. 拼接为 `key1=value1&key2=value2` 格式。
- 嵌套对象使用点号连接:`terminal.terminalNo=value`
- 列表元素使用中括号索引:`limitPay[0]=value`
- 展开后整体参与排序和拼接
### 2. RSA 签名
使用**商户私钥**对待签名字符串进行签名:
- 算法:`SHA256withRSA`
- 编码:UTF-8
- 输出:Base64 编码字符串
### 3. 填入 sign 字段
将 Base64 签名结果填入请求 JSON 的 `sign` 字段。
## 响应验签
商户收到响应后,使用**平台公钥**验证 `sign` 字段:
1. 获取响应 JSON 中的所有字段。
2. 移除 `sign` 字段。
3. 按与请求签名相同的方式:参数升序 → 拼接。
4. 使用平台公钥以 `SHA256withRSA` 验签。
## 代码示例
### Java — 生成签名
```java
import java.security.*;
import java.util.*;
import java.util.Base64;
// 1. 构造请求参数(TreeMap 自动按 key 排序)
Map params = new TreeMap<>();
params.put("appId", "APP001");
params.put("bizOrderNo", "ORDER20241201001");
params.put("method", "wechat_qr");
params.put("mchNo", "M200000001");
params.put("nonceStr", "5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
params.put("notifyUrl", "https://your-domain.com/notify");
params.put("amount", "100");
params.put("reqId", "REQ20241201001");
params.put("reqTime", "2024-12-01 12:00:00");
params.put("title", "测试商品");
// 2. 拼接待签名字符串(排除 sign,按 ASCII 排序)
String signStr = params.entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("&"));
// 3. RSA 签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey); // 商户私钥
signature.update(signStr.getBytes(StandardCharsets.UTF_8));
String sign = Base64.getEncoder().encodeToString(signature.sign());
```
### Java — 验签响应/回调
```java
// 1. 移除 sign 字段,按 key 排序拼接
String verifyStr = sortedParams.entrySet().stream()
.filter(e -> !"sign".equalsIgnoreCase(e.getKey()))
.filter(e -> e.getValue() != null && !e.getValue().isEmpty())
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("&"));
// 2. 使用平台公钥验签
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey); // 平台公钥
signature.update(verifyStr.getBytes(StandardCharsets.UTF_8));
byte[] signBytes = Base64.getDecoder().decode(receivedSign);
boolean valid = signature.verify(signBytes);
if (!valid) {
throw new RuntimeException("签名验证失败");
}
```
## 签名规则要点
| 规则 | 说明 |
| --- | --- |
| 排序方式 | 按参数 key 的 ASCII 码升序 |
| 拼接格式 | `key1=value1&key2=value2`(无空格、无转义) |
| 空值处理 | 值为 null 或空字符串的参数不参与签名 |
| sign 排除 | `sign` 字段本身不参与签名计算(大小写不敏感) |
| 编码 | 签名字符串统一使用 UTF-8 |
| 签名算法 | `SHA256withRSA` |
| 输出格式 | Base64 编码字符串 |
| 签名位置 | JSON 请求体 `sign` 字段(非 HTTP Header) |
---
# 应用配置
**源**: https://doc.open.daxpay.cn/operation-guide/admin/app-config.md
# 应用配置
> 应用管理用于为商户创建支付应用,每个应用拥有独立的密钥和通道配置。
## 功能说明
- 创建应用(AppId / AppSecret)
- 配置应用支持的支付通道
- 密钥管理
- 应用状态管理
> 本章节持续完善中。
---
# 商户管理
**源**: https://doc.open.daxpay.cn/operation-guide/admin/merchant-management.md
# 商户管理
> 商户管理用于维护系统中的商户信息,包括商户的创建、配置和状态管理。
## 功能说明
- 新建商户
- 商户信息编辑
- 商户状态管理(启用/停用)
- 商户费率配置
> 本章节持续完善中。
---
# 管理端使用入门
**源**: https://doc.open.daxpay.cn/operation-guide/admin/overview.md
# 管理端使用入门
> 运营管理端是系统管理员的统一操作平台,支持支付平台配置、商户管理、应用管理等核心功能。
## 功能概览
- 支付平台配置 — 对接各支付通道的参数配置
- 商户管理 — 商户信息维护与状态管理
- 应用管理 — 为商户创建和配置应用密钥
- 用户管理 — 系统管理员和运营人员的账号管理
> 本章节持续完善中,具体操作指引请参考各子页面。
---
# 支付平台配置
**源**: https://doc.open.daxpay.cn/operation-guide/admin/payment-config.md
# 支付平台配置
> 支付平台配置是运营管理端的核心功能,用于配置和管理各支付通道的对接参数。
## 功能说明
- 添加和管理支付通道(支付宝、微信支付、云闪付等)
- 配置通道参数(商户号、密钥、证书等)
- 启用/禁用通道
- 通道费率配置
> 本章节持续完善中。
---
# 用户管理
**源**: https://doc.open.daxpay.cn/operation-guide/admin/user-management.md
# 用户管理
> 用户管理用于维护运营管理端的系统管理员和运营人员账号。
## 功能说明
- 添加管理员账号
- 角色与权限分配
- 账号状态管理(启用/禁用)
- 密码重置
> 本章节持续完善中。
---
# 操作指南
**源**: https://doc.open.daxpay.cn/operation-guide/introduction.md
# 操作指南
本板块正在建设中,后续将补充详细的操作使用指南。
## 计划内容
- 安装部署
- 商户配置
- 通道接入
- 日常运维
如需提前了解,可参考 [项目介绍](https://doc.open.daxpay.cn/getting-started/introduction.md),或加入 [交流群](https://doc.open.daxpay.cn/resources/license.md) 反馈需求。
---
# 支付设备管理
**源**: https://doc.open.daxpay.cn/operation-guide/merchant/devices.md
# 支付设备管理
> 支付设备管理用于管理支付码牌、支付辅助终端等硬件设备。
## 功能说明
- 支付码牌管理(生成、绑定、启用/禁用)
- 支付辅助终端管理
- 设备与商户绑定
> 本章节持续完善中。
---
# 网关支付配置
**源**: https://doc.open.daxpay.cn/operation-guide/merchant/gateway-config.md
# 网关支付配置
> 网关支付配置用于设置商户的网关支付参数,支持 PC 端在线支付场景。
## 功能说明
- 配置网关支付参数
- 支付页面样式设置
- 回调地址配置
> 本章节持续完善中。
---
# 交易订单管理
**源**: https://doc.open.daxpay.cn/operation-guide/merchant/orders.md
# 交易订单管理
> 交易订单管理用于查看、查询和管理所有支付订单记录。
## 功能说明
- 订单列表查询(按时间、状态、金额等筛选)
- 订单详情查看
- 订单导出
> 本章节持续完善中。
---
# 商户端使用入门
**源**: https://doc.open.daxpay.cn/operation-guide/merchant/overview.md
# 商户端使用入门
> 商户端是商家日常运营的核心平台,支持交易查询、退款处理、设备管理等业务操作。
## 功能概览
- 交易订单管理 — 查看和管理支付订单
- 退款管理 — 处理退款申请
- 支付设备管理 — 管理支付码牌和终端设备
- 网关支付配置 — 配置网关支付参数
> 本章节持续完善中,具体操作指引请参考各子页面。
---
# 退款管理
**源**: https://doc.open.daxpay.cn/operation-guide/merchant/refund.md
# 退款管理
> 退款管理用于处理支付退款申请,支持全额退款和部分退款。
## 功能说明
- 发起退款申请
- 退款状态查询
- 退款记录查看
> 本章节持续完善中。
---
# 收银台小程序
**源**: https://doc.open.daxpay.cn/operation-guide/miniapp/cashier.md
# 收银台小程序
> 收银台小程序为收银员提供移动端收款工具,支持扫码支付等收款方式。
## 功能说明
- 扫码收款(微信/支付宝/云闪付)
- 收款记录查询
- 退款操作
> 本章节持续完善中。
---
# 商户端小程序
**源**: https://doc.open.daxpay.cn/operation-guide/miniapp/merchant.md
# 商户端小程序
> 商户端小程序为商户提供移动端日常运营管理能力。
## 功能说明
- 交易订单查询与管理
- 退款处理
- 经营数据查看
- 设备管理
> 本章节持续完善中。
---
# 小程序端使用入门
**源**: https://doc.open.daxpay.cn/operation-guide/miniapp/overview.md
# 小程序端使用入门
> 小程序端为不同角色提供移动端操作能力,包括商户端小程序和收银台小程序。
## 功能概览
- 商户端小程序 — 商户移动端管理(交易查询、退款等)
- 收银台小程序 — 收银员移动端收款
> 本章节持续完善中,具体操作指引请参考各子页面。
---
# 支付宝
**源**: https://doc.open.daxpay.cn/extension/channels/alipay.md
# 支付宝
## 通道概述
支付宝是中国最大的第三方支付平台之一,DaxPay 支持支付宝直连模式和服务商模式对接。
## 支持的支付方式
- **扫码支付**:用户扫描商户收款码完成支付
- **JSAPI 支付**(`alipay_jsapi`):支付宝端内调起收银台,含小程序场景(官方产品码 `JSAPI_PAY`,`alipay.trade.create` + `my.tradePay`)
- **APP 支付**:在商户 APP 内调起支付宝 APP 完成支付
- **H5 支付**:在手机网页中完成支付
- **PC 支付**:在电脑网站中完成支付
## 配置说明
在运营端「通道管理」中添加支付宝通道,配置以下参数:
- 商户号(PID)
- 应用 ID(AppId)
- 商户私钥
- 支付宝公钥
- 应用公钥证书(可选)
## 回调处理
支付宝支持同步回调和异步通知:
- **同步回调**:支付完成后用户跳转的回调地址
- **异步通知**:支付宝服务端通知商户支付结果
## 注意事项
- 确保服务器 IP 在支付宝白名单内
- 证书模式更安全,建议使用
- 服务商模式下需额外配置间连商户信息
---
# 斗拱支付
**源**: https://doc.open.daxpay.cn/extension/channels/dougong.md
# 斗拱支付
## 通道概述
斗拱支付是汇付天下旗下的聚合支付产品,通过汇付 SDK 统一对接微信、支付宝、银联。DaxPay 通过汇付 V2 Trade 接口实现斗拱通道收单。
## 支持的支付方式
- **微信扫码(主扫)**:返回二维码链接
- **支付宝扫码(主扫)**:返回二维码链接
- **银联扫码(主扫)**:返回二维码链接
- **微信公众号支付(JSAPI)**:需 openId,返回调起参数
- **微信小程序支付**:需 openId,返回调起参数
- **支付宝 JSAPI**:需 openId / buyerId,返回 tradeNO
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 汇付商户号(huifuId,每笔交易必填)
- 商户 appId
- 服务商系统 ID(sysId)
- 产品号(productId)
- 商户 RSA 私钥(PEM 格式 PKCS#8)
- 斗拱 RSA 公钥(PEM 格式,用于验签)
## 签名方式
RSA(PEM 格式 PKCS#8,商户私钥签名 / 斗拱公钥验签)
## 回调处理
- 支持异步通知回调
- 需在斗拱支付商户平台配置回调地址
## 注意事项
- 需在汇付商户平台配置回调地址
- 确保服务器 IP 在白名单内
- 沙箱与生产环境使用不同网关地址
---
# 抖音支付
**源**: https://doc.open.daxpay.cn/extension/channels/douyin.md
# 抖音支付
## 通道概述
抖音支付是字节跳动旗下抖音平台的支付服务,DaxPay 支持抖音支付直连模式,覆盖抖音小程序和 APP 场景。
## 支持的支付方式
- **抖音小程序支付**:用户在抖音小程序内发起支付
- **抖音 APP 支付**:在商户 APP 内调起抖音支付
## 配置说明
在运营端「通道管理」中添加抖音支付通道,配置以下参数:
- 商户号
- 应用 ID
- 商户私钥
- 抖音公钥
## 回调处理
- 支持异步通知回调
- 需在抖音开放平台配置回调地址
## 注意事项
- 仅支持抖音生态内的支付场景
- 小程序支付需先在抖音开放平台注册小程序
- 确保回调地址可通过外网访问
---
# 富友支付
**源**: https://doc.open.daxpay.cn/extension/channels/fuyou.md
# 富友支付
## 通道概述
上海富友支付旗下的聚合支付通道,支持微信、支付宝、银联扫码及付款码等收单方式。DaxPay 通过富友聚合接口统一对接。
## 支持的支付方式
- **微信扫码(主扫)**:用户扫描商户收款码
- **微信 JSAPI(公众号)**:微信公众号端内调起支付
- **微信小程序**:微信小程序端内调起支付
- **支付宝扫码(主扫)**:用户扫描商户收款码
- **支付宝 JSAPI**:支付宝端内调起支付
- **银联扫码(主扫)**:云闪付扫码支付
- **付款码(被扫)**:商户扫描用户付款码,同步返回扣款结果
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 机构号(ins_cd)
- 商户号(mchnt_cd,子商户级)
- 终端号(term_id)
- 商户 RSA 私钥(Base64,PKCS#8)
- 富友 RSA 公钥(Base64,X509,用于验签)
- 订单前缀(关联订单号前缀,用于回调反查)
## 签名方式
MD5withRSA(商户 RSA 私钥签名 / 富友 RSA 公钥验签,Base64 编码)
## 回调处理
- 支持异步通知回调
- 需在富友支付商户平台配置回调地址
## 注意事项
- 部分支付方式需单独签约
- 确保服务器 IP 在富友白名单内
- 回调凭订单号前缀反查平台订单
---
# 海科融通
**源**: https://doc.open.daxpay.cn/extension/channels/haikerongtong.md
# 海科融通
## 通道概述
北京海科融通支付旗下的聚合支付通道,支持微信、支付宝、云闪付扫码及付款码等收单方式。DaxPay 通过海科融通预下单与付款码接口对接。
## 支持的支付方式
- **微信 JSAPI / 小程序**:微信公众号或小程序端内调起支付
- **支付宝扫码(主扫)**:用户扫描商户收款码
- **支付宝 JSAPI / 小程序**:支付宝端内调起支付
- **云闪付扫码(主扫)**:云闪付扫码支付
- **条码支付(被扫)**:商户扫描用户付款码,同步返回结果
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 服务商编号(agent_no)
- 商户号(merch_no)
- 接入机构标识(access_id)
- SAAS 终端号(pn)
- 签名密钥(access_key,用于 MD5 签名与回调验签)
## 签名方式
MD5(大写签名,仅依赖接入密钥 access_key,无需证书)
## 回调处理
- 支持异步通知回调
- 需在海科融通商户平台配置回调地址
## 注意事项
- 无需证书,仅需接入密钥即可完成签名
- 部分支付方式需单独签约
- 确保服务器 IP 在海科融通白名单内
---
# 汇付天下
**源**: https://doc.open.daxpay.cn/extension/channels/huifu.md
# 汇付天下
## 通道概述
汇付天下旗下 Adapay 直连聚合支付通道,一个应用 ID 覆盖微信、支付宝、银联全场景。DaxPay 通过 Adapay API 对接,支持 16 种支付方式。
## 支持的支付方式
- **微信**:扫码、JSAPI(公众号)、APP、H5、小程序、付款码
- **支付宝**:扫码、JSAPI(生活号)、APP、H5、PC 网页、付款码
- **银联**:扫码、JSAPI、H5、付款码
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- Adapay 支付应用 ID(app_id)
- API Key(请求头 Authorization)
- 商户 RSA 私钥(PKCS#8 Base64 字符串,用于请求签名)
- Adapay 平台公钥(X509 Base64,用于响应验签)
## 签名方式
SHA1withRSA(商户 RSA 私钥签名 / Adapay 平台公钥验签,PKCS#8 Base64 编码)
## 回调处理
- 支持异步通知回调
- 需在汇付天下商户平台配置回调地址
## 注意事项
- 动态二维码(微信/银联聚合扫码)走 qrPrePay 特殊路径
- 需在 Adapay 商户平台配置回调地址
- 私钥为 Base64 字符串(非 PEM 格式)
---
# 拉卡拉
**源**: https://doc.open.daxpay.cn/extension/channels/lakala.md
# 拉卡拉
## 通道概述
拉卡拉是中国领先的第三方支付机构,提供聚合收单服务。DaxPay 通过拉卡拉 V3 接口对接,覆盖扫码、JSAPI、APP、小程序等主流支付场景。
## 支持的支付方式
- **条码支付(付款码被扫)**:用户出示付款码,商户扫码完成支付
- **预下单(扫码 / JSAPI / APP / 小程序)**:先下单获取支付链接或调起参数,用户扫码或在端内完成支付
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 应用编号(lkl_app_id)
- 商户证书序列号
- 商户 RSA 私钥(PEM 格式)
- 拉卡拉 RSA 公钥(PEM 格式,用于验签)
- 商户号(merchantNo)
- 终端号(termNo)
- 门店编号(store_id)
## 签名方式
RSA(PEM 格式 PKCS#8,商户私钥签名 / 拉卡拉公钥验签)
## 回调处理
- 支持异步通知回调
- 需在拉卡拉商户平台配置回调地址
## 注意事项
- 部分支付方式需单独签约
- 确保服务器 IP 在拉卡拉白名单内
- 沙箱与生产环境使用不同网关地址
---
# 乐刷支付
**源**: https://doc.open.daxpay.cn/extension/channels/leshua.md
# 乐刷支付
## 通道概述
乐刷科技旗下的聚合支付通道,支持微信、支付宝、银联等多渠道收单。DaxPay 通过乐刷统一接口对接,覆盖扫码与付款码场景。
## 支持的支付方式
- **付款码支付(被扫)**:用户出示付款码,商户扫码完成支付
- **预下单(扫码 / JSAPI / H5 / 小程序)**:通过 pay_way + jspay_flag 区分底层渠道与支付形态
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 乐刷商户号(merchant_id)
- 交易密钥(tradeKey,用于请求签名与回调验签)
- 签名类型(MD5 或 SM3)
## 签名方式
MD5 或 SM3(由签名类型 signType 决定,交易密钥 tradeKey 参与签名)
## 回调处理
- 支持异步通知回调
- 需在乐刷支付商户平台配置回调地址
## 注意事项
- 部分支付方式需单独签约
- 确保服务器 IP 在乐刷白名单内
---
# 快钱支付
**源**: https://doc.open.daxpay.cn/extension/channels/quick_pay.md
# 快钱支付
## 通道概述
快钱支付是快钱清算旗下的第三方支付平台。DaxPay 已预留通道枚举,暂未实现对接。
> 🚧 **规划中**:该通道尚未实现,如需对接请联系开发团队。
---
# 杉德支付
**源**: https://doc.open.daxpay.cn/extension/channels/shande.md
# 杉德支付
## 通道概述
杉德支付旗下的聚合支付通道,通过河马付产品对接微信、支付宝、银联。DaxPay 通过杉德 SDK 统一实现扫码、JSAPI、小程序及付款码收单。
## 支持的支付方式
- **聚合扫码**:不指定底层渠道,用户扫码后自动识别微信/支付宝
- **微信扫码(主扫)**:返回二维码
- **支付宝扫码(主扫)**:返回二维码
- **微信公众号支付(JSAPI)**:需 openId,返回调起参数
- **微信小程序支付**:需 openId,返回调起参数
- **支付宝 JSAPI**:需 openId / buyerId
- **条码支付(被扫)**:直接扣款,可能同步完成
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 杉德代理号(app_id,服务商身份)
- 杉德商户编号(sub_app_id,交易类请求必填)
- 门店号(store_id)
- 商户 RSA 私钥(PEM 格式 PKCS#8 Base64)
- 杉德 RSA 公钥(X509 Base64,用于验签)
## 签名方式
RSA(PEM 格式 PKCS#8 Base64,商户私钥签名 / 杉德公钥验签)
## 回调处理
- 支持异步通知回调
- 需在杉德支付商户平台配置回调地址
## 注意事项
- 需在杉德商户平台配置回调地址
- 确保服务器 IP 在白名单内
- 异步通知地址透传给杉德 biz_content.notify_url
---
# 盛付通
**源**: https://doc.open.daxpay.cn/extension/channels/sheng_pay.md
# 盛付通
## 通道概述
盛付通是盛付科技旗下的第三方支付平台。DaxPay 已预留通道枚举,暂未实现对接。
> 🚧 **规划中**:该通道尚未实现,如需对接请联系开发团队。
---
# 随行付
**源**: https://doc.open.daxpay.cn/extension/channels/suixingfu.md
# 随行付
## 通道概述
随行付支付旗下的聚合支付通道,支持微信、支付宝、银联等多渠道收单。DaxPay 通过随行付天阙接口对接,覆盖统一下单、扫码、付款码及小程序收银台场景。
## 支持的支付方式
- **聚合统一下单(JSAPI / 小程序)**:统一下单接口,由 payType + payWay 决定底层渠道
- **扫码支付(主扫)**:返回统一二维码链接
- **付款码支付(被扫)**:由 authCode 自动识别渠道,同步返回扣款结果
- **小程序收银台**:返回小程序调起参数
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 天阙合作机构 ID(orgId)
- 商户号(mno,子商户级)
- 商户 RSA 私钥(Base64,PKCS#8)
- 天阙 RSA 公钥(Base64,X509,用于验签)
## 签名方式
RSA(商户私钥签名 / 天阙公钥验签,Base64 编码)
## 回调处理
- 支持异步通知回调
- 需在随行付商户平台配置回调地址
## 注意事项
- 部分支付方式需单独签约
- 确保服务器 IP 在随行付白名单内
---
# 银联商务
**源**: https://doc.open.daxpay.cn/extension/channels/unionpay.md
# 银联商务
## 通道概述
银联商务是中国银联旗下综合支付服务机构,DaxPay 支持银联商务全渠道收银对接,覆盖银行卡、扫码等支付方式。
## 支持的支付方式
- **银行卡支付**:借记卡/信用卡支付
- **扫码支付**:银联二维码、微信/支付宝扫码
- **网关支付**:网银在线支付
- **快捷支付**:绑卡支付
## 配置说明
在运营端「通道管理」中添加银联商务通道,配置以下参数:
- 商户号
- 终端号
- 商户密钥
- 证书路径
## 回调处理
- 支持同步回调和异步通知
- 需在银联商户平台配置回调地址
## 注意事项
- 银行卡支付需完成商户资质审核
- 证书需妥善保管并定期更新
- 部分功能需单独申请开通
---
# 微信支付
**源**: https://doc.open.daxpay.cn/extension/channels/wechat.md
# 微信支付
## 通道概述
微信支付是腾讯旗下微信平台的支付服务,DaxPay 支持微信支付直连模式和服务商模式对接。
## 支持的支付方式
- **JSAPI 支付**:微信内网页调用支付
- **扫码支付**:用户扫描二维码完成支付
- **APP 支付**:在商户 APP 内调起微信完成支付
- **H5 支付**:在手机浏览器中完成支付
- **小程序支付**:在微信小程序内完成支付
## 配置说明
在运营端「通道管理」中添加微信支付通道,配置以下参数:
- 商户号(MchId)
- 应用 ID(AppId)
- API v3 密钥
- 商户 API 证书(证书序列号 + 私钥)
- 支付回调地址
## 回调处理
微信支付使用 API v3 回调通知机制:
- 需在微信商户平台配置回调地址
- 支持回调签名验证(微信公钥验签)
- 回调消息需在 5 秒内返回应答
## 注意事项
- 推荐使用 API v3 接口
- 服务商模式下商户号与服务商号不同
- 确保服务器 IP 在白名单内
- 证书需定期更新
---
# 易宝支付
**源**: https://doc.open.daxpay.cn/extension/channels/yibao.md
# 易宝支付
## 通道概述
易宝支付旗下的聚合支付通道(YOP 平台),支持微信、支付宝、银联扫码及 H5 场景。DaxPay 通过易宝 YOP SDK 对接,覆盖聚合码与指定渠道下单。
## 支持的支付方式
- **聚合扫码**:不指定渠道,返回通用二维码,用户扫码后自动识别
- **微信扫码(主扫)**:指定渠道为微信
- **支付宝扫码(主扫)**:指定渠道为支付宝
- **银联扫码(主扫)**:指定渠道为银联
- **微信 H5**:手机浏览器内调起微信支付
- **支付宝 H5 / WAP**:手机浏览器内调起支付宝
## 配置参数
在运营端「通道管理」中添加该通道,配置以下参数:
- 易宝商户号(merchantNo)
- 易宝服务商商编(parentMerchantNo / yopIsvNo)
- 通道应用 AppKey(YOP 应用标识)
- 商户 RSA 私钥(PEM 格式 PKCS#8)
- 易宝平台 RSA 公钥(PEM 格式,用于验签)
- 微信 AppId / AppSecret(微信 H5 / JSAPI 场景用,可空)
## 签名方式
RSA(PEM 格式 PKCS#8,YOP SDK 自动处理签名与验签)
## 回调处理
- 支持异步通知回调
- 需在易宝支付商户平台配置回调地址
## 注意事项
- 通道子应用 channel-two 已实现,启动模块暂未启用
- 需在易宝商户平台配置回调地址
- YOP SDK 自动处理签名,无需手动签名
---
# 银盛支付
**源**: https://doc.open.daxpay.cn/extension/channels/ysep_pay.md
# 银盛支付
## 通道概述
银盛支付是银盛支付服务旗下的第三方支付平台。DaxPay 已预留通道枚举,暂未实现对接。
> 🚧 **规划中**:该通道尚未实现,如需对接请联系开发团队。
---
# 全渠道支付
**源**: https://doc.open.daxpay.cn/extension/pricing/allchannel.md
# 全渠道支付
## 概述
旗舰版在增强版基础上扩展全部支付通道,开源版自带 4 个核心通道,新增 13 个商业通道(共 17 个,对齐 [ChannelEnum](https://doc.open.daxpay.cn/codes/channels.md#支付通道-channelenum) 码表)。
## 自带通道(开源版即可用)
| 通道 | 支持模式 | 支付方式 |
|------|----------|----------|
| 支付宝 | 直连/服务商 | 扫码/JSAPI/APP/H5/小程序 |
| 微信支付 | 直连/服务商 | JSAPI/扫码/APP/H5 |
| 抖音支付 | 直连 | 抖音小程序/APP |
| 银联商务 | 直连 | 全渠道收银 |
## 商业通道(旗舰版专属)
以下通道仅在购买旗舰版后可用:
| 通道 | 说明 |
|------|------|
| 云闪付 | 银联云闪付 |
| 拉卡拉 | 拉卡拉聚合支付 |
| 乐刷支付 | 乐刷支付聚合支付 |
| 随行付 | 随行付聚合支付 |
| 汇付天下 | 汇付天下聚合支付(含 Adapay / 斗拱两个产品) |
| 海科融通 | 海科融通支付 |
| 易宝支付 | 易宝聚合支付 |
| 杉德支付 | 杉德聚合支付(含河马付产品) |
| 富友支付 | 富友聚合支付 |
| 盛付通 | 盛付通聚合支付 |
| 银盛支付 | 银盛聚合支付 |
| 快钱支付 | 快钱聚合支付 |
各通道的使用指南请参考 [通道文档](https://doc.open.daxpay.cn/extension/channels/alipay.md)。
> 商业通道为旗舰版专属功能,需购买旗舰版方可使用。
---
# 移动端
**源**: https://doc.open.daxpay.cn/extension/pricing/mobile.md
# 移动端
## 概述
增强版及以上版本提供完整的移动端能力,基于 UniApp 跨端框架,一套代码同时覆盖微信、支付宝、抖音小程序,以及 H5 与 APP,满足运营、商户、收银等不同角色的移动办公与收款需求。
## 管理端移动应用
供运营/管理人员使用,支持微信、支付宝小程序及 H5。
- 查看交易订单与流水
- 管理商户与通道配置
- 基础数据统计查看
- 基于 UniApp 跨端框架,一套代码多端运行
## 商户端移动应用
供商户自助使用,支持微信、支付宝小程序及 H5。
- 自助查询交易记录
- 管理门店与收款码牌
- 查看营收统计数据
- 基于 UniApp 跨端框架
## 收银端移动应用
供收银员使用,支持微信、支付宝、抖音三端小程序及 H5。
- 扫码收款、订单查询
- 退款操作
- 语音播报
- 基于 UniApp 跨端框架
## 部署说明
移动端基于 UniApp 开发,通过 pnpm 命令即可编译到微信/支付宝/抖音小程序、H5 以及 APP(Android/iOS)。
> 移动端为商业版功能,需购买增强版及以上版本。
---
# 版本清单
**源**: https://doc.open.daxpay.cn/extension/pricing/overview.md
# 版本清单
DaxPay 提供多个版本供选择,满足不同业务场景需求。
| 模块 | 功能点 | 开源版 | 基础版 | 增强版 | 旗舰版 | 备注 |
|-------|-------------------|--------------|-------------|-------------|-------------|--------------------|
| 基础说明 | 价格(不含票) | ¥0 | ¥999 | ¥- | ¥- | 只可开具增值税普通发票 |
| | 简要描述 | 免费开源,LGPL v3协议 | 源码授权 + 商业授权 | 基础版+多端小程序 | 增强版+全部支付通道 | 开源版 LGPL v3 |
| 核心架构 | JDK 25 | ✅ | ✅ | ✅ | ✅ | 基于 Java 25 构建 |
| | Spring Boot 4.1.x | ✅ | ✅ | ✅ | ✅ | Jakarta EE 10 原生支持 |
| | 消息队列 Artemis | ✅ | ✅ | ✅ | ✅ | ActiveMQ Artemis |
| | 数据库 PostgreSQL | ✅ | ✅ | ✅ | ✅ | 相比 MySQL 更高性能 |
| | 国际化支持 | ✅ | ✅ | ✅ | ✅ | 中日韩 + 东盟多语 + 多时区 |
| | 安全控制增强 | ✅ | ✅ | ✅ | ✅ | Sa-Token + RBAC |
| | 数据加密/脱敏 | ✅ | ✅ | ✅ | ✅ | AES-GCM 字段级加密 |
| | 全链路追踪 | ✅ | ✅ | ✅ | ✅ | OpenTelemetry |
| | S3 对象存储 | ✅ | ✅ | ✅ | ✅ | MinIO/OSS/COS |
| 业务端能力 | 运营端(WEB) | ✅ | ✅ | ✅ | ✅ | Vben Admin 5 |
| | 商户端(WEB) | ✅ | ✅ | ✅ | ✅ | 多门店/多应用管理 |
| | 支付网关(WEB/H5) | ✅ | ✅ | ✅ | ✅ | PC/移动双端适配 |
| | 管理端小程序 | ❌ | ❌ | ✅ | ✅ | UniApp 跨端 |
| | 商户端小程序 | ❌ | ❌ | ✅ | ✅ | UniApp 跨端 |
| | 收银小程序 | ❌ | ❌ | ✅ | ✅ | 微信/支付宝/抖音 |
| 支付能力 | 普通支付 | ✅ | ✅ | ✅ | ✅ | 单笔下单 |
| | 聚合支付 | ✅ | ✅ | ✅ | ✅ | 一码多付 |
| | 收银台支付 | ✅ | ✅ | ✅ | ✅ | 统一收银台 |
| | 支付退款 | ✅ | ✅ | ✅ | ✅ | 全额/部分退款 |
| 支付通道 | 支付宝 | ✅ | ✅ | ✅ | ✅ | 直连/服务商模式 |
| | 微信支付 | ✅ | ✅ | ✅ | ✅ | JSAPI/扫码/APP/H5 |
| | 抖音支付 | ✅ | ✅ | ✅ | ✅ | 抖音小程序/APP |
| | 银联商务 | ✅ | ✅ | ✅ | ✅ | 全渠道收银 |
| | 拉卡拉 | ❌ | ❌ | ❌ | ✅ | 聚合支付通道 |
| | 乐刷 | ❌ | ❌ | ❌ | ✅ | 乐刷聚合支付 |
| | 随行付 | ❌ | ❌ | ❌ | ✅ | 随行付聚合支付 |
| | 斗拱 | ❌ | ❌ | ❌ | ✅ | 斗拱聚合支付 |
| | 海科融通 | ❌ | ❌ | ❌ | ✅ | 海科融通支付 |
| | 易宝 | ❌ | ❌ | ❌ | ✅ | 易宝聚合支付 |
| | 汇付天下 | ❌ | ❌ | ❌ | ✅ | 汇付天下聚合支付 |
| | 杉德 | ❌ | ❌ | ❌ | ✅ | 杉德聚合支付 |
| | 富友 | ❌ | ❌ | ❌ | ✅ | 富友聚合支付 |
| | 盛付通 | ❌ | ❌ | ❌ | ✅ | 盛付通聚合支付 |
| | 银盛 | ❌ | ❌ | ❌ | ✅ | 银盛聚合支付 |
| | 快钱 | ❌ | ❌ | ❌ | ✅ | 快钱聚合支付 |
| 配套资源 | 发版群/工单支持 | ❌ | ✅ | ✅ | ✅ | 专属技术交流群 |
| | 代码私服 | ❌ | ✅ | ✅ | ✅ | 阿里云效 |
| | 部署方式 | 自行构建/Docker | 自行构建/Docker | 自行构建/Docker | 自行构建/Docker | Docker Compose |
| | 授权方式 | 开源授权 LGPL v3 | 源码授权 | 源码授权 | 源码授权 | |
| | 机器数限制 | 无限制 | 无限制 | 无限制 | 无限制 | |
| | 更新维护 | ✅ | ✅ | ✅ | ✅ | |
| | 二次分发 | ❌ | ❌ | ❌ | ❌ | 禁止二次转售 |
| | 文档教程 | ✅ | ✅ | ✅ | ✅ | |
---
# 更新日志
**源**: https://doc.open.daxpay.cn/resources/changelog.md
# 更新日志
本页记录 DaxPay 开源版各版本的发布内容。每个版本按变更类型分组标注。
## 版本说明
| 标签 | 含义 |
|------|------|
| 🚀 新增 | 新功能、新通道、新应用 |
| ⚡ 优化 | 性能改进、体验提升、重构 |
| 🐛 修复 | Bug 修复 |
| ⚠️ 破坏性变更 | 不兼容升级,升级时需额外处理 |
| 📚 文档 | 文档更新 |
遵循 [语义化版本](https://semver.org/lang/zh-CN/):`主版本.次版本.修订号`,预发布版本附加 `-beta`、`-rc` 等标识。
## 当前版本
- **DaxPay 开源版**:`4.0.0-beta1`
- **通道子应用**:`4.0.0-beta1`
---
## 4.0.0-beta1
> 首个公开版本,奠定支付核心架构与多端管理界面。
### 🚀 新增
**支付核心**
- 支付交易完整生命周期:支付、退款、查询、回调、同步、关闭、商户通知
- 统一下单,支持全额 / 部分退款,退款同步与差错处理
- 主动同步通道订单状态,补偿回调丢失
- 商户回调消息分发、重试策略、通知任务调度
**通道架构**
- 主应用编排 + 子应用对接的分层架构,第三方 SDK 隔离到独立子应用
- 已对接 **12 个**国内支付通道:
- 直连通道(`channel-one`):支付宝、微信、抖音、银联商务
- 聚合通道(`channel-two`):拉卡拉、海科融通、斗拱、乐刷、随行付、河马付、Adapay、富友
- 通道子应用 **Java (Spring Boot) + Go (Gin) 双实现**,端口、路由、响应契约对等
- 主应用与子应用链路 AES-GCM 加密,声明式 HTTP 客户端调用
- 通道配置统一收敛:废弃微信/抖音旧通道专属应用表,所有通道走统一的支付产品与进件商户体系
**多商户与多端管理**
- 运营端 Web(`daxpay-admin`)— 平台运营方管理后台
- 商户端 Web(`daxpay-merchant`)— 商户自助管理后台
- 移动 H5(`dax-pay-h5`)— PC 与移动双端,设备探测分发
- 商户管理小程序(`dax-pay-app-admin`)— H5 / 微信 / 支付宝 / 抖音 / App 多端编译
- 收银小程序(`dax-pay-cashier`)— 微信 / 支付宝 / 抖音
- 多商户 / 服务商模式,数据行级隔离(商户编号自动隔离)
**安全机制**
- 接口请求 / 响应 RSA 签名防篡改
- 敏感字段 AES-256-GCM 加密存储
- Sa-Token 权限认证(token name: `Accesstoken`),RBAC 角色权限码 + 菜单数据隔离
- TOTP 两步验证 + 备份码(支持 Google Authenticator)
- 社交登录:微信 / 支付宝 / 抖音开放平台扫码登录
- 沙箱 / 生产部署级隔离,启动期强制对齐
**国际化与时区**
- 10 语种支持:简体中文、英文、繁体中文(台 / 港)、日文、韩文,东盟四语(印尼 / 越南 / 泰 / 马来)
- 时间字段统一 `timestamptz(6)` + `OffsetDateTime`,UTC 存储
**支付产品与通道路由**
- 通道配置重构为「支付产品」抽象层:`PayProduct`(产品)+ `PayCapability`(能力)+ 产品策略(`AbsProductStrategy`),新增通道只加策略不改路由框架
- 通道商户(`ChannelMerchant`)统一进件,唯一绑定支付产品,作为收款路径与路由定位的锚点
- 通道路由解耦:路由配置存通道商户号(`channelMchNo`)再反推产品,替代旧版直接绑定产品编码
- 三种解析方式:基础模式(按支付渠道)/场景模式(按支付方式)/直接指定通道商户
- 网关场景(聚合扫码/码牌/收银台)统一 `AUTO`→`METHOD`→`DIRECT` 三级解析
- 沙箱/生产标准化:产品级环境切换 + 商户环境固化快照 + 全局开关 + 路由层环境一致性兜底校验
- 风控插件:黑名单(IP / 商户号 / openId)+ 命中记录,交易前风险检查
**可观测性与运维**
- OpenTelemetry 链路追踪,日志关联 traceId
- 审计日志:关键操作审计,支持 IP 定位(`ip2region`)
- 站内通知:公告、个人消息、SSE 实时推送
- Docker 部署:官方镜像与 Compose 编排
- 生产环境优雅停机
---
# 组件示例
**源**: https://doc.open.daxpay.cn/resources/examples.md
本页演示文档站支持的两类增强组件:**Tabs 标签页**与 **Mermaid 图表**。两者均支持深浅色自适应,Mermaid 会在切换主题时自动重绘。
## Tabs 标签页
### 基础用法
用 `:::tabs` 容器包裹,`==` 分隔各标签页。适合多选项并列的内容。
== 微信支付
支持 JSAPI、Native、扫码、APP、小程序支付,覆盖微信生态全场景。
== 支付宝
支持电脑网站、手机网站、APP、当面付、刷脸支付等主流能力。
== 银联
支持全渠道支付、网关支付、二维码支付,适用于银行卡收单场景。
### 代码示例切换
添加 `variant:code` 可让标签页呈现为代码组样式,适合多语言 / 多版本代码对比。
== cURL
```bash
curl -X POST https://api.daxpay.cn/unipay \
-H "Content-Type: application/json" \
-H "Accesstoken: ${token}" \
-d '{"bizOrderNo":"O202601001","amount":100,"channel":"alipay"}'
```
== Java
```java
DaxPayClient client = new DaxPayClient(config);
UnipayParam param = new UnipayParam();
param.setBizOrderNo("O202601001");
param.setAmount(100);
param.setChannel("alipay");
DaxPayResult result = client.execute(param);
```
== PHP
```php
$client = new DaxPayClient($config);
$result = $client->unipay([
'bizOrderNo' => 'O202601001',
'amount' => 100,
'channel' => 'alipay',
]);
```
### 联动选择
用 `key:名称` 标记的多个标签组会**共享选中状态**,在一处切换即处处同步。
== 微信支付
微信支付通道说明与对接要点。
== 支付宝
支付宝通道说明与对接要点。
下面这组与上方共享同一个 `key`,切换上方时此处会同步:
== 微信支付
- 费率:0.6%
- 结算周期:T+1
== 支付宝
- 费率:0.6%
- 结算周期:T+1
### 嵌套标签页
外层用四个冒号,内层用三个冒号,可实现层级切换。
=== 沙箱环境
== 微信支付
沙箱环境微信支付配置说明。
== 支付宝
沙箱环境支付宝配置说明。
=== 生产环境
== 微信支付
生产环境微信支付配置说明。
== 支付宝
生产环境支付宝配置说明。
## Mermaid 图表
在 Markdown 中使用 mermaid 代码块即可渲染图表,支持流程图、时序图、架构图、状态图等。
### 支付流程
```mermaid
flowchart TD
A[商户系统发起下单] --> B[主应用接收请求]
B --> C{签名校验}
C -->|失败| D[拒绝请求]
C -->|通过| E[通道路由]
E --> F[通道子应用处理]
F --> G[返回支付凭证]
G --> H[用户完成支付]
H --> I[异步回调通知]
I --> J[更新订单状态]
J --> K[通知商户系统]
```
### 支付与回调时序
```mermaid
sequenceDiagram
participant M as 商户系统
participant P as 主应用
participant C as 通道子应用
participant U as 用户
M->>P: 统一下单(签名)
P->>P: 验签 + 通道路由
P->>C: HTTP 调用通道
C-->>P: 返回支付凭证
P-->>M: 返回凭证
M->>U: 展示二维码 / 调起支付
U->>C: 完成支付
C->>P: 异步回调
P->>M: 通知支付结果
```
### 系统架构
```mermaid
graph LR
subgraph 前端
UI[dax-pay-ui
Web 管理端]
H5[dax-pay-h5
移动 H5]
end
subgraph 主应用
P[dax-pay-open
端口 12121]
end
subgraph 子服务
C1[dax-pay-channel-one
通道适配 20100]
end
DB[(PostgreSQL)]
R[(Redis)]
UI --> P
H5 --> P
P --> C1
P --> DB
P --> R
```
### 订单状态机
```mermaid
stateDiagram-v2
[*] --> 待支付: 创建订单
待支付 --> 支付中: 发起支付
支付中 --> 成功: 收到成功回调
支付中 --> 待支付: 支付超时 / 失败
待支付 --> 已关闭: 关闭订单
成功 --> 已退款: 申请退款
成功 --> [*]
已关闭 --> [*]
已退款 --> [*]
```
## 思维导图
文档站支持两种思维导图:**Mermaid mindmap**(静态 SVG)与 **Markmap**(可折叠 / 缩放的交互式)。
### Mermaid mindmap(静态)
```mermaid
mindmap
root((DaxPay))
支付
微信支付
支付宝
银联
退款
全额退款
部分退款
架构
主应用
通道子应用
Web 管理端
移动 H5
```
### Markmap(交互式)
支持点击节点折叠 / 展开、滚轮缩放、拖拽平移。
```markmap
# DaxPay
## 支付
### 微信支付
### 支付宝
### 银联
## 退款
### 全额退款
### 部分退款
## 架构
### 主应用
### 通道子应用
### Web 管理端
### 移动 H5
```
---
# 开源协议
**源**: https://doc.open.daxpay.cn/resources/license.md
# 开源协议
DaxPay 开源版基于 [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.html)(LGPL v3.0)协议开源,受中华人民共和国相关法律法规的保护和限制。使用前请阅读开源协议,如不同意请勿使用。
版权所有 © 济南易杯光年软件有限公司。
## LGPL v3.0 核心要点
LGPL(Lesser GPL)是 [GPL](https://www.gnu.org/licenses/gpl-3.0.html) 的一个变体,专为**类库**设计,比 GPL 更宽松。核心区别在于对「链接」的处理:
| 使用方式 | 是否需开源你的代码 | 说明 |
|---------|------------------|------|
| **通过接口 / 网络调用** | 否 | 业务系统通过 DaxPay 的 HTTP 接口调用,**完全不受 LGPL 约束** |
| **动态链接** | 否 | 动态链接 LGPL 库,业务代码可闭源 |
| **静态链接** | 是 | 静态链接 LGPL 库需开源业务代码,或提供可重新链接的目标文件 |
| **修改 LGPL 库本身** | 是 | 对 DaxPay 源码的修改必须以 LGPL 协议开源 |
绝大多数场景下,业务系统通过 **RESTful HTTP 接口**调用 DaxPay(独立部署的支付服务),这属于「通过网络调用」,你的业务代码**无需开源**,可自由用于商业闭源项目。
## 商业使用说明
LGPL v3.0 **允许商业使用**。具体地:
- ✅ **商用授权** — 企业可免费将 DaxPay 用于商业项目
- ✅ **SaaS 服务** — 可基于 DaxPay 对外提供 SaaS 支付服务
- ✅ **闭源业务** — 业务系统通过接口调用 DaxPay,业务代码可闭源
- ✅ **二次开发** — 可修改源码适配自身需求(对 DaxPay 本身的修改需开源)
- ✅ **私有部署** — 可在内部私有环境部署,无需公开配置
若你**修改了 DaxPay 源码本身**(而非仅调用其接口),修改部分必须以 LGPL v3.0 协议开源。仅通过接口调用则无此义务。
## 商业授权
开源版基于 LGPL v3.0,**允许商业使用**。若你需要**闭源修改 DaxPay 源码**(修改后无需开源),可购买商业授权跳过 LGPL 的开源义务。
### 开源授权 vs 商业授权
| 维度 | 开源授权 (LGPL v3.0) | 商业授权 |
|------|---------------------|---------|
| 费用 | 免费 | 付费(基础版 ¥999 起) |
| 商业使用 | ✅ 允许 | ✅ 允许 |
| 闭源修改源码 | ❌ 修改需以 LGPL 开源 | ✅ 修改无需开源 |
| 深度定制 | 受 LGPL 约束 | 无开源义务 |
| 技术支持 | 社区交流群 | 专属群 + 工单支持 |
| 代码获取 | 公开仓库 | 阿里云效私服 |
- 你修改了 DaxPay 源码并希望**闭源**这些修改
- 你希望获得**专属技术支持**与优先问题响应
- 仅通过接口调用(不修改源码)**无需购买**,LGPL 已允许商用
### 版本选择
DaxPay 提供多个商业版本,满足不同业务场景:
- **基础版**(¥999)— 源码授权 + 商业授权,适合个人 / 小团队
- **增强版** — 基础版 + 多端小程序(管理端 / 商户端 / 收银小程序)
- **旗舰版** — 增强版 + 全部支付通道
完整版本对比详见 [版本清单](https://doc.open.daxpay.cn/extension/pricing/overview.md)。
### 联系购买
微信添加小助手 `sdcit2020` 咨询商业授权与版本选择。
## 你的义务
使用 DaxPay 时需遵守以下义务:
1. **保留版权声明** — 分发或部署时保留原始版权与许可证声明
2. **开源修改** — 对 DaxPay 库本身的修改须以 LGPL 开源
3. **注明来源** — 衍生作品需注明基于 DaxPay
## 协议全文
- [LGPL v3.0 协议原文(英文)](https://www.gnu.org/licenses/lgpl-3.0.html)
- [LGPL v3.0 协议原文(中文翻译)](https://www.gnu.org/licenses/lgpl-3.0.zh-cn.html)
- [GPL v3.0 协议原文](https://www.gnu.org/licenses/gpl-3.0.html)(LGPL 基于 GPL)
本页为 LGPL v3.0 协议的通俗说明,不构成法律意见。如有疑问请查阅协议原文或咨询专业法律顾问。最终解释以 [LGPL v3.0 协议原文](https://www.gnu.org/licenses/lgpl-3.0.html)为准。
---
# 网关支付
**源**: https://doc.open.daxpay.cn/common/gateway-payment.md
# 网关支付
> 网关支付提供统一的支付收银台与交易处理能力,支持多种支付方式与通道路由。
## 功能概览
- 收银台页面 — 统一网关收银台,自适应 PC 与移动端
- 支付流程 — 统一下单、支付、异步回调完整链路
- 支付方式 — 扫码支付、JSAPI、APP、H5 等多种支付场景
- 通道路由 — 多通道智能路由,按产品与策略匹配最优通道
> 🚧 本功能正在开发中,详细操作指南将在后续版本中补充。
---
# 商户配置
**源**: https://doc.open.daxpay.cn/common/merchant-config.md
# 商户配置
> 商户配置是支付系统的核心管理功能,涵盖商户信息、通道参数、应用密钥等配置管理。
## 功能概览
- 商户信息管理 — 商户号、联系人、结算信息维护
- 通道商户配置 — 各支付通道(支付宝、微信、银联等)的商户参数对接
- 应用与密钥 — 应用创建、API 密钥生成与管理
- 环境配置 — 沙箱联调与生产环境切换
> 🚧 本功能正在开发中,详细操作指南将在后续版本中补充。
---
# 交易管理
**源**: https://doc.open.daxpay.cn/common/transaction-management.md
# 交易管理
> 交易管理涵盖订单查询、退款处理、资金对账等商户日常运营核心功能。
## 功能概览
- 订单管理 — 支付订单全生命周期查询与跟踪
- 退款管理 — 退款发起、审核与状态跟踪
- 交易流水 — 资金流水明细与对账文件下载
- 数据统计 — 交易量、成功率、通道分布等数据分析
> 🚧 本功能正在开发中,详细操作指南将在后续版本中补充。