# 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 # 交易管理 > 交易管理涵盖订单查询、退款处理、资金对账等商户日常运营核心功能。 ## 功能概览 - 订单管理 — 支付订单全生命周期查询与跟踪 - 退款管理 — 退款发起、审核与状态跟踪 - 交易流水 — 资金流水明细与对账文件下载 - 数据统计 — 交易量、成功率、通道分布等数据分析 > 🚧 本功能正在开发中,详细操作指南将在后续版本中补充。