# Technical Documentation: jeequan/jeepay

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/jeequan/jeepay)

### Overview (`README.md`)

<p align="center">
  <a href="https://www.jeequan.com">
    <img src="https://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jeepay_logo.svg" alt="Jeepay Logo">
  </a>
</p>

<p align="center">
  <strong>计全支付（Jeepay）- 让支付接入更简单</strong>
</p>

<p align="center">
  一套面向互联网企业的开源支付系统，支持普通商户模式、服务商模式、聚合支付与多应用接入。
</p>

<p align="center">
  👉 <a href="https://www.jeequan.com">官网</a> ·
  <a href="https://doc.jeequan.com/#/integrate/open">项目文档</a> ·
  <a href="https://github.com/jeequan/jeepay">GitHub</a> ·
  <a href="https://gitee.com/jeequan/jeepay">Gitee</a> ·
  <a href="https://github.com/jeequan/jeepay-ui">前端项目</a>
</p>

<p align="center">
  <a target="_blank" href="https://spring.io/projects/spring-boot">
    <img src="https://img.shields.io/badge/Spring%20Boot-3.3.7-yellowgreen" />
  </a>
  <a target="_blank" href="https://www.oracle.com/java/technologies/downloads/#java17">
    <img src="https://img.shields.io/badge/JDK-17-green.svg" />
  </a>
  <a target="_blank" href="http://www.gnu.org/licenses/lgpl.html">
    <img src="https://img.shields.io/badge/license-LGPL--3.0-blue" />
  </a>
  <a href="https://gitee.com/jeequan/jeepay/stargazers" target="_blank">
    <img src="https://gitee.com/jeequan/jeepay/badge/star.svg?theme=gvp" alt="gitee star">
  </a>
  <a target="_blank" href="https://github.com/jeequan/jeepay">
    <img src="https://img.shields.io/github/stars/jeequan/jeepay.svg?style=social" alt="github star"/>
  </a>
  <a target="_blank" href="https://gitcode.com/jeequantech/jeepay">
    <img src="https://gitcode.com/jeequantech/jeepay/star/badge.svg" alt="gitcode star"/>
  </a>
</p>

<p align="center">
  <a href="https://jq.qq.com/?_wv=1027&k=94WnXmdL">
    <img src="https://img.shields.io/badge/QQ%E7%BE%A4%E2%91%A0-635647058-critical" alt="QQ群">
  </a>
</p>

---

# 目录

