# business-pay 通用支付模块

## 模块说明

本模块已从 **Beetl 服务端页面 + 内嵌 Vue** 改造为 **前后分离** 架构：

| 层级 | 路径 | 说明 |
|------|------|------|
| **对外 API** | `business-pay-api` | `PayCenterApi`、`PayOrderReadApi`（供其他模块依赖） |
| 管理端 API | `business-pay-controller` | REST：`/admin/manager/business/pay/{实体}/v1/*` |
| 应用编排 | `business-pay-application` | Application Service |
| 领域服务 | `business-pay-service` | Domain Service + Mapper + API 实现 |
| 数据对象 | `business-pay-bean` | Entity / DTO / VO / Convert |
| 管理端页面 | `TravelWebFront/src/views/business/pay/*` | ProTable + Vue3 |
| **数据库脚本** | `sql/` | 建表、种子、菜单权限（见 `sql/README.md`） |

**其他业务模块接入时，只依赖 `business-pay-api` + `business-pay-bean`，不要依赖 `business-pay-service` / `business-pay-controller`。**

---

## 两条支付主链路（必读）

| 链路 | 主单表 | 适用场景 | 下单入口 | 回调入口 |
|------|--------|----------|----------|----------|
| **杏花村 C 端（推荐）** | `biz_finance_pay_order`（`business-finance`） | 小程序商城/酒店/门票等 | `PayCenterApi.wechatJsapiPrepay` | 各业务移动端回调 + `WechatPayNotifyAdapterService` |
| **Legacy 支付中心** | `sys_pay_order` | 原物业/多通道遗留 | `PayCenterApi.paymentOrder` | `PayNotifyController` → `PayCenterApi.notify` |

> C 端微信 **禁止** 对杏花村订单走 `paymentOrder`（会尝试写 `sys_pay_order`）；`PayCenterServiceImpl` 与 `WxPayOperationStrategy` 已对 `bizScene` 非空订单做拦截。

---

## 一、业务模块如何接入

### 1.1 Maven 依赖

```xml
<dependency>
    <groupId>com.xinghuacuntravel</groupId>
    <artifactId>business-pay-api</artifactId>
    <version>${project.version}</version>
</dependency>
<dependency>
    <groupId>com.xinghuacuntravel</groupId>
    <artifactId>business-pay-bean</artifactId>
    <version>${project.version}</version>
</dependency>
```

移动端网关（`business-mobile-gateway`）已依赖上述 API，并在网关内编排预支付与回调。

### 1.2 支付渠道编码（`BasicPayOrderData.payType`）

| 枚举 | value | 说明 |
|------|-------|------|
| `PayTypeStyle.WX_PAY` | `1` | 微信 V3（JSAPI / APP） |
| `PayTypeStyle.ALI_PAY` | `2` | 支付宝 |
| `PayTypeStyle.PFA_PAY` | `3` | 浦发 |
| `PayTypeStyle.TLINX_PAY` | `4` | TLinx |

### 1.3 通用入参 `BasicPayOrderData`

| 字段 | 说明 |
|------|------|
| `payType` | 渠道编码，见上表 |
| `payAmount` | 金额，**单位：分** |
| `orderNumber` | 商户单号 / 系统支付单号 |
| `subject` / `description` | 商品标题与描述 |
| `notifyUrl` | 渠道异步通知完整 URL |
| `userId` | 缴费用户 ID |
| `attach` | 微信 attach，建议 JSON（含 `bizType`、`orderId`、`payOrderId`） |
| `payerOpenId` | 微信 JSAPI 付款人 openid |
| `wxTradeType` | `JSAPI`（默认）或 `APP` |
| `bizScene` | 杏花村业务场景（如 `MALL_ORDER`）；**非空表示走 finance 主单** |
| `bizOrderId` | 业务订单主键 |
| `financePayOrderId` | 财务支付单 ID（`createIntent` 后回填） |

判断是否为杏花村财务链路：`payOrderData.isTravelFinanceOrder()` ⇔ `bizScene` 非空。

浦发等扩展字段使用子类 `PfPayOrderData`（`storeNumber`、`pfPayType` 等），见 `business-pay-service` 包 `com.jeesharp.business.modules.pay.dto`。

