# 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
com.xinghuacuntravel
business-pay-api
${project.version}
com.xinghuacuntravel
business-pay-bean
${project.version}
```
移动端网关(`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 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
**维护者:** 项目团队