- [项目简介](#项目简介)
- [Jeepay 适合谁](#jeepay-适合谁)
- [官方托管服务（计全付）](#官方托管服务计全付)
- [部署方式](#部署方式)
- [系统架构](#系统架构)
- [核心技术栈](#核心技术栈)
- [文档与资源](#文档与资源)
- [贡献与协作](#贡献与协作)
- [更多支持](#更多支持)

---

# 项目简介

Jeepay 是一套面向互联网企业的开源支付系统，支持 **普通商户模式** / **多渠道服务商模式** / **聚合码支付** / **多商户多应用接入**。已对接微信支付、支付宝、云闪付等主流渠道。

后端 `Spring Boot 3.3.7` + `JDK 17` + `Spring Security`，前端 `Ant Design Vue`，MQ 支持 `RocketMQ` / `ActiveMQ` / `RabbitMQ`。

适合自建聚合支付平台、SaaS 支付中台、多商户支付系统以及电商 / 零售 / 本地生活 / 数字内容等业务的支付接入与二次开发。

---

# Jeepay 适合谁

- 想**独立掌控**支付流程、商户体系、渠道配置、回调通知，不想被托管服务绑定
- 需要**服务商模式**管理多家商户、多家渠道的平台方
- 计划长期**二次开发**，希望起点是一套架构清晰、代码分层明确、文档完备的开源系统
- 需要 Docker / Shell 一键部署、分布式、多 MQ 可切换的**可运维**支付底座

由原 `XxPay` 团队持续开发维护，多年支付实战沉淀。

---

# 官方托管服务（计全付）

如果你希望 **不自建部署、直接拿到可用的支付通道与分账能力**，欢迎来 **计全付官方** 申请接入：

- **目标场景**：没有支付牌照 / 没有支付通道资源的中小商户、SaaS 平台、独立开发者
- **提供内容**：微信、支付宝、银联等主流通道聚合接入；**分账能力**；账户体系、结算与对账；售后支撑
- **分账亮点**：支持 **100% 全额分账**，满足平台型业务的分润 / 代收代付诉求
- **优势**：开通即用，免去服务器与运维成本；费率与政策按业务规模定制

联系方式：官网 <https://www.jeequan.com> · 微信客服见文末。

---

# 部署方式

| 方式 | 适用场景 | 跳转 |
|---|---|---|
| **Shell 脚本一键安装** | 干净的 CentOS / Anolis / Ubuntu / Debian 服务器 | [docs/deploy/shell.md](docs/deploy/shell.md) |
| **Docker Compose 部署** | 本地 / 测试环境起完整集群（含前端） | [docs/deploy/compose.md](docs/deploy/compose.md) |
| 宝塔面板一键安装 | 有宝塔面板（≥ 9.2.0），Docker 应用市场一键装 | Compose 文件：[`docker-compose.baota.yml`](docker-compose.baota.yml)，用法：[docs/deploy/baota.md](docs/deploy/baota.md) |
| 自助源码部署 | 对接内部基础设施的团队 | 自备 MySQL / Redis / MQ，按环境调整 `conf/` 后 Maven 打包部署 |

> 默认镜像指向**华为云 SWR 公开仓库**，国内零配置直达，不依赖 Docker Hub。部署后需域名 + HTTPS 见 [docs/deploy/https.md](docs/deploy/https.md)，出问题优先看 [docs/deploy/troubleshooting.md](docs/deploy/troubleshooting.md)。

---

# 系统架构

> Jeepay 计全支付系统架构图



> Jeepay 聚合码支付流程图



---

# 核心技术栈

| 软件名称 | 描述 | 版本 |
|---|---|---|
| JDK | Java 运行环境 | 17 |
| Spring Boot | 后端开发框架 | 3.3.7 |
| Redis | 分布式缓存 | 3.2.8+ |
| MySQL | 数据库 | 5.7.x / 8.0+ |
| MQ | 消息中间件 | RocketMQ / ActiveMQ / RabbitMQ |
| Ant Design Vue | 前端 UI 框架 | 4.2.6 |
| MyBatis-Plus | MyBatis 增强工具 | 3.4.2 |
| WxJava | 微信开发 Java SDK | 4.6.0 |
| Hutool | Java 工具类库 | 5.8.26 |

---

# 文档与资源

## 官方文档

- 项目文档：<https://doc.jeequan.com/#/integrate/open>
- 快速上手：<https://doc.jeequan.com/#/integrate/open/dev/109>
- 开发指导：<https://doc.jeequan.com/#/integrate/open/dev/103>
- 通道对接：<https://doc.jeequan.com/#/integrate/open/dev/104>
- 线上部署：<https://doc.jeequan.com/#/integrate/open/dev/111>
- 接口文档：<https://doc.jeequan.com/#/integrate/open/api/81>
- 常见问题：<https://doc.jeequan.com/#/integrate/open/dev/107>

## 本仓库文档

- 部署 — Shell 脚本：[docs/deploy/shell.md](docs/deploy/shell.md)
- 部署 — Docker Compose：[docs/deploy/compose.md](docs/deploy/compose.md)
- 部署 — 宝塔面板：[docs/deploy/baota.md](docs/deploy/baota.md)
- 部署 — 域名 + HTTPS：[docs/deploy/https.md](docs/deploy/https.md)
- 部署 — 常见问题排查：[docs/deploy/troubleshooting.md](docs/deploy/troubleshooting.md)
- 镜像发布（维护者）：[docs/deploy/publish.md](docs/deploy/publish.md)
- 功能与接口市场：[docs/features.md](docs/features.md)
- 项目结构：[docs/project-structure.md](docs/project-structure.md)
- 系统截图：[docs/screenshots.md](docs/screenshots.md)
- 贡献指南：[CONTRIBUTING.md](CONTRIBUTING.md)

## SDK 资源

Jeepay 已提供 Java、Python SDK，以及 PHP 对接 Demo：

- SDK 下载地址：<https://doc.jeequan.com/#/integrate/open/api/116>
- Java SDK 仓库：<https://github.com/jeequan/jeepay-sdk-java>

## AI 接入助手

如果你用 Claude / Cursor / ChatGPT 等 AI 工具接入 Jeepay，可以使用 [Jeepay Skills](https://github.com/jeequan/jeepay-skills) —— 把签名陷阱、字段大小写、wayCode 选择等 AI 容易踩坑的细节系统化整理，让 AI 一次接对。

- 仓库地址：<https://github.com/jeequan/jeepay-skills>
- 支持 Claude Code / Cursor / Cline / 网页 AI（claude.ai · ChatGPT · 通义千问 · 文心一言）
- 也可作为纯文档浏览，不用 AI 也能直接看接入指南

## 项目地址

- 服务端：[GitHub](https://github.com/jeequan/jeepay) · [Gitee](https://gitee.com/jeequan/jeepay) · [GitCode](https://gitcode.com/jeequantech/jeepay)
- 前端：[GitHub](https://github.com/jeequan/jeepay-ui) · [Gitee](https://gitee.com/jeequan/jeepay-ui) · [GitCode](https://gitcode.com/jeequantech/jeepay-ui)

---

# 贡献与协作

- 分支模型、commit 规范、PR 流程、测试要求：见 [CONTRIBUTING.md](CONTRIBUTING.md)
- 反馈问题 / 提交 PR / 完善渠道对接 / 补充文档，都欢迎
- 在线体验：[支付流程](https://www.jeequan.com/demo/jeepay_cashier.html) · [管理平台演示](https://www.jeequan.com/doc/detail_84.html)

---

# 更多支持

欢迎关注官方渠道，获取更多产品动态、部署指导与社区支持。

## 官方公众号

微信扫描下方二维码，关注 **计全科技** 公众号：



## 官方微信交流群

微信扫描下方二维码加入官方交流群。若项目对你有帮助，欢迎先点一个 Star 支持。



## 微信客服

- 微信客服咨询：<https://work.weixin.qq.com/kfid/kfc6de0edce151ee062>

---

### Features (`docs/features.md`)

# 功能与接口市场

## 功能模块

> Jeepay 运营平台功能



> Jeepay 商户系统功能



## 接口市场

计全官方团队基于开源版代码，持续开发了多家第三方支付机构、银行以及扩展支付接口的对接代码，帮助用户更快完成支付能力接入。

- 接口市场：<https://www.jeequan.com/ifstore/list.html>
- 插件安装说明：<https://doc.jeequan.com/#/integrate/open/dev/113>

### 三方支付

汇付 Adapay、斗拱支付、支付宝直付通、微信收付通、银盛支付、银联条码前置、银联支付、联动优势、国通星驿付、丰付支付、盛付通、乐刷、杉德支付、瑞银信、拉卡拉、汇聚支付、新生支付、河马支付、海科融通、富友支付、易生支付、支付宝云支付、通联支付。

### 银行

工行支付、浦发银行、建行龙支付、交行支付。

### 四方支付

付呗支付、米花支付。

---

### Project Structure (`docs/project-structure.md`)

# 项目结构与仓库关系

## 项目结构

```text
jeepay
├── conf                     # 系统部署所需 yml 配置
├── docker                   # Docker 相关文件
├── docs                     # 项目文档
│   ├── deploy               # 部署详细文档
│   ├── install              # 安装脚本
│   ├── script               # 启动脚本
│   └── sql                  # 初始化 SQL 文件
├── jeepay-components        # 公共组件目录
│   ├── jeepay-components-mq # MQ 组件
│   └── jeepay-components-oss# OSS 组件
├── jeepay-core              # 核心依赖模块
├── jeepay-manager           # 运营平台服务端（9217）
├── jeepay-merchant          # 商户系统服务端（9218）
├── jeepay-payment           # 支付网关（9216）
├── jeepay-service           # 业务层代码
└── jeepay-z-codegen         # MyBatis 代码生成模块
```

## 仓库关系

| 仓库 | 作用 |
|---|---|
| `jeepay` | 服务端主仓库，包含支付网关、运营平台、商户平台、核心服务 |
| `jeepay-ui` | 前端项目 |
| `jeepay-sdk-java` | Java SDK，供业务系统对接 Jeepay 接口时使用 |

---

### Deploy Baota (`docs/deploy/baota.md`)

# 宝塔面板部署

面向在宝塔（BaoTa）面板上把 jeepay 作为 Docker 应用一键安装的场景。宝塔用户不需要 `git clone` 源码，所有配置文件由 compose 里的 `jeepay-configs` init 容器（`alpine/git` 镜像）从 gitee 按 tag 拉下来分发。

## Compose 文件

- 位置：仓库根目录 [`docker-compose.baota.yml`](../../docker-compose.baota.yml)
- 宝塔应用模板引用该文件作为 `docker-compose` 部分即可

## 镜像默认地址

所有业务镜像 + MySQL / Redis / RocketMQ / Nginx 默认走**华为云 SWR 公开仓库**（`swr.cn-south-1.myhuaweicloud.com/jeepay/*`），由计全官方维护，国内直拉不需要 Docker Hub 加速器。`alpine/git`（配置分发 init 容器）仍从 Docker Hub 拉（< 20MB，一次性）。

想改回 Docker Hub 上游镜像，可通过下面"可选环境变量"覆盖。

## 宝塔应用模板要声明的变量

### 必须

| 变量 | 用途 | 建议默认 |
|---|---|---|
| `VERSION` | 业务镜像 tag（`jeepay-manager` 等） | `3.2.0` |
| `CONFIG_REF` | 配置源 git ref（与 `VERSION` 同版本的 tag 或 `master`） | 当前 release tag |
| `UI_RELEASE` | 前端 `html.tar.gz` 的 `jeepay-ui` release tag | `V3.0.0` |
| `APP_PATH` | 宿主部署根目录 | 宝塔默认 |
| `HOST_IP` | 对外绑定 IP | 宝塔默认 |
| `WEB_HTTP_PORT1` / `2` / `3` | 映射到容器 `19216` / `19217` / `19218` | `19216` / `19217` / `19218` |
| `CPUS` / `MEMORY_LIMIT` | nginx 资源限制 | `1` / `512m` |

### 可选（改镜像源时覆盖）

| 变量 | 默认 |
|---|---|
| `MYSQL_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/mysql:8.0.25` |
| `REDIS_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/redis:6.2.14` |
| `ROCKETMQ_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/rocketmq:5.3.1` |
| `NGINX_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/nginx:1.18.0` |
| `MANAGER_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-manager:${VERSION}` |
| `MERCHANT_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-merchant:${VERSION}` |
| `PAYMENT_IMAGE` | `swr.cn-south-1.myhuaweicloud.com/jeepay/jeepay-payment:${VERSION}` |
| `JEEPAY_CONFIGS_IMAGE` | `alpine/git:v2.45.2`（Docker Hub） |

**切回 Docker Hub 整套示例**：

```
MYSQL_IMAGE=mysql:8.0.25
REDIS_IMAGE=redis:6.2.14
ROCKETMQ_IMAGE=apache/rocketmq:5.3.1
NGINX_IMAGE=nginx:1.18.0
MANAGER_IMAGE=jeepay/jeepay-manager:3.2.0
MERCHANT_IMAGE=jeepay/jeepay-merchant:3.2.0
PAYMENT_IMAGE=jeepay/jeepay-payment:3.2.0
```

## 安装后怎么改配置

配置文件都在 `${APP_PATH}/jeepayhomes/jeepayConfigs/` 下，**直接编辑即可**：

```
jeepayConfigs/
├── db/my.cnf, init.sql
├── redis/redis.conf
├── rocketmq/broker.conf
├── service/{manager,merchant,payment}/application.yml
├── nginx/nginx.conf, conf.d/, html/
└── .latest/        # 最新版模板（只读参考，不要改）
```

改完重启对应服务：

```bash
docker compose restart jeepay-manager
# nginx 改完可热加载
docker exec nginx118 nginx -t && docker exec nginx118 nginx -s reload
```

`jeepay-configs` 用 `cp -n` 铺配置，**已存在的文件永远不覆盖**，机器重启 / compose up 都不会丢失用户编辑。

## 升级版本

1. 在宝塔 UI 改 `VERSION` 和 `CONFIG_REF` 到新 tag（两者建议同值）
2. 重建应用：宝塔 UI 点"重建"，或 `docker compose up -d`
3. `.latest/` 目录会同步刷新到新版模板，用户自己的 yml 不动
4. 看 `diff` 决定是否合并新模板中的新字段：
   ```bash
   diff ${APP_PATH}/jeepayhomes/jeepayConfigs/service/manager/application.yml \
        ${APP_PATH}/jeepayhomes/jeepayConfigs/.latest/conf/manager/application.yml
   ```

## 宝塔场景特有的点

- **不需要 `jeepay/jeepay-configs` 镜像**：从 `alpine/git` 直接 clone，配置永远跟 git tag 一致
- **`jeepay-configs` 容器安装后显示 `Exited (0)`**：正常，一次性 init 容器跑完即退出
- **`baota_net` 是宝塔预建网络**：compose 里 `external: true`，不要自己创建

## 验证

安装完成后检查：

```bash
# 8 个业务容器 + 1 个 init 容器
docker ps -a --format "table {{.Names}}\t{{.Status}}" | grep -E "jeepay|mysql8|redis6|rocketmq|nginx118"

# 三个 API healthy
for c in jeepaymanager jeepaymerchant jeepaypayment; do
  echo -n "$c: "; docker inspect --format '{{.State.Health.Status}}' $c
done

# 验证码 / 登录（浏览器访问宝塔映射的 19217 端口）
```

## 出问题看哪里

- [troubleshooting.md](./troubleshooting.md)：所有部署方式通用的故障排查
- [https.md](./https.md)：配置域名 + HTTPS 反代（宝塔场景建议在外层再套一层 nginx + 证书）
- `${APP_PATH}/jeepayhomes/service/logs/`：业务服务日志
- `docker logs jeepay-configs`：配置分发是否成功

---

### Deploy Compose (`docs/deploy/compose.md`)

# Docker Compose 部署

适合本地 / 测试环境拉起完整集群（含前端）。

## 目录约定

```
jeepay-open/
├── jeepay/
└── jeepay-ui/
```

前端不在 jeepay 同级时，可在 `jeepay/.env` 覆盖 `UI_BASE_DIR`（参考 `.env.example`）。

## 启动

```bash
cd jeepay
mvn clean package -DskipTests          # 编译后端 JAR

docker compose up -d --build           # 首次：编译镜像 + 启动
docker compose up -d                   # 后续：跳过编译
docker compose restart payment         # 重启某个服务
```

**默认镜像**指向华为云 SWR 公开仓库（与 Shell 部署一致），国内零配置直达。

## 暴露端口

| 组件 | 端口 |
|---|---|
| MySQL | `13306`（避开宿主 3306） |
| Redis | `6380` |
| RocketMQ | `9876` / `10909` / `10911` / `10912` |
| payment / manager / merchant | `9216` / `9217` / `9218` |
| 前端 | manager `9227` / merchant `9228` / cashier `9226` |

## 默认账号

- 运营平台 `http://localhost:9227`：`jeepay` / `jeepay123`
- 商户系统 `http://localhost:9228`：需运营平台创建商户用户（默认密码 `jeepay666`）

## 常用命令

```bash
docker compose ps
docker compose logs -f --tail=100 payment manager merchant
docker compose config                  # 启动前变量 / 语法校验
docker compose down                    # 停止 + 清网络（卷保留）
docker compose down -v                 # 连同卷一起删
```

## 配置说明

- 默认 MQ = RocketMQ；`conf/payment|manager|merchant/application.yml` 已切到 `rocketMQ`。
- 容器内 MySQL / Redis 主机名 = `mysql` / `redis`（compose 已配 network alias）。
- 改 `conf/*.yml` 后 `docker compose restart <service>` 即可。
- 要回到 ActiveMQ / RabbitMQ，需同时改 `docker-compose.yml` 和 `conf/*.yml`。

---

- 出问题排查：[troubleshooting.md](./troubleshooting.md)
- 推镜像到 Docker Hub / 华为云 SWR（维护者流程）：[publish.md](./publish.md)

---

### Deploy Https (`docs/deploy/https.md`)

# 域名 + HTTPS 反代

jeepay 三个平台的公网接入需要在 19216 / 19217 / 19218 前面再架一层 nginx + SSL。本文给出可直接抄的模板。

## 代码层面已就绪

- 内置 `nginx.conf` 三个 server 都已补 `X-Forwarded-Proto` / `X-Forwarded-Port` / `proxy_http_version 1.1` / WebSocket 头 / 长超时。
- Spring Boot 已开启 `server.forward-headers-strategy: framework`。

外层反代只要照下面模板写，回跳 URL / WebSocket / 微信支付 H5 redirect 都会自动拼对。

## 推荐拓扑：三个子域名

| 外部域名 | 用途 | 内部回源 |
|---|---|---|
| `admin.example.com` | 运营平台 | `http://127.0.0.1:19217` |
| `mch.example.com` | 商户平台 | `http://127.0.0.1:19218` |
| `pay.example.com` | 支付网关 + 收银台 | `http://127.0.0.1:19216` |

## 外层 nginx 模板

```nginx
server {
    listen 443 ssl http2;
    server_name pay.example.com;
    ssl_certificate     /etc/ssl/jeepay/pay.crt;
    ssl_certificate_key /etc/ssl/jeepay/pay.key;

    location / {
        proxy_pass http://127.0.0.1:19216;
        proxy_http_version 1.1;                         # 必须，否则 WS 会被隐式关闭

        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;     # 必须，否则 Spring Boot 拼 http:// 回调
        proxy_set_header X-Forwarded-Port  $server_port;

        # WebSocket（商户端支付测试 / 收银台订单推送）
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout  3600s;                      # 默认 60s，长连接会静默断
        proxy_send_timeout  3600s;
    }
}
# admin / mch 域名同构，仅 proxy_pass 换为 19217 / 19218
```

## 快速申请 Let's Encrypt 证书

```bash
# 宿主机（不是容器内）
yum install -y nginx certbot python3-certbot-nginx   # Ubuntu: apt-get -y install ...
certbot --nginx -d admin.example.com -d mch.example.com -d pay.example.com \
  --agree-tos -m you@example.com --redirect
```

`certbot --nginx` 会自动给你上面写的 server 块加 `listen 443 ssl` + cert 路径 + HTTP→HTTPS 301。

## 第三方支付平台回调 URL

去微信 / 支付宝 / 云闪付后台，异步通知 / 回跳 URL 必须填**公网域名**，不要填内网 IP：

```
https://pay.example.com/api/pay/notify/...
https://pay.example.com/api/anon/paySuccess?...
```

## 验证

```bash
# 握手 101 + Spring Boot 能识别 https
curl -s -I https://admin.example.com/api/anon/auth/vercode?t=$(date +%s) | head -3
# 收银台
curl -s -o /dev/null -w "%{http_code}\n" https://pay.example.com/cashier/index.html
```

访问 `https://admin.example.com` 登录、`https://mch.example.com` 发起支付测试，浏览器 DevTools Network 里 WS 连接应该能持续收到订单状态推送。

## 防火墙

- 公网必须开：`80` `443`
- 公网建议关：`19216` / `19217` / `19218`（已通过 80/443 反代提供）

## 不同拓扑的取舍

- **单域名 + 路径前缀**（比如 `https://www.example.com/admin/`）：需要同步改前端 `publicPath` + Spring Boot `context-path`，工作量大，不推荐新手。
- **只对外暴露收银台**：SaaS / 电商最常用，公网只放 `pay.example.com`，运营 / 商户平台留内网。防火墙只开一个子域对应的 80/443。

---

### Deploy Publish (`docs/deploy/publish.md`)

# 镜像发布（维护者流程）

终端用户**不需要**看本文。仓库默认镜像已指向华为云 SWR 公开仓库，装即用。

本文给计全团队 / 二开团队说明如何把自己构建的 jeepay 镜像推到镜像仓库。

## 发布到 Docker Hub

```bash
docker login

DOCKERHUB_NAMESPACE=<你的 Docker Hub 用户名或组织> \
IMAGE_TAG=3.2.0 \
PUSH_LATEST=true \
bash docker/publish-dockerhub.sh
```

参数：

- `DOCKERHUB_NAMESPACE`：必填。
- `IMAGE_TAG`：版本号，默认 `latest`。
- `PUSH_LATEST=true`：非 latest tag 时额外补推 latest。
- `SKIP_MAVEN=true`：JAR 已提前打包时跳过 `mvn package`。

推送产物：

- `<namespace>/jeepay-manager:<tag>`
- `<namespace>/jeepay-merchant:<tag>`
- `<namespace>/jeepay-payment:<tag>`

## 发布到华为云 SWR（amd64 + arm64 多架构）

```bash
docker login swr.cn-south-1.myhuaweicloud.com

SWR_NAMESPACE=jeepay \
IMAGE_TAG=3.2.0 \
PUSH_LATEST=true \
bash docker/publish-swr.sh
```

- 分别构建并推 `amd64` / `arm64` 临时 tag，再合成统一多架构 tag。
- 用户最终使用：`swr.cn-south-1.myhuaweicloud.com/<namespace>/jeepay-manager:3.2.0`。
- 改区域：`SWR_REGISTRY=swr.cn-north-4.myhuaweicloud.com`。

## 同步第三方基础镜像到 SWR

让国内用户完全免 Docker Hub 访问：

```bash
SWR_NAMESPACE=jeepay bash docker/sync-swr-thirdparty.sh
```

默认同步：

- `mysql:8` / `mysql:8.0.25`
- `redis:6.2.14`
- `apache/rocketmq:5.3.1`
- `nginx:1.18.0`
- `eclipse-temurin:17-jre`

同步完成后仓库默认部署配置会优先使用 `swr.cn-south-1.myhuaweicloud.com/jeepay/*`。

---

### Deploy Shell (`docs/deploy/shell.md`)

# Shell 脚本一键安装

在一台干净的 x86_64 服务器（CentOS / Anolis / Ubuntu / Debian）上，复制粘贴一条命令：

**CentOS / Anolis**
```bash
yum install -y wget curl && wget -O install.sh https://gitee.com/jeequan/jeepay/raw/master/docs/install/install.sh && bash install.sh
```

**Ubuntu / Debian**
```bash
apt update && apt-get -y install wget curl git docker.io && wget -O install.sh https://gitee.com/jeequan/jeepay/raw/master/docs/install/install.sh && bash install.sh
```

脚本自动：识别发行版、装齐依赖（`wget` / `curl` / `git` / `docker`）、拉镜像、起 8 个容器、跑部署自检。**默认**：

| 项 | 值 |
|---|---|
| 安装目录 | `/jeepayhomes` |
| 镜像来源 | `swr.cn-south-1.myhuaweicloud.com/jeepay/*`（华为云 SWR 公开仓库，免登录） |
| MQ | RocketMQ（namesrv + broker） |
| 源码 ref | 最新 release tag（与业务镜像完全兼容） |

装完访问：

| 平台 | 地址 | 账号 / 密码 |
|---|---|---|
| 运营平台 | `http://<IP>:19217` | `jeepay` / `jeepay123` |
| 商户系统 | `http://<IP>:19218` | 需在运营平台创建商户用户，默认密码 `jeepay666` |
| 支付网关 / 收银台 | `http://<IP>:19216/cashier/index.html` | — |

## 常用命令

```bash
# 容器 / 日志 / 资源
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
docker logs -f jeepaymanager --tail 100
docker stats --no-stream

# 改完 yml / nginx.conf 后重启或重载
docker restart jeepaymanager jeepaymerchant jeepaypayment
docker exec nginx118 nginx -t && docker exec nginx118 nginx -s reload

# 完整安装日志（每步输出 + summary box）
ls -lt /tmp/jeepay-install-*.log | head -1

# MySQL / Redis 直连
docker exec -it mysql8 mysql -uroot -p'jeepaydb123456' jeepaydb
docker exec -it redis6 redis-cli
```

## 卸载

```bash
wget -O uninstall.sh https://gitee.com/jeequan/jeepay/raw/master/docs/install/uninstall.sh && bash uninstall.sh
```

脚本自动识别 `rootDir`（从 `mysql8` 容器卷反推），打印确认后删容器 / 网络 / 整个 `rootDir`。若容器已手工清掉，可显式：`rootDir=/jeepayhomes bash uninstall.sh`。

## 高级覆盖项（可选）

安装前 `export xxx=yyy`，或在 `docs/install/config.sh` 取消对应注释行即可。

| 变量 | 默认 | 场景 |
|---|---|---|
| `rootDir` | `/jeepayhomes` | 改部署目录 |
| `mysql_pwd` | `jeepaydb123456` | 改 MySQL root 密码 |
| `mysqlHostPort` / `redisHostPort` | `3306` / `6379`（被占自动换到 `13306` / `16379`） | 固定到某个端口 |
| `mysqlImage` / `redisImage` / `rocketmqImage` / `nginxImage` | SWR 官方 | 切内网仓库 / 回 Docker Hub |
| `managerImage` / `merchantImage` / `paymentImage` | SWR `jeepay-*:3.2.0` | 换自有镜像 / 版本 |
| `rocketmqPlatform` | `linux/amd64` | 自行构建的 arm64 RocketMQ 镜像时改 `linux/arm64`（上游 rocketmq 不发 arm64） |
| `brokerIP1` | `rocketmq-broker` | 有外部 RocketMQ 客户端时改真实 IP |
| `jeepayRef` | 最新 release tag | 临时拉 master 或其他 tag |

---

- 出问题排查：[troubleshooting.md](./troubleshooting.md)
- 域名 + HTTPS 反代：[https.md](./https.md)
- Docker Compose 部署：[compose.md](./compose.md)

---

### Deploy Troubleshooting (`docs/deploy/troubleshooting.md`)

# 部署常见问题排查

排障第一步：先看**完整安装日志**（Shell 部署时脚本在开头与 summary box 里都打印了路径）：

```bash
ls -lt /tmp/jeepay-install-*.log | head -1
less $(ls -t /tmp/jeepay-install-*.log | head -1)
```

## 登录页验证码不出 / 任何 DB 操作报错

99% 是 manager 连不上 MySQL 或 Redis。按下面顺序排查：

```bash
# 1) 三个应用是否 healthy
for c in jeepaymanager jeepaymerchant jeepaypayment; do
  echo -n "$c: "; docker inspect --format '{{.State.Health.Status}}' $c
done

# 2) manager 实际挂载的 application.yml
docker exec jeepaymanager grep -nE "url:|host:|password:" /jeepayhomes/service/app/application.yml

# 3) 从 manager 容器内验证 DB / Redis 连通
docker exec jeepaymanager getent hosts mysql redis
docker exec jeepaymanager sh -c "timeout 3 bash -c '</dev/tcp/mysql/3306' && echo MySQL_OK"
docker exec jeepaymanager sh -c "timeout 3 bash -c '</dev/tcp/redis/6379' && echo Redis_OK"
```

历史坑（V3.2.7 之前的老部署可能遇到）：
- `application.yml` 里 `host: redis` / `mysql`，但容器名是 `redis6` / `mysql8` → 新版 `install.sh` 已给容器加 `--network-alias`。
- `password: rootroot`（Compose 默认）与 `mysql_pwd=jeepaydb123456` 不一致 → 新版 `install.sh` 会自动 `sed` 替换。

## 业务触发 RocketMQ 时报 `connect to x.x.x.x:10911 failed`

两个可能原因：
1. **broker.conf 里 `brokerIP1` 是宿主的某个 Docker bridge 地址**（老版本用 `hostname -I` 挑错了）：
   ```bash
   rootDir=$(docker inspect mysql8 --format '{{range .Mounts}}{{if eq .Destination "/var/lib/mysql"}}{{.Source}}{{end}}{{end}}' | sed 's|/mysql/data$||')
   sed -i 's/^brokerIP1=.*/brokerIP1=rocketmq-broker/' $rootDir/rocketmq/broker/conf/broker.conf
   docker restart rocketmq-broker
   ```
2. **broker 启动好了但 Spring Boot RocketMQ producer 缓存了坏连接**——重启三个业务应用让客户端重新从 nameserver 拉路由：
   ```bash
   docker restart jeepaymanager jeepaymerchant jeepaypayment
   ```

## RocketMQ Broker 启动失败 NullPointerException

Broker 日志出现 `ScheduleMessageService.configFilePath` 相关 NPE，通常是 volume 权限问题。RocketMQ 5.x 镜像以 `rocketmq`（uid=3000）用户运行，而 Docker volume 默认 root 权限：

```bash
docker run --rm -u root -v jeepay_rocketmq_broker_store:/data alpine chown -R 3000:3000 /data
docker run --rm -u root -v jeepay_rocketmq_broker_logs:/data alpine chown -R 3000:3000 /data
```

Compose 已通过 `user: "0:0"` 规避；Shell 部署命中需手工修。

## WebSocket 握手 101 但收不到消息

商户端支付测试页 `ws://.../api/anon/ws/payOrder/...` 订阅订单状态，握手显示 `101 Switching Protocols` 但后续没数据。外层 nginx 必须配：

```nginx
proxy_http_version 1.1;                # 必须，HTTP/1.0 下 Connection: close 隐式生效
proxy_set_header Upgrade   $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout  3600s;             # 默认 60s，长连接必断
proxy_send_timeout  3600s;
```

内层 jeepay 内置 nginx 已从 V3.2.7 起全量补齐，外层反代若自己维护需同步修。

## `application.yml` 变成目录而不是文件

Spring Boot 容器起来但拿不到配置。原因：某次 `cp` 失败后 `docker run -v <path>:<container>` 把 host 不存在的 path 自动建成目录：

```bash
docker stop jeepaymanager jeepaymerchant jeepaypayment
rm -rf $rootDir/service/configs
bash uninstall.sh        # 或手工重跑 install.sh 的 [6] 步骤
```

V3.2.8+ 的 `install.sh` 每个 `cp` 都加了返回值 + 文件类型校验，失败会 `exit 1` 明确指引，不再留半成品。

## Apple Silicon（M1/M2/M3）

RocketMQ 官方镜像只发布 `linux/amd64`，在 Apple Silicon 上通过 Rosetta 2 模拟运行，启动略慢属正常。Docker Desktop → Settings → 开启 **Use Rosetta for x86_64/amd64 emulation**。

## 镜像拉取失败（403 / 超时）

默认 SWR 镜像偶尔有地区限制，先确认：

```bash
docker pull swr.cn-south-1.myhuaweicloud.com/jeepay/mysql:8.0.25
```

如持续失败，可临时回 Docker Hub 上游（安装前 export）：

```bash
export mysqlImage=mysql:8.0.25
export redisImage=redis:6.2.14
export rocketmqImage=apache/rocketmq:5.3.1
export nginxImage=nginx:1.18.0
export managerImage=jeepay/jeepay-manager:3.2.0
export merchantImage=jeepay/jeepay-merchant:3.2.0
export paymentImage=jeepay/jeepay-payment:3.2.0
bash install.sh
```

## 前端镜像构建失败（Docker Compose 场景）

- `jeepay-ui` 目录是否存在且在 `jeepay` 同级？
- `UI_BASE_DIR` 是否正确？
- npm 源是否可达？必要时在 `jeepay-ui` 的 Dockerfile 里切淘宝源。

## 打包排障现场给维护者

```bash
ts=$(date +%Y%m%d-%H%M%S)
out=/tmp/jeepay-debug-$ts
mkdir -p $out
docker ps -a > $out/docker-ps.txt
for c in mysql8 redis6 rocketmq-namesrv rocketmq-broker jeepaymanager jeepaymerchant jeepaypayment nginx118; do
    docker logs --tail 200 $c > $out/log-$c.txt 2>&1
    docker inspect $c > $out/inspect-$c.json 2>&1
done
docker network inspect jeepay-net > $out/network.json 2>&1
cp $(ls -t /tmp/jeepay-install-*.log | head -1) $out/install.log 2>/dev/null
tar -czf $out.tar.gz -C /tmp "$(basename $out)"
echo "已打包到：$out.tar.gz"
```

把 `.tar.gz` 发维护者，能直接定位。

---

### Jeepay Payment Src Main Resources Markdown Doc Api1 (`jeepay-payment/src/main/resources/markdown/doc/api1.md`)

# 接口规则

## 协议规则
传输方式：采用HTTP传输(生产环境建议HTTPS)   
提交方式：`POST` 或 `GET`   
内容类型：`application/json`   
字符编码：`UTF-8`   
签名算法：`MD5`   

## 参数规范
交易金额：默认为人民币交易，单位为分，参数值不能带小数。   
时间参数：所有涉及时间参数均使用精确到毫秒的13位数值，如：1622016572190。时间戳具体是指从格林尼治时间1970年01月01日00时00分00秒起至现在的毫秒数。

## 签名算法
`签名生成的通用步骤如下`

***第一步：*** 设所有发送或者接收到的数据为集合M，将集合M内非空参数值的参数按照参数名ASCII码从小到大排序（字典序），使用URL键值对的格式（即key1=value1&amp;key2=value2…）拼接成字符串stringA。
特别注意以下重要规则：   
◆ 参数名ASCII码从小到大排序（字典序）；   
◆ 如果参数的值为空不参与签名；   
◆ 参数名区分大小写；   
◆ 验证调用返回或支付中心主动通知签名时，传送的sign参数不参与签名，将生成的签名与该sign值作校验。   
◆ 支付中心接口可能增加字段，验证签名时必须支持增加的扩展字段

***第二步：*** 在stringA最后拼接上key`[即 StringA +"&key=" + 私钥 ]` 得到stringSignTemp字符串，并对stringSignTemp进行MD5运算，再将得到的字符串所有字符转换为大写，得到sign值signValue。

如请求支付系统参数如下：
```java
Map signMap = new HashMap<>();
signMap.put("platId", "1000");
signMap.put("mchOrderNo", "P0123456789101");
signMap.put("amount", "10000");
signMap.put("clientIp", "192.168.0.111");
signMap.put("returnUrl", "https://www.baidu.com");
signMap.put("notifyUrl", "https://www.baidu.com");
signMap.put("reqTime", "20190723141000");
signMap.put("version", "1.0");
```
`待签名值`： 
amount=10000&amp;clientIp=192.168.0.111&amp;mchOrderNo=P0123456789101&amp;notifyUrl=https://www.baidu.com&amp;platId=1000&amp;reqTime=20190723141000&amp;returnUrl=https://www.baidu.com&amp;version=1.0&amp;key=EWEFD123RGSRETYDFNGFGFGSHDFGH

`签名结果`：4A5078DABBCE0D9C4E7668DACB96FF7A 

`最终请求支付系统参数`：amount=10000&amp;clientIp=192.168.0.111&amp;mchOrderNo=P0123456789101&amp;notifyUrl=https://www.baidu.com&amp;platId=1000&reqTime=20190723141000&amp;returnUrl=https://www.baidu.com&amp;version=1.0&amp;sign=4A5078DABBCE0D9C4E7668DACB96FF7A

&gt; 运营管理平台可以管理商户的私钥

`提示：`签名以及接口调用，请使用jeepay官方提供的sdk：https://gitee.com/jeequan/jeepay-sdk-java

---

### Jeepay Payment Src Main Resources Markdown Doc Api2 (`jeepay-payment/src/main/resources/markdown/doc/api2.md`)

# 支付接口

## 统一下单

商户业务系统通过统一下单接口发起支付收款订单，Jeepay支付网关会根据商户配置的支付通道路由支付通道完成支付下单。支付网关根据不同的支付方式返回对应的支付参数，业务系统使用支付参数发起收款。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/pay/unifiedOrder

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的订单号  
支付方式 | wayCode | 是 | String(30) | WX_LITE | 支付方式,如微信小程序WX_LITE
支付金额 | amount | 是 | int | 100 | 支付金额,单位分  
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny  
客户端IP | clientIp | 否 | String(32) | 210.73.10.148 | 客户端IPV4地址  
商品标题 | subject | 是 | String(64) | Jeepay商品标题测试 | 商品标题  
商品描述 | body | 是 | String(256) | Jeepay商品描述测试 | 商品描述  
异步通知地址 | notifyUrl | 否 | String(128) | https://www.jeequan.com/notify.htm | 支付结果异步回调URL,只有传了该值才会发起回调  
跳转通知地址 | returnUrl | 否 | String(128) | https://www.jeequan.com/return.htm | 支付结果同步跳转通知URL
失效时间 | expiredTime | 否 | int | 3600 | 订单失效时间,单位秒,默认2小时.订单在(创建时间+失效时间)后失效   
渠道参数 | channelExtra | 否 | String(256 | {"auth_code", "13920933111042"} | 特定渠道发起的额外参数,json格式字符串.详见渠道参数说明  
分账模式 | divisionMode | 否 | int | 0 | 分账模式： 0-该笔订单不允许分账[默认], 1-支付成功按配置自动完成分账, 2-商户手动分账(解冻商户金额)  
扩展参数 | extParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳   
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式  


`请求示例数据`

```json
{
  "amount": 8,
  "extParam": "",
  "mchOrderNo": "mho1624005107281",
  "subject": "商品标题",
  "wayCode": "ALI_BAR",
  "sign": "84F606FA25A6EC4783BECC08D4FDC681",
  "reqTime": "1624005107",
  "body": "商品描述",
  "version": "1.0",
  "channelExtra": "{\"authCode\":\"280812820366966512\"}",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "clientIp": "192.166.1.132",
  "notifyUrl": "https://www.jeequan.com",
  "signType": "MD5",
  "currency": "cny",
  "returnUrl": "",
  "mchNo": "M1623984572",
  "divisionMode": 1
}
```

> 返回参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
支付订单号 | payOrderId | 是 | String(30) | U12021022311124442600 | 返回支付系统订单号  
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 返回商户传入的订单号  
订单状态 | orderState | 是 | int | 2 | 支付订单状态<br>0-订单生成<br>1-支付中<br>2-支付成功<br>3-支付失败<br>4-已撤销<br>5-已退款<br>6-订单关闭  
支付数据类型 | payDataType | 是 | String | payUrl | 支付参数类型<br>payUrl-跳转链接的方式<br>form-表单方式<br>wxapp-微信支付参数(微信公众号,小程序,app支付时)<br>aliapp-支付宝app支付参数<br>ysfapp-云闪付app支付参数<br>codeUrl-二维码地址<br>codeImgUrl-二维码图片地址<br>none-空支付参数 
支付数据 | payData | 否 | String | http://www.jeequan.com/pay.html | 发起支付用到的支付参数，如果微信公众号支付等 
渠道错误码 | errCode | 否 | String | ACQ.PAYMENT_AUTH_CODE_INVALID | 上游渠道返回的错误码
渠道错误描述 | errMsg | 否 | String | Business Failed 失败 | 上游渠道返回的错误描述

`返回示例数据`

```json
{
  "code": 0,
  "data": {
    "errCode": "ACQ.PAYMENT_AUTH_CODE_INVALID",
    "errMsg": "Business Failed【支付失败，获取顾客账户信息失败，请顾客刷新付款码后重新收款，如再次收款失败，请联系管理员处理。[SOUNDWAVE_PARSER_FAIL]】",
    "mchOrderNo": "mho1624005752661",
    "orderState": 3,
    "payOrderId": "P202106181642329900002"
  },
  "msg": "SUCCESS",
  "sign": "F4DA202C516D1F33A12F1E547C5004FD"
}
```

> 支付方式

WayCode | 支付方式 
------- | ------- 
QR_CASHIER | 聚合扫码(用户扫商家) 
AUTO_BAR | 聚合条码(商家扫用户) 
ALI_BAR | 支付宝条码 
ALI_JSAPI | 支付宝生活号
ALI_APP | 支付宝APP 
ALI_WAP | 支付宝WAP 
ALI_PC | 支付宝PC网站 
ALI_QR | 支付宝二维码 
WX_BAR | 微信条码
WX_JSAPI | 微信公众号 
WX_LITE | 微信小程序 
WX_APP | 微信APP 
WX_H5 | 微信H5 
WX_NATIVE | 微信扫码
YSF_BAR | 云闪付条码 
YSF_JSAPI | 云闪付jsapi 

> channelExtra参数说明

当 `wayCode=AUTO_BAR` 或 `wayCode=ALI_BAR` 或  `wayCode=WX_BAR` 或  `wayCode=YSF_BAR` 时，channelExtra必须传auth_code，为用户的付款码值，channelExtra示例数据如：
```json
{"auth_code": "13920933111042"}
```

当 `wayCode=ALI_JSAPI` 时，channelExtra必须传buyerUserId，为支付宝用户ID，channelExtra示例数据如：
```json
{"buyerUserId": "2088702585070844"}
```

当 `wayCode=WX_JSAPI` 或 `wayCode=WX_LITE` 时，channelExtra必须传openid，channelExtra示例数据如：
```json
{"openid": "o6BcIwvSiRpfS8e_UyfQNrYuk2LI"}
```

当 `wayCode=QR_CASHIER` 或 `wayCode=ALI_QR` 或  `wayCode=WX_NATIVE` 时，channelExtra可以传payDataType设置返回支付数据支付类型。此时payDataType可以为：codeUrl-二维码地址,codeImgUrl-二维码图片地址，不传payDataType默认返回codeUrl类型, channelExtra示例数据如：
```json
{"payDataType": "codeImgUrl"}
```

当 `wayCode=ALI_WAP` 时，channelExtra可以传payDataType设置返回支付数据支付类型。此时payDataType可以为：form-返回自动跳转的支付表单,codeImgUrl-返回一个二维码图片URL,payUrl-返回支付链接，不传payDataType默认返回payUrl类型, channelExtra示例数据如：
```json
{"payDataType": "form"}
```

当 `wayCode=ALI_PC` 时，channelExtra可以传payDataType设置返回支付数据支付类型。此时payDataType可以为：form-返回自动跳转的支付表单,payUrl-返回支付链接，不传payDataType默认返回payUrl类型, channelExtra示例数据如：
```json
{"payDataType": "form"}
```


## 查询订单

商户通过该接口查询订单，支付网关会返回订单最新的数据

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/pay/query

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
支付订单号 | payOrderId | 是 | String(30) | P20160427210604000490 | 支付中心生成的订单号，与mchOrderNo二者传一即可  
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的订单号，与payOrderId二者传一即可  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
  "payOrderId": "P202106181104177050002",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "sign": "46940C58B2F3AE426B77A297ABF4D31E",
  "signType": "MD5",
  "reqTime": "1624006009",
  "mchNo": "M1623984572",
  "version": "1.0"
}
```

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
支付订单号 | payOrderId | 是 | String(30) | P12021022311124442600 | 返回支付系统订单号
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 返回商户传入的订单号  
支付接口 | ifCode | 是 | String(30) | wxpay | 支付接口编码   
支付方式 | wayCode | 是 | String(30) | WX_LITE | 支付方式,如微信小程序WX_LITE   
支付金额 | amount | 是 | int | 100 | 支付金额,单位分  
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny  
订单状态 | state | 是 | int | 2 | 支付订单状态<br>0-订单生成<br>1-支付中<br>2-支付成功<br>3-支付失败<br>4-已撤销<br>5-已退款<br>6-订单关闭  
客户端IP | clientIp | 否 | String(32) | 210.73.10.148 | 客户端IPV4地址  
商品标题 | subject | 是 | String(64) | Jeepay商品标题测试 | 商品标题  
商品描述 | body | 是 | String(256) | Jeepay商品描述测试 | 商品描述  
渠道订单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的订单号  
渠道错误码 | errCode | 否 | String | 1002 | 渠道下单返回错误码
渠道错误描述 | errMsg | 否 | String | 业务异常错误 | 渠道下单返回错误描述
扩展参数 | extParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 订单支付成功时间,13位时间戳  

`返回示例数据`

```json
{
  "code": 0,
  "data": {
    "amount": 58,
    "appId": "60cc09bce4b0f1c0b83761c9",
    "body": "商品描述",
    "channelOrderNo": "2021061822001423031419593035",
    "clientIp": "192.166.1.132",
    "createdAt": 1623985457705,
    "currency": "cny",
    "extParam": "",
    "ifCode": "alipay",
    "mchNo": "M1623984572",
    "mchOrderNo": "mho1623985457320",
    "payOrderId": "P202106181104177050002",
    "state": 2,
    "subject": "商品标题",
    "successTime": 1623985459000,
    "wayCode": "ALI_BAR"
  },
  "msg": "SUCCESS",
  "sign": "9548145EA12D0CD8C1628BCF44E19E0D"
}
```

## 关闭订单

商户通过该接口关闭订单，支付网关会对订单完成关闭处理。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/pay/close

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
支付订单号 | payOrderId | 是 | String(30) | P20160427210604000490 | 支付中心生成的订单号，与mchOrderNo二者传一即可  
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的订单号，与payOrderId二者传一即可  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
  "payOrderId": "P202106181104177050002",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "sign": "46940C58B2F3AE426B77A297ABF4D31E",
  "signType": "MD5",
  "reqTime": "1624006009",
  "mchNo": "M1623984572",
  "version": "1.0"
}
```

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
渠道错误码 | errCode | 否 | String | 1002 | 渠道关单返回错误码
渠道错误描述 | errMsg | 否 | String | 关闭异常 | 渠道关单返回错误描述

`返回示例数据`

```json
{
  "code": 0,
  "data": {
    "errCode": '',
    "errMsg": ''
  },
  "msg": "SUCCESS",
  "sign": "9548145EA12D0CD8C1628BCF44E19E0D"
}
```

## 支付通知

当订单支付成功时，支付网关会向商户系统发起回调通知。如果商户系统没有正确返回，支付网关会延迟再次通知。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：该链接是通过统一下单接口提交的参数notifyUrl设置，如果无法访问链接，商户系统将无法接收到支付中心的通知。

请求方式：`POST`

请求类型：`application/x-www-form-urlencoded`

> 通知参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
支付订单号 | payOrderId | 是 | String(30) | P12021022311124442600 | 返回支付系统订单号
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 返回商户传入的订单号  
支付接口 | ifCode | 是 | String(30) | wxpay | 支付接口编码   
支付方式 | wayCode | 是 | String(30) | WX_LITE | 支付方式,微信小程序WX_LITE   
支付金额 | amount | 是 | int | 100 | 支付金额,单位分  
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny  
订单状态 | state | 是 | int | 2 | 支付订单状态<br>0-订单生成<br>1-支付中<br>2-支付成功<br>3-支付失败<br>4-已撤销<br>5-已退款<br>6-订单关闭  
客户端IP | clientIp | 否 | String(32) | 210.73.10.148 | 客户端IPV4地址  
商品标题 | subject | 是 | String(64) | Jeepay商品标题测试 | 商品标题  
商品描述 | body | 是 | String(256) | Jeepay商品描述测试 | 商品描述  
渠道订单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的订单号  
渠道错误码 | errCode | 否 | String | 1002 | 渠道下单返回错误码
渠道错误描述 | errMsg | 否 | String | 134586944573118714 | 渠道下单返回错误描述
扩展参数 | extParam | 否 | String(512) | 134586944573118714 | 商户扩展参数
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 订单支付成功时间,13位时间戳  
通知请求时间 | reqTime | 是 | String(30) | 1622016572190 | 通知请求时间，,13位时间戳  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  

&gt; 返回结果

业务系统处理后同步返回给支付中心，返回字符串 success 则表示成功，返回非success则表示处理失败，支付中心会再次通知业务系统。（通知频率为0/30/60/90/120/150,单位：秒）

`注意：返回的字符串必须是小写，且前后不能有空格和换行符。`

`通知示例数据`

```json
{
    "amount": 5,
    "body": "商品描述",
    "clientIp": "192.166.1.132",
    "createdAt": "1622016572190",
    "currency": "cny",
    "extParam": "",
    "ifCode": "wxpay",
    "mchNo": "M1621873433953",
    "appId": "60cc09bce4b0f1c0b83761c9",
    "mchOrderNo": "mho1621934803068",
    "payOrderId": "20210525172643357010",
    "state": 3,
    "subject": "商品标题",
    "wayCode": "WX_BAR",
    "sign": "C380BEC2BFD727A4B6845133519F3AD6"
}
```

## 获取渠道用户ID

商户通过该接口获取渠道的用户ID，如微信的openID，支付宝的userId。该接口通过跳转获取到用户ID后，会跳转到商户上传的redirectUrl地址，并传递用户ID参数

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/channelUserId/jump

请求方式：`GET`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
支付接口 | ifCode | 是 | String(30) | AUTO | 目前只支持传 AUTO   
跳转地址 | redirectUrl | 是 | String | https://www.jeequan.com | 获取到用户ID后，会携带用户ID参数跳转到该地址  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
  "mchNo": "M1621873433953",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "ifCode": "wxpay",
  "redirectUrl": "https://www.jeequan.com",
  "sign": "A5C93D50743126ED91AA6ED96CDEEEF8",
  "signType": "MD5",
  "reqTime": "1622011236571",
  "version": "1.0"
}
```

`当获取到渠道用户ID后，会301重定向到跳转地址，传递参数如下`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
渠道用户ID | channelUserId | 是 | String | o6BcIwvSiRpfS8e_UyfQNrYuk2LI | 渠道用户ID，微信openId或支付宝userId

`完整跳转URL示例`

```html
https://www.jeequan.com/toU?channelUserId=o6BcIwvSiRpfS8e_UyfQNrYuk2LI
```

## 返回码

code | 描述 
------- | -------
0 | 成功 
9999 | 异常，具体错误详见msg字段

---

### Jeepay Payment Src Main Resources Markdown Doc Api3 (`jeepay-payment/src/main/resources/markdown/doc/api3.md`)

# 退款接口

## 统一退款

商户业务系统通过统一退款接口发起退款请求，Jeepay支付网关会根据商户发起的支付订单号，找到对应到支付通道发起退款。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/refund/refundOrder

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
支付订单号 | payOrderId | 是 | String(30) | P20160427210604000490 | 支付中心生成的订单号，与mchOrderNo二者传一即可  
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的支付订单号，与payOrderId二者传一即可  
商户退款单号 | mchRefundNo | 是 | String(30) | M27210632100491 | 商户生成的退款单号  
退款金额 | refundAmount | 是 | int | 100 | 退款金额,单位分   
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
退款原因 | refundReason | 是 | String(64) | 用户退货 | 退款原因  
客户端IP | clientIp | 否 | String(32) | 210.73.10.148 | 客户端IPV4地址  
异步通知地址 | notifyUrl | 否 | String(128) | https://www.jeequan.com/notify.htm | 退款完成后回调该URL,只有传了该值才会发起回调  
渠道参数 | channelExtra | 否 | String(256 | {"auth_code", "13920933111042"} | 特定渠道发起的额外参数,json格式字符串.详见渠道参数说明  
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳   
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式  


`请求示例数据`

```json
{
  "payOrderId": "P202106181104177050002",
  "extParam": "",
  "mchOrderNo": "",
  "refundReason": "退款测试",
  "sign": "2762CDB48D5179281DB6C0995E4EEDE0",
  "reqTime": "1624007315",
  "version": "1.0",
  "channelExtra": "",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "mchRefundNo": "mho1624007315478",
  "clientIp": "192.166.1.132",
  "notifyUrl": "https://www.jeequan.com",
  "signType": "MD5",
  "currency": "cny",
  "mchNo": "M1623984572",
  "refundAmount": 4
}
```

> 返回参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
退款订单号 | refundOrderId | 是 | String(30) | R202106181708358940000 | 返回退款订单号  
商户退款单号 | mchRefundNo | 是 | String(30) | mho1624007315478 | 返回商户传入的退款单号  
退款状态 | state | 是 | int | 2 | 退款状态<br>0-订单生成<br>1-退款中<br>2-退款成功<br>3-退款失败<br>4-退款关闭  
渠道退款单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的退款单号   
渠道错误码 | errCode | 否 | String | ACQ.PAYMENT_AUTH_CODE_INVALID | 上游渠道返回的错误码
渠道错误描述 | errMsg | 否 | String | Business Failed 失败 | 上游渠道返回的错误描述

`返回示例数据`

```json
{
  "code": 0,
  "data": {
    "channelOrderNo": "2021061822001423031419593035",
    "mchRefundNo": "mho1624007315478",
    "payAmount": 58,
    "refundAmount": 4,
    "refundOrderId": "R202106181708358940000",
    "state": 2
  },
  "msg": "SUCCESS",
  "sign": "2843B811B7A75D56B7D1950362820875"
}
```

## 查询订单

商户通过该接口查询退款订单，支付网关会返回订单最新的数据

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/refund/query

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
退款订单号 | refundOrderId | 是 | String(30) | R20160427210604000490 | 支付中心生成的退款单号，与mchRefundNo二者传一即可  
商户退款单号 | mchRefundNo | 是 | String(30) | 20160427210604000490 | 商户生成的退款单号，与refundOrderId二者传一即可  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
  "refundOrderId": "P202106181105527690009",
  "appId": "60cc09bce4b0f1c0b83761c9",
  "sign": "1484293FCAEAFE11DEC8949DB6B525A9",
  "signType": "MD5",
  "reqTime": "1624008199",
  "mchNo": "M1623984572",
  "version": "1.0"
}
```

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
退款订单号 | refundOrderId | 是 | String(30) | R20160427210604000490 | 支付中心生成的退款单号  
支付订单号 | payOrderId | 是 | String(30) | P12021022311124442600 | 返回支付系统订单号
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户退款单号 | mchRefundNo | 是 | String(30) | 20160427210604000490 | 商户生成的退款单号
支付金额 | payAmount | 是 | int | 100 | 支付金额,单位分 
退款金额 | refundAmount | 是 | int | 100 | 退款金额,单位分 
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
退款状态 | state | 是 | int | 2 | 退款状态<br>0-订单生成<br>1-退款中<br>2-退款成功<br>3-退款失败<br>4-退款关闭  
渠道订单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的订单号  
渠道错误码 | errCode | 否 | String | 1002 | 渠道返回错误码
渠道错误描述 | errMsg | 否 | String | 134586944573118714 | 渠道返回错误描述
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 订单支付成功时间,13位时间戳  

`返回示例数据`

```json
{
  "code": 0,
  "data": {
    "appId": "60cc09bce4b0f1c0b83761c9",
    "channelOrderNo": "2021061822001423031419593035",
    "createdAt": 1623985552769,
    "currency": "cny",
    "extParam": "",
    "mchNo": "M1623984572",
    "mchRefundNo": "mho1623985552430",
    "payAmount": 58,
    "payOrderId": "P202106181104177050002",
    "refundAmount": 4,
    "refundOrderId": "P202106181105527690009",
    "state": 2,
    "successTime": 1623985554000
  },
  "msg": "SUCCESS",
  "sign": "E3F9F008FC5EF84BD782CCC7BE69DC5E"
}
```

## 退款通知

当退款完成时(成功或失败)，支付网关会向商户系统发起回调通知。如果商户系统没有正确返回，支付网关会延迟再次通知。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：该链接是通过统一退款接口提交的参数notifyUrl设置，如果无法访问链接，商户系统将无法接收到支付中心的通知。

请求方式：`POST`

请求类型：`application/x-www-form-urlencoded`

> 通知参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
退款订单号 | refundOrderId | 是 | String(30) | R20160427210604000490 | 支付中心生成的退款单号  
支付订单号 | payOrderId | 是 | String(30) | P12021022311124442600 | 返回支付系统订单号
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户退款单号 | mchRefundNo | 是 | String(30) | 20160427210604000490 | 商户生成的退款单号
支付金额 | payAmount | 是 | int | 100 | 支付金额,单位分 
退款金额 | refundAmount | 是 | int | 100 | 退款金额,单位分 
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
退款状态 | state | 是 | int | 2 | 退款状态<br>0-订单生成<br>1-退款中<br>2-退款成功<br>3-退款失败<br>4-退款关闭  
渠道订单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的订单号  
渠道错误码 | errCode | 否 | String | 1002 | 渠道返回错误码
渠道错误描述 | errMsg | 否 | String | 134586944573118714 | 渠道返回错误描述
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 订单支付成功时间,13位时间戳  
通知请求时间 | reqTime | 是 | String(30) | 1622016572190 | 通知请求时间，,13位时间戳  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  

&gt; 返回结果

业务系统处理后同步返回给支付中心，返回字符串 success 则表示成功，返回非success则表示处理失败，支付中心会再次通知业务系统。（通知频率为0/30/60/90/120/150,单位：秒）

`注意：返回的字符串必须是小写，且前后不能有空格和换行符。`

`通知示例数据`

```json
{
    "appId": "60cc09bce4b0f1c0b83761c9",
    "channelOrderNo": "2021061822001423031419593035",
    "createdAt": 1623985552769,
    "currency": "cny",
    "extParam": "",
    "mchNo": "M1623984572",
    "mchRefundNo": "mho1623985552430",
    "payAmount": 58,
    "payOrderId": "P202106181104177050002",
    "refundAmount": 4,
    "refundOrderId": "P202106181105527690009",
    "state": 2,
    "successTime": 1623985554000
}
```

---

### Jeepay Payment Src Main Resources Markdown Doc Api4 (`jeepay-payment/src/main/resources/markdown/doc/api4.md`)

# 转账接口

## 发起转账

商户业务系统通过转账接口发起转账申请，Jeepay支付网关将根据请求数据传入到对应的上游接口。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/transferOrder

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的转账订单号
接口代码 | ifCode | 是 | String(10) | wxpay | wxpay-微信官方接口 ; alipay-支付宝官方接口
入账方式 | entryType | 是 | String(20) | 20160427210604000490 | 入账方式： WX_CASH-微信零钱; ALIPAY_CASH-支付宝转账; BANK_CARD-银行卡
转账金额 | amount | 是 | int | 100 | 转账金额,单位分   
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
收款账号 | accountNo | 是 | String(64) | o6BcIwvTvIqf1zXZohc61biryWik | wxpay-openID, alipay-登录账号  
收款人姓名 | accountName | 否 | String(64) | 张三 | 填入则验证姓名，否则不验证
收款人开户行名称 | bankName | 否 | String(64) | 中国工商银行 | 当前仅作为记录
客户端IP | clientIp | 否 | String(32) | 210.73.10.148 | 客户端IPV4地址  
转账备注信息 | transferDesc | 否 | String(128) | 测试转账 | 转账备注信息
异步通知地址 | notifyUrl | 否 | String(128) | https://www.jeequan.com/notify.htm | 转账完成后回调该URL,只有传了该值才会发起回调
渠道参数 | channelExtra | 否 | String(256 | {} | 特定渠道发起的额外参数,json格式字符串
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳   
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式  


`请求示例数据`

```json
{"ifCode":"wxpay",
"entryType":"WX_CASH",
"amount":1,
"accountName":"",
"mchOrderNo":"mho1629106169045",
"sign":"3EB5A3B81E92DB41677E235363E7DDE3",
"transferDesc":"测试转账",
"reqTime":"1629106169",
"version":"1.0",
"appId":"60cc3ba74ee0e6685f57eb1e",
"accountNo":"a6BcIwtTvIqv1zXZohc61biryWok",
"clientIp":"192.166.1.132",
"signType":"MD5",
"currency":"CNY",
"mchNo":"M1623997351"
}
```

> 返回参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
转账订单号 | transferId | 是 | String(30) | T202108161731281310004 | 返回转账订单号  
商户转账单号 | mchOrderNo | 是 | String(30) | mho1624007315478 | 返回商户传入的转账单号  
转账状态 | state | 是 | int | 2 | 转账状态<br>0-订单生成<br>1-转账中<br>2-转账成功<br>3-转账失败<br>4-转账关闭  
渠道转账单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的转账单号   
渠道错误码 | errCode | 否 | String | ACQ.PAYMENT_AUTH_CODE_INVALID | 上游渠道返回的错误码
渠道错误描述 | errMsg | 否 | String | Business Failed 失败 | 上游渠道返回的错误描述

`返回示例数据`

```json
{
    "code": 0,
    "data": {
        "accountNo": "1",
        "amount": 11,
        "channelOrderNo": "20210816110070001506260000372216",
        "mchOrderNo": "1629106288",
        "state": 2,
        "transferId": "T202108161731281310004"
    },
    "msg": "SUCCESS",
    "sign": "195BF6F112386F7FC8EA2AA7EECA1D33"
}
```

## 查询订单

商户通过该接口查询转账订单，支付网关会返回订单最新的数据

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/transfer/query

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
转账订单号 | transferId | 是 | String(30) | T20160427210604000490 | 支付中心生成的转账单号，与mchOrderNo二者传一即可  
商户转账单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的转账单号，与transferId二者传一即可  
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
"appId":"60cc3ba74ee0e6685f57eb1e",
"sign":"D3C0CC231F3FC3D033650699BA099B39",
"signType":"MD5",
"reqTime":"1629106457",
"transferId":"T202108121543441860003",
"mchNo":"M1623997351",
"version":"1.0"
}
```

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的转账订单号
转账订单号 | transferId | 是 | String(30) | T20160427210604000490 | 支付中心生成的转账单号
转账金额 | amount | 是 | int | 100 | 转账金额,单位分   
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
接口代码 | ifCode | 是 | String(10) | wxpay | wxpay-微信官方接口 ; alipay-支付宝官方接口
入账方式 | entryType | 是 | String(20) | 20160427210604000490 | 入账方式： WX_CASH-微信零钱; ALIPAY_CASH-支付宝转账; BANK_CARD-银行卡
转账状态 | state | 是 | int | 2 | 转账状态<br>0-订单生成<br>1-转账中<br>2-转账成功<br>3-转账失败<br>4-转账关闭 
收款账号 | accountNo | 是 | String(64) | o6BcIwvTvIqf1zXZohc61biryWik | wxpay-openID, alipay-登录账号  
收款人姓名 | accountName | 否 | String(64) | 张三 | 填入则验证姓名，否则不验证
收款人开户行名称 | bankName | 否 | String(64) | 中国工商银行 | 当前仅作为记录
转账备注信息 | transferDesc | 否 | String(128) | 测试转账 | 转账备注信息
渠道转账单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的转账单号 
渠道错误码 | errCode | 否 | String | 1002 | 渠道返回错误码
渠道错误描述 | errMsg | 否 | String | 134586944573118714 | 渠道返回错误描述
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 转账成功时间,13位时间戳  


`返回示例数据`

```json
{
    "code": 0,
    "data": {
        "accountNo": "o6BcIwvTvIqf1zXZohc61biryWik",
        "amount": 1,
        "appId": "6113805e42020495c62bd4cb",
        "createdAt": 1628818820011,
        "currency": "CNY",
        "entryType": "WX_CASH",
        "errCode": "OPENID_ERROR",
        "errMsg": "openid与商户appid不匹配【openid与商户appid不匹配】",
        "ifCode": "wxpay",
        "mchNo": "M1623997351",
        "mchOrderNo": "1628818820",
        "state": 3,
        "transferDesc": "测试",
        "transferId": "T202108130940200100001"
    },
    "msg": "SUCCESS",
    "sign": "A262DBD3D6182E8A0AEC90EF820F2A5A"
}
```

## 转账通知

当转账完成时(成功或失败)，支付网关会向商户系统发起回调通知。如果商户系统没有正确返回，支付网关会延迟再次通知。

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：该链接是通过转账申请接口提交的参数notifyUrl设置，如果无法访问链接，商户系统将无法接收到支付中心的通知。

请求方式：`POST`

请求类型：`application/x-www-form-urlencoded`

> 通知参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
商户订单号 | mchOrderNo | 是 | String(30) | 20160427210604000490 | 商户生成的转账订单号
转账订单号 | transferId | 是 | String(30) | T20160427210604000490 | 支付中心生成的转账单号
转账金额 | amount | 是 | int | 100 | 转账金额,单位分   
货币代码 | currency | 是 | String(3) | cny | 三位货币代码,人民币:cny
接口代码 | ifCode | 是 | String(10) | wxpay | wxpay-微信官方接口 ; alipay-支付宝官方接口
入账方式 | entryType | 是 | String(20) | 20160427210604000490 | 入账方式： WX_CASH-微信零钱; ALIPAY_CASH-支付宝转账; BANK_CARD-银行卡
转账状态 | state | 是 | int | 2 | 转账状态<br>0-订单生成<br>1-转账中<br>2-转账成功<br>3-转账失败<br>4-转账关闭 
收款账号 | accountNo | 是 | String(64) | o6BcIwvTvIqf1zXZohc61biryWik | wxpay-openID, alipay-登录账号  
收款人姓名 | accountName | 否 | String(64) | 张三 | 填入则验证姓名，否则不验证
收款人开户行名称 | bankName | 否 | String(64) | 中国工商银行 | 当前仅作为记录
转账备注信息 | transferDesc | 否 | String(128) | 测试转账 | 转账备注信息
渠道转账单号 | channelOrderNo | 否 | String | 20160427210604000490 | 对应渠道的转账单号 
渠道错误码 | errCode | 否 | String | 1002 | 渠道返回错误码
渠道错误描述 | errMsg | 否 | String | 134586944573118714 | 渠道返回错误描述
扩展参数 | extraParam | 否 | String(512) | 134586944573118714 | 商户扩展参数,回调时会原样返回  
创建时间 | createdAt | 是 | long | 1622016572190 | 订单创建时间,13位时间戳  
成功时间 | successTime | 否 | long | 1622016572190 | 转账成功时间,13位时间戳  

&gt; 返回结果

业务系统处理后同步返回给支付中心，返回字符串 success 则表示成功，返回非success则表示处理失败，支付中心会再次通知业务系统。（通知频率为0/30/60/90/120/150,单位：秒）

`注意：返回的字符串必须是小写，且前后不能有空格和换行符。`

`通知示例数据`

```json
 {
        "accountNo": "o6BcIwvTvIqf1zXZohc61biryWik",
        "amount": 1,
        "appId": "6113805e42020495c62bd4cb",
        "createdAt": 1628818820011,
        "currency": "CNY",
        "entryType": "WX_CASH",
        "errCode": "OPENID_ERROR",
        "errMsg": "openid与商户appid不匹配【openid与商户appid不匹配】",
        "ifCode": "wxpay",
        "mchNo": "M1623997351",
        "mchOrderNo": "1628818820",
        "state": 3,
        "transferDesc": "测试",
        "transferId": "T202108130940200100001"
    }
```

---

### Jeepay Payment Src Main Resources Markdown Doc Api5 (`jeepay-payment/src/main/resources/markdown/doc/api5.md`)

# 分账接口

## 分账业务

> 业务介绍：商户分账主要用于商户将交易成功的资金，按照一定的周期，分账给其他方，可以是合作伙伴、员工、用户或者其他分润方。

参考微信文档： 



微信分账：https://pay.weixin.qq.com/wiki/doc/api/allocation.php?chapter=26_1
支付宝分账： https://opendocs.alipay.com/open/20190308105425129272/intro


接口目录： 

## 绑定分账用户

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/division/receiver/bind

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号   
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
接口代码 | ifCode | 是 | String(10) | wxpay | wxpay-微信官方接口 ; alipay-支付宝官方接口
接收者账号别名 | receiverAlias | 是 | String(64) | 张三 | 接收者账号别名
组ID | receiverGroupId | 是 | long | 10001 | 需先登录商户系统查找待加入的组ID
分账接收账号类型 | accType | 是 | int | 1 | 分账接收账号类型: 0-个人(对私) 1-商户(对公)
分账接收账号 | accNo | 是 | String(10) | 1231312@qq.com | 分账接收账号, 微信个人是openid, 支付宝可以是userId或登录名
分账接收账号名称 | accName | 否 | String(30) | 张三 | 微信选填（当填入则验证），支付宝账号必填
分账关系类型 | relationType | 是 | String(30) | wxpay | 分账关系类型：<br/>SERVICE_PROVIDER：服务商 <br/>STORE：门店<br/>STAFF：员工<br/>STORE_OWNER：店主<br/>PARTNER：合作伙伴<br/>HEADQUARTER：总部<br/>BRAND：品牌方<br/>DISTRIBUTOR：分销商<br/>USER：用户<br/>SUPPLIER：供应商<br/>CUSTOM：自定义
分账关系类型名称 | relationTypeName | 否 | String(30) | wxpay | 当relationType=CUSTOM 必填
渠道特殊信息 | channelExtInfo | 否 | String(256) | wxpay | 渠道特殊信息
默认分账比例 | divisionProfit | 是 | String(10) | wxpay | 若分账30% 则填入 0.3
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳   
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式  


`请求示例数据`

```json
{
 'version': '1.0',
'reqTime': '1622016572190',
'signType': 'MD5',
'sign': 'MD5MD5MD5MD5MD5MD5MD5MD5MD5MD5MD5MD5',
'mchNo': 'M1623997000',
'appId': '60cc3ba74ee0e6685f57e000',
'ifCode': 'wxpay',
'receiverAlias': '我的第一个账号',
'receiverGroupId': '100001',
'accType': '0',
'accNo': 'sfsfsd@qq.com',
'accName': '张三',
'relationType': 'OTHERS',
'relationTypeName': '我的员工',
'divisionProfit': '0.3' 
}
```

> 返回参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
绑定账号ID | receiverId | 是 | long | 10001 | 绑定账号ID, 订单分账将使用该ID
接收者账号别名 | receiverAlias | 是 | String(64) | 张三 | 接收者账号别名
组ID | receiverGroupId | 是 | long | 10001 | 组ID
分账接收账号类型 | accType | 是 | int | 1 | 分账接收账号类型: 0-个人(对私) 1-商户(对公)
分账接收账号 | accNo | 是 | String(10) | 1231312@qq.com | 分账接收账号
分账接收账号名称 | accName | 否 | String(30) | 张三 | 分账接收账号名称
分账关系类型 | relationType | 是 | String(30) | wxpay | 分账关系类型
渠道特殊信息 | channelExtInfo | 否 | String(256) | wxpay | 渠道特殊信息
默认分账比例 | divisionProfit | 是 | String(10) | wxpay | 默认分账比例
绑定成功时间 | bindSuccessTime | 是 | Long | 1622016572190 | 绑定成功时间
绑定状态 | bindState | 是 | int | 1 | 绑定状态 1-绑定成功, 0-绑定异常 
渠道错误码 | errCode | 否 | String | ACQ.PAYMENT_AUTH_CODE_INVALID | 上游渠道返回的错误码
渠道错误描述 | errMsg | 否 | String | Business Failed 失败 | 上游渠道返回的错误描述

`返回示例数据`

```json
{
    "code": 0,
    "data": {
        "accName": "张三",
        "accNo": "sfsfsd@qq.com",
        "accType": 0,
        "appId": "60cc3ba74ee0e6685f57eb1e",
        "bindState": 0,
        "divisionProfit": 0.3,
        "errCode": "NOAUTH",
        "errMsg": "无分账权限",
        "ifCode": "wxpay",
        "mchNo": "M1623997351",
        "receiverAlias": "我的第一个账号",
        "receiverGroupId": 100001,
        "relationType": "OTHERS",
        "relationTypeName": "我的员工"
    },
    "msg": "SUCCESS",
    "sign": "552CB91FA1E1DB378A534B377E4E9403"
}
```

## 发起订单分账

当订单下单时传入的分账模式  divisionMode = 2商户手动分账(解冻商户金额)，支持商户手动发起订单分账。<br>注意：需要在订单支付完成后（建议1分钟后）调用分账接口。 

> 接口说明

适用对象：`普通商户` `特约商户`

请求URL：https://pay.jeepay.vip/api/division/exec

请求方式：`POST`

请求类型：`application/json` 或 `application/x-www-form-urlencoded`

> 请求参数

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 
应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID
支付订单号 | payOrderId | 否 | String(30) | P20160427210604000490 | 支付中心生成的支付订单号，与mchOrderNo二者传一即可  
商户单号 | mchOrderNo | 否 | String(30) | 20160427210604000490 | 商户生成的支付单号，与payOrderId二者传一即可  
是否使用系统配置的自动分账组 | useSysAutoDivisionReceivers | 是 | int | 1 | 是否使用系统配置的自动分账组： 0-否 1-是
分账接收者账号列表 | receivers | 否 | String(512) | [] |  接收者账号列表（JSONArray 转换为字符串类型）<br/>仅当useSysAutoDivisionReceivers=0 时该字段值有效。<br/>参考：<br/>方式1： 按账号纬度<br/>[{<br/>receiverId: 800001,<br/>divisionProfit: 0.1 (若不填入则使用系统默认配置值)<br/>}]<br/>方式2： 按组纬度<br/>[{<br/>receiverGroupId: 100001, (该组所有 当前订单的渠道账号并且可用状态的全部参与分账)<br/>divisionProfit: 0.1 (每个账号的分账比例， 若不填入则使用系统默认配置值， 建议不填写)<br/>}]
请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳  
接口版本 | version | 是 | String(3) | 1.0 | 接口版本号，固定：1.0  
签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值，详见签名算法  
签名类型 | signType | 是 | String(32) | MD5 | 签名类型，目前只支持MD5方式 

`请求示例数据`

```json
{
 'version': '1.0',
'reqTime': '1622016572190',
'signType': 'MD5',
'sign': '1',
'mchNo': 'M1623997351',
'appId': '60cc3ba74ee0e6685f57eb1e',
'payOrderId': 'P202108271011463510002',
'useSysAutoDivisionReceivers': '0',
'receivers': '[{"receiverGroupId":"","receiverId":"800029","divisionProfit":"0.0001"},{"receiverGroupId":"","receiverId":"800028","divisionProfit":"0.0002"}]' 
}
```

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
返回状态 | code | 是 | int | 0 | 0-处理成功，其他-处理有误，详见错误码  
返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因，例如：签名失败、参数格式校验错误  
签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名,如data为空则不返回
返回数据 | data | 否 | String(512) | {} | 返回下单数据,json格式数据  

`data数据格式`

字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述
------- | -------| -------| -------| -------| -------
分账状态 | state | 是 | int | 2 | 分账状态 1-分账成功, 2-分账失败
上游分账批次号 | channelBatchOrderId | 否 | String(30) | T20160427210604000490 | 上游分账批次号
渠道错误码 | errCode | 否 | String | 1002 | 渠道返回错误码
渠道错误描述 | errMsg | 否 | String | ERROR | 渠道返回错误描述


`返回示例数据`

```json
{
    "code": 0,
    "data": {
        "errCode": "unknown-sub-code",
        "errMsg": "Business Failed【未知的错误码ACQ.ROYALTY_ACCOUNT_NOT_EXIST】",
        "state": 2
    },
    "msg": "SUCCESS",
    "sign": "56836E18015DD7E4FAFE45380C0AD098"
}
```

---

--- METRICS ---
- Files Extracted: 14
- Estimated Token Budget: ~15945 tokens
- Canonical Reference: https://codewiki.google/github.com/jeequan/jeepay