---

## 二、杏花村 C 端：微信 JSAPI 预支付（推荐）

### 2.1 调用流程

```mermaid
sequenceDiagram
    participant App as 小程序/业务Controller
    participant GW as WechatJsapiPayOrderPrepayService
    participant Fin as PayOrderApplicationService
    participant Pay as PayCenterApi
    participant WX as 微信支付V3

    App->>GW: execute(WechatPrepayCommand)
    GW->>Fin: createIntentForJsapi(...)
    Fin-->>GW: outTradeNo, payOrderId
    GW->>Pay: wechatJsapiPrepay(BasicPayOrderData)
    Pay->>WX: 统一下单
    WX-->>Pay: prepay_id 等
    Pay-->>GW: WechatJsapiPrepayVO
    GW->>Fin: bindPrepayAfterJsapi(...)
    GW-->>App: 调起收银台参数
```

**推荐做法**：业务模块在 Application 层准备好金额、业务单 ID、描述等，由 **mobile-gateway** 统一调用 `WechatJsapiPayOrderPrepayService`，不要在各业务里直接拼微信 SDK。

网关参考实现：`business-mobile-gateway/.../WechatJsapiPayOrderPrepayService.java`

```java
// 1. 财务主单（biz_finance_pay_order）
PayOrderIntentVO intent = payOrderApplicationService.createIntentForJsapi(
    bizScene, bizOrderId, amountYuan, memberId, subject, description,
    notifyUrl, openid, null);

// 2. 组装 PayCenterApi 入参（须带 bizScene）
BasicPayOrderData payData = new BasicPayOrderData();
payData.setPayType(PayTypeStyle.WX_PAY.getValue());
payData.setBizScene(bizScene);
payData.setBizOrderId(bizOrderId);
payData.setFinancePayOrderId(intent.getPayOrderId());
payData.setOrderNumber(intent.getOutTradeNo());
payData.setPayAmount(amountFen);
payData.setPayerOpenId(openid);
payData.setNotifyUrl(notifyUrl);
payData.setAttach(attachJson); // 建议含 orderId、payOrderId、memberId、bizType

// 3. 仅调渠道，不写 sys_pay_order
WechatJsapiPrepayVO prepay = payCenterApi.wechatJsapiPrepay(payData);

// 4. 回写 prepay_id
payOrderApplicationService.bindPrepayAfterJsapi(intent.getPayOrderId(), prepayId);
```

**回调 URL 拼接规则**：

```
notifyUrl = pay_wechat_config.notifyBaseUrl（去尾斜杠） + /pay/notify/wechat（全业态统一相对路径）
```

完整示例：`https://{domain}/mobile/pay/notify/wechat`（`notifyBaseUrl` 须含 `/mobile` 前缀）。

`notifyBaseUrl` 在管理后台 **支付 · 微信配置** 维护；业态路由依赖预支付 attach 中的 `bizType`（`WechatPayAttachSupport`），由 `TravelWechatPayNotifyMobileController` 统一接收入口。

### 2.2 仅调用 PayCenterApi 的场景

若已在业务侧创建好 `biz_finance_pay_order`，可只注入 `PayCenterApi`：

```java
@Autowired
private PayCenterApi payCenterApi;

// 预支付
WechatJsapiPrepayVO vo = payCenterApi.wechatJsapiPrepay(payData);

// 读取公开配置（回调基地址等，不含密钥）
PayWechatPublicConfigVO cfg = payCenterApi.getWechatPublicConfig();

// 自行处理回调报文时验签解密
Map<String, Object> parsed = payCenterApi.wechatParsePayNotify(rawBody, headers);
```

---

## 三、Legacy 链路：各渠道下单 / 查单 / 退款

适用于仍使用 **`sys_pay_order`** 的物业或多通道场景。

### 3.1 下单

```java
@Autowired
private PayCenterApi payCenterApi;

BasicPayOrderData data = new BasicPayOrderData();
data.setPayType(PayTypeStyle.ALI_PAY.getValue()); // 或 WX_PAY / PFA_PAY / TLINX_PAY
data.setPayAmount(100L);       // 分
data.setSubject("商品标题");
data.setUserId("userId");
data.setNotifyUrl("https://your.domain/api/pay/payNotify/aliPayNotify");
// 浦发：使用 PfPayOrderData 并设置 storeNumber、pfPayType 等

Object channelResult = payCenterApi.paymentOrder(request, data);
```

内部流程（策略模式）：

1. `PayOperationStrategyFactory` 按 `payType` 选择策略（`WxPayOperationStrategy`、`AliPayOperationStrategy` 等）。
2. 发布 `PayOrderCheckEvent` → `PayApiOrderServiceImpl` 校验参数。
3. 发布 `PayOrderCreateEvent` → 写入 `sys_pay_order` + `sys_pay_order_info`（**杏花村 finance 订单会跳过创建**）。
4. 调用对应渠道 SDK 下单，返回渠道原始结果（由调用方解析）。

### 3.2 查单 / 退款

```java
payCenterApi.checkOrder(request, payOrderData);   // 需 orderNumber + payType
payCenterApi.returnOrder(request, payOrderData);  // 另需 refundAmount（分）
```

### 3.3 只读查询 Legacy 单

```java
@Autowired
private PayOrderReadApi payOrderReadApi;

PayOrderSummaryDTO summary = payOrderReadApi.getByOrderNumber(orderNumber);
```

---

## 四、回调怎么处理

### 4.1 杏花村 C 端微信回调（统一入口）

微信服务器 POST 至杏花村 C 端统一入口：

```
POST {mobilePath}/pay/notify/wechat   # 全业态，mobilePath 默认 /mobile
```

处理链：

```mermaid
flowchart LR
    WX[微信服务器] --> MC[TravelWechatPayNotifyMobileController]
    MC --> AD[WechatPayNotifyAdapterService]
    AD --> API[PayCenterApi.wechatParsePayNotify]
    AD --> BA[WechatPayCallbackAdapter 按 attach.bizType]
    AD --> FIN[PayOrderApi.markPaid]
    AD --> REC[PayRecordApi 记流水]
```

步骤说明：

1. **验签与解密**：`PayCenterApi.wechatParsePayNotify(rawBody, headers)`，依赖 `pay_wechat_config` 中的 APIv3 密钥与平台证书。
2. **解析 attach**：从中取 `orderId`（业务单）、`payOrderId`（财务支付单）、`bizType`（与 `MobilePayBizType` 一致）。
3. **业务确认**：`WechatPayCallbackAdapter.confirm(orderId, payOrderId, thirdPartyTradeNo)`（商城/酒店/门票各自实现）。
4. **财务落账**：`markPaidByWechatOutTradeNo` + `recordWechatJsapiNotifyIfAbsent`（幂等以流水为准）。

扩展新业务回调：

1. 实现 `WechatPayCallbackAdapter`，`bizType()` 返回对应 `MobilePayBizType`。
2. 预支付走 `WechatJsapiPayOrderPrepayService.execute`（`attach` 含 `bizType`、`orderId`、`payOrderId`）。
3. **无需**新增业态 Notify Controller；统一入口为 `TravelWechatPayNotifyMobileController`（`POST /mobile/pay/notify/wechat`）。

### 4.2 Legacy 统一回调入口

| 渠道 | HTTP 路径 | `payType` |
|------|-----------|-----------|
| 支付宝 | `POST /api/pay/payNotify/aliPayNotify` | `2` |
| 微信 | `POST /api/pay/payNotify/wxNotify` | `1` |
| 浦发 | `POST /api/pay/payNotify/pfNotify` | `3` |

Controller：`business-pay-controller/.../PayNotifyController.java`  
实现：`PayCenterApi.notify(payType, request)` → `PayNotifyStrategy` → 异步 `PayOrderUpdateEvent` → `PayApiOrderServiceImpl.orderUpdate` 更新 **`sys_pay_order`**。

微信 Legacy 回调要点（`WxPayNotifyStrategy`）：

- 请求体为 **V3 JSON**，应答为 V3 JSON（`WechatPayV3NotifyResponse.success/fail`），非 V2 XML。
- `trade_state=SUCCESS` 时发布 `PayOrderUpdateEvent`；若 attach 含 `bizScene`，`wxOrderOperate` **不会** 更新 `sys_pay_order`（避免与 finance 双写）。

支付宝（`AliPayNotifyStrategy`）：验签 → `trade_status` 校验 → 异步更新 `sys_pay_order`。  
浦发（`PfPayNotifyStrategy`）：按浦发报文解析后同样走 `PayOrderUpdateEvent`。

### 4.3 回调配置检查清单

- [ ] 管理后台 **微信配置** 已填 `notifyBaseUrl`（HTTPS 公网域名，须含 `/mobile` 后缀）。
- [ ] 预支付写入的 `notify_url` 为 `{notifyBaseUrl}/pay/notify/wechat`；attach 含正确 `bizType`。
- [ ] 微信商户平台配置的「支付通知 URL」与实际上线 `notifyUrl` 一致。
- [ ] 支付宝 `ali.pay.notifyUrl`（或后续库表配置）指向 `/api/pay/payNotify/aliPayNotify`。
- [ ] 浦发 `pufa-pay.properties` 中 `NOTIFY_URL` 指向 `/api/pay/payNotify/pfNotify`。
- [ ] 回调处理具备幂等（finance 流水 / `sys_pay_order` 状态判断）。

---

## 五、渠道配置说明

| 渠道 | 配置来源 | 管理端 |
|------|----------|--------|
| 微信 V3 | `pay_wechat_config` | **支付 · 微信配置** |
| 支付宝 | `ali.pay.*`（YAML，计划迁库） | — |
| 浦发 | `pufa-pay.properties` | — |
| TLinx | 代码常量 `TLinx2Config` 等 | — |
| 支付商户 | `pay_merchant` | **支付 · 商户**（浦发等，与微信配置分离） |

微信配置详见下文「微信 V3 配置」；运行时由 `PayWechatWxPayClientHolder` 读库装配，保存后缓存失效。

---

## 六、管理端实体与接口

| 功能 | 表名 | API 前缀 | 前端路由 |
|------|------|----------|----------|
| **渠道公共配置** | `pay_channel_config` | `/manager/business/pay/payChannelConfig/v1`（`POST create` / `POST update`） | `/business/pay/channelConfig` |
| 支付商户 | `pay_merchant` | `/manager/business/pay/payMerchant/v1` | `/business/pay/merchant` |
| **微信支付 V3** | `pay_wechat_config` | `/manager/business/pay/payWechatConfig/v1` | `/business/pay/wechatConfig` |
| 支付拓展单 | `pay_order_extension` | `/manager/business/pay/payOrderExtension/v1` | `/business/pay/orderExtension` |
| 退款订单 | `pay_refund` | `/manager/business/pay/payRefund/v1` | `/business/pay/refund` |
| 系统支付订单 | `sys_pay_order` | `/manager/business/pay/sysPayOrder/v1` | `/business/pay/sysPayOrder` |

标准操作：`GET info`、`POST list`、`POST create`、`POST update`、`GET delete?ids=`（各子模块若仍为 `POST save` 以代码为准）。

### 权限标识

```
manager:business:pay:payChannelConfig:info|list|create|update|delete
manager:business:pay:payMerchant:info|list|save|delete
manager:business:pay:payWechatConfig:info|list|save|delete
manager:business:pay:payOrderExtension:info|list|save|delete
manager:business:pay:payRefund:info|list|save|delete
manager:business:pay:sysPayOrder:info|list|save|delete
```

菜单 SQL：`doc/sql/business-pay/pay_admin_menu.sql`（`path` 建议 `business/pay/wechatConfig`，`component` 为 `business/pay/wechatConfig/index`）。

**完整支付域菜单（含 finance 结算/分账等）见下文第十一节。**

---

## 七、启动集成

`web-starter` 已依赖 `business-pay-controller`，启动后即可访问管理端 API 与 `/api/pay/payNotify/*` 回调。

`business-mobile-gateway` 依赖 `business-pay-api`，C 端预支付与业务回调在网关模块。

---

## 八、与 business-finance 的关系

| 模块 | 职责 |
|------|------|
| **business-finance** | 杏花村 **`biz_finance_pay_order`**、支付流水；创建支付意图、标记已支付 |
| **business-pay** | 渠道能力（微信 V3 下单/验签）、Legacy **`sys_pay_order`**、管理端配置 |

C 端主链路：**finance 写主单 → pay 调渠道 → 业务回调 adapter → finance 改状态 + 记流水**。

数据迁移说明：`doc/sql/business-finance/sys_pay_order_migrate_to_finance.md`。

---

## 九、支付核心能力（包结构）

| 能力 | 包路径 | 说明 |
|------|--------|------|
| 对外 API | `business-pay-api` | `PayCenterApi`、`PayOrderReadApi` |
| 支付策略 | `strategy/operation/` | 各渠道下单/查单/退款 |
| 回调策略 | `strategy/notify/` | 各渠道异步通知 |
| 订单监听 | `listener/event/PayApiOrderServiceImpl` | `sys_pay_order` 创建与更新 |
| 微信 V3 | `service/weixin/`、`paywechatconfig/` | 配置、预支付、回调解析 |
| 回调 HTTP | `PayNotifyController` | Legacy 统一入口 |

**注意**：模块内 `PayOrderService` 为 `PayCenterApi` 别名；与 `business-finance` 的 `PayOrderService` **包名不同**，注入时勿混淆。

---

## 十、微信 V3 配置（后台）

| 项 | 说明 |
|----|------|
| 配置表 | `pay_wechat_config`（`sql/pay_wechat_config.sql`） |
| 管理端 | `GET active`、`POST save` |
| 种子 SQL | `sql/pay_wechat_config_seed.sql` |
| 全部 SQL | 见 `sql/README.md`（建表/种子/菜单集中存放） |
| 运行时 | `PayWechatWxPayClientHolder` 按库表装配，保存后自动失效缓存 |
| **已移除** | `wx.pay` YAML、gateway 内重复 `WechatMiniPay*` 实现 |

---

## 十一、管理端前端菜单路由（与 `sys_menu_info` 对照）

> **路由登记**：`TravelWebFrontProject/src/business/asyncRouter.ts`  
> **页面目录**：`TravelWebFrontProject/src/business/views/pay/*`、`.../views/finance/*`  
> 与系统库对照时，**`menu_path` 须与路由 `name` 完全一致**，否则动态路由无法匹配。

### 11.1 字段对照

| 字段 | 前端路由（asyncRouter） | 系统菜单（`sys_menu_info`） |
|------|-------------------------|-----------------------------|
| 路由名 | `name` | `menu_path` |
| 访问地址 | `path`（如 `/business/pay/channelConfig`） | 由壳层与 `class_path` 拼出 |
| 组件 | `views/.../index.vue` | `component`（无 `.vue`，如 `business/pay/channelConfig/index`） |
| 侧栏 | `hidden: true` 或 `meta.hidden` | `is_show`（0 隐藏 / 1 显示） |

### 11.2 支付中心 `/business/pay/*`

> 菜单 SQL：`doc/sql/business-pay/pay_admin_menu.sql`（历史 `sys_menu` 结构；生产以 `sys_menu_info` + 下表 `menu_path` 为准）

| 菜单标题 | 路由名 `menu_path` | 浏览器路径 | 组件 `component` | 侧栏 |
|---------|-------------------|-----------|------------------|------|
| 渠道配置 | `businessPayChannelConfig` | `/business/pay/channelConfig` | `business/pay/channelConfig/index` | 显示 |
| 微信配置 | `businessPayWechatConfig` | `/business/pay/wechatConfig` | `business/pay/wechatConfig/index` | **隐藏**（从渠道配置进入） |
| 支付宝配置 | `businessPayAlipayConfig` | `/business/pay/alipayConfig` | `business/pay/alipayConfig/index` | **隐藏** |
| 浦发配置 | `businessPayPufaConfig` | `/business/pay/pufaConfig` | `business/pay/pufaConfig/index` | **隐藏** |
| 特约商户进件 | `businessPaySubMerchantApplyment` | `/business/pay/subMerchantApplyment` | `business/pay/subMerchantApplyment/index` | 显示 |
| 进件申请编辑 | `businessPaySubMerchantApplymentEditor` | `/business/pay/subMerchantApplyment/editor` | `business/pay/subMerchantApplyment/editor` | **隐藏** |
| 进件申请进度 | `businessPaySubMerchantApplymentProgress` | `/business/pay/subMerchantApplyment/progress` | `business/pay/subMerchantApplyment/progress` | **隐藏** |
| 修改结算账户 | `businessPaySubMerchantApplymentSettlementModify` | `/business/pay/subMerchantApplyment/settlementModify` | `business/pay/subMerchantApplyment/settlementModify` | **隐藏** |
| 商户注销 | `businessPaySubMerchantApplymentMerchantCancel` | `/business/pay/subMerchantApplyment/merchantCancel` | `business/pay/subMerchantApplyment/merchantCancel` | **隐藏** |
| 平台账户提现 | `businessPayPlatformFundWithdraw` | `/business/pay/platformFundWithdraw` | `business/pay/platformFundWithdraw/index` | 显示 |
| 商户账户提现 | `businessPayMerchantFundWithdraw` | `/business/pay/merchantFundWithdraw` | `business/pay/merchantFundWithdraw/index` | 显示 |
| 支付拓展单 | `businessPayOrderExtension` | `/business/pay/orderExtension` | `business/pay/orderExtension/index` | 显示 |
| 退款订单（支付中心） | `businessPayRefund` | `/business/pay/refund` | `business/pay/refund/index` | 显示 |
| 系统支付订单（Legacy） | `businessPaySysPayOrder` | `/business/pay/sysPayOrder` | `business/pay/sysPayOrder/index` | 显示 |

### 11.3 财务 · 支付/结算 `/business/finance/*`

> 模块：`business-finance`  
> 菜单 SQL：`business-finance/src/main/resources/sql/finance_menu_permission.sql`、`finance_merchant_finance_permission.sql`；  
> 支付记录/支付单：`doc/sql/business-finance/finance_pay_record_menu.sql`、`finance_pay_order_menu.sql`

| 菜单标题 | 路由名 `menu_path` | 浏览器路径 | 组件 `component` | 侧栏 | 备注 |
|---------|-------------------|-----------|------------------|------|------|
| 支付记录 | `businessFinancePayRecord` | `/business/finance/payRecord` | `business/finance/payRecord/index` | 显示 | |
| 支付单 | `businessFinancePayOrder` | `/business/finance/payOrder` | `business/finance/payOrder/index` | 显示 | **杏花村主支付单**（`biz_finance_pay_order`） |
| 商户结算配置 | `businessFinanceMerchantSettle` | `/business/finance/merchantSettle` | `business/finance/merchantSettle/index` | 显示 | |
| 微信分账单 | `businessFinanceProfitSharing` | `/business/finance/profitSharing` | `business/finance/profitSharing/index` | 显示 | 平台视角 |
| 我的分账 | `businessFinanceMyProfitSharing` | `/business/finance/myProfitSharing` | `business/finance/profitSharing/index` | 显示 | 商户视角，同组件 |
| 支付退款单（财务） | `businessFinancePayRefund` | `/business/finance/payRefund` | `business/finance/payRefund/index` | 显示 | 与 `businessPayRefund` 不同模块 |
| 商户应收账 | `businessFinanceMerchantReceivable` | `/business/finance/merchantReceivable` | `business/finance/merchantReceivable/index` | 显示 | 平台视角 |
| 我的收入 | `businessFinanceMyIncome` | `/business/finance/myIncome` | `business/finance/merchantReceivable/index` | 显示 | 商户视角，同组件 |
| 商户结算单 | `businessFinanceMerchantSettlementBill` | `/business/finance/merchantSettlementBill` | `business/finance/merchantSettlementBill/index` | 显示 | 平台代收结算 |
| 我的结算单 | `businessFinanceMySettlementBill` | `/business/finance/mySettlementBill` | `business/finance/merchantSettlementBill/index` | 显示 | 商户视角，同组件 |
| 分账回退单 | `businessFinanceProfitSharingReturn` | `/business/finance/profitSharingReturn` | `business/finance/profitSharingReturn/index` | 显示 | |
| 财务对账 | `businessFinanceReconcile` | `/business/finance/reconcile` | `business/finance/reconcile/index` | 显示 | |

**无独立菜单（按钮权限）**

| 能力 | 权限标识 | 挂在页面 | SQL |
|------|----------|----------|-----|
| 平台收入日汇总回填 | `manager:business:finance:platformRevenue:rollup` | 商户应收账 → 平台佣金趋势卡片 | `finance_merchant_finance_permission.sql` |

### 11.4 易混淆项（对照时重点核对）

| 对比项 | 支付中心（`business-pay`） | 财务（`business-finance`） |
|--------|---------------------------|----------------------------|
| 退款 | `businessPayRefund` → `/business/pay/refund` | `businessFinancePayRefund` → `/business/finance/payRefund` |
| 支付单 | `businessPaySysPayOrder`（Legacy `sys_pay_order`） | `businessFinancePayOrder`（**C 端主链路**） |
| 分账 | — | `profitSharing`（平台）/ `myProfitSharing`（商户） |
| 结算 | 进件子页「修改结算账户」 | `merchantSettle` 配置 + `merchantSettlementBill` 结算单 |

### 11.5 系统库核对 SQL

```sql
SELECT menu_name, menu_short_name, menu_path, component, sort_num, is_show
FROM sys_menu_info
WHERE del_flag = '0'
  AND (
    menu_path LIKE 'businessPay%'
    OR menu_path LIKE 'businessFinance%'
    OR component LIKE 'business/pay/%'
    OR component LIKE 'business/finance/%'
  )
ORDER BY sort_num, menu_name;
```

**应存在的路由名（`menu_path`）清单：**

```
-- 支付中心（14）
businessPayChannelConfig
businessPayWechatConfig
businessPayAlipayConfig
businessPayPufaConfig
businessPaySubMerchantApplyment
businessPaySubMerchantApplymentEditor
businessPaySubMerchantApplymentProgress
businessPaySubMerchantApplymentSettlementModify
businessPaySubMerchantApplymentMerchantCancel
businessPayPlatformFundWithdraw
businessPayMerchantFundWithdraw
businessPayOrderExtension
businessPayRefund
businessPaySysPayOrder

-- 财务支付/结算（12）
businessFinancePayRecord
businessFinancePayOrder
businessFinanceMerchantSettle
businessFinanceProfitSharing
businessFinanceMyProfitSharing
businessFinancePayRefund
businessFinanceMerchantReceivable
businessFinanceMyIncome
businessFinanceMerchantSettlementBill
businessFinanceMySettlementBill
businessFinanceProfitSharingReturn
businessFinanceReconcile
```

核对要点：`menu_path` = 路由 `name`；`component` 与上表一致；隐藏子页勿误设 `is_show = 1`。

---

## 十二、常见问题

**Q：新业务要做小程序微信支付，最少改哪些地方？**  
A：finance 创建支付意图；网关复用 `WechatJsapiPayOrderPrepayService.execute`；新增 `WechatPayCallbackAdapter`；配置 `notifyBaseUrl`（统一回调路径 `/pay/notify/wechat` 由网关常量维护）。

**Q：能否在业务 Service 里直接 `paymentOrder` 调微信？**  
A：杏花村订单不可以，须 `wechatJsapiPrepay` 且带 `bizScene`；Legacy 物业单可以 `paymentOrder`。

**Q：回调成功但业务单未更新？**  
A：查 attach 是否含正确 `orderId` / `payOrderId`；查 `WechatPayCallbackAdapter` 是否注册；查 finance 日志是否 `markPaidByWechatOutTradeNo` 异常。

**Q：Legacy 微信回调仍走 `/api/pay/payNotify/wxNotify` 可以吗？**  
A：可以，但 C 端杏花村订单应走各业务 `/app/.../notify/wechat`，由 `WechatPayNotifyAdapterService` 统一处理，避免只更新 `sys_pay_order`。

---

**文档版本：** 2.1  
**最后更新：** 2026-06-29  
**维护者：** 项目团队
