# 小区支付配置 - PRD

## 文档信息

| 项目 | 内容 |
|------|------|
| 文档版本 | v1.2.0 |
| 创建日期 | 2026-02-26 |
| 更新日期 | 2026-03-09 |
| 模块名称 | 小区支付配置 |
| 文档状态 | 已评审修订 |

---

## 一、模块概述

### 1.1 模块定位

小区支付配置模块是支付中台的核心配置模块,负责为每个小区配置其使用的支付服务商、支付方式和业务场景。通过本模块,运营平台管理员可以灵活控制不同小区使用不同的支付能力。

**v1.1.1版本说明:**
- 支持两种商户模式:**子商户模式**和**独立商户模式**
- 子商户模式:小区在运营平台服务商下申请子商户,仅需配置子商户号
- 独立商户模式:小区独立申请普通商户,需配置完整商户信息(商户号、AppID、密钥)
- 配置流程根据商户模式有所不同

### 1.2 核心功能

1. **小区主支付配置** - 为小区配置主要使用的支付服务商和商户信息(支持子商户/独立商户两种模式)
2. **小区业务场景配置** - 为小区不同业务模块配置对应的支付方式
3. **支付路由服务** - 根据小区和业务类型自动选择支付方式
4. **向导式配置流程** - 分步骤引导完成小区支付配置 (v1.2.0新增)
5. **配置模板** - 支持从其他小区复制配置或使用预设模板 (v1.2.0新增)
6. **配置健康检查** - 定期检查配置有效性并预警 (v1.2.0新增)

### 1.3 使用角色

- **运营平台管理员** - 配置小区支付方式
- **系统路由服务** - 自动选择支付方式
- **业务系统** - 调用路由服务获取支付配置

### 1.4 商户模式说明 (v1.1.1新增, v1.1.2增强)

| 模式 | 说明 | 配置信息 | 适用场景 |
|------|------|---------|---------|
| 子商户模式 | 小区在运营平台服务商下申请子商户 | 仅需子商户号,自动关联服务商信息 | 统一管理、结算方便 |
| 独立商户模式 | 小区独立申请普通商户 | 完整商户号、AppID、密钥 | 独立结算、已有商户 |

**v1.1.2 混合商户模式支持:**

同一小区可以针对不同支付服务商使用不同的商户模式，提供更灵活的配置能力。

**典型场景示例:**
```
小区A 支付配置
├── 微信支付: 子商户模式 (挂靠华南运营平台)
├── 支付宝: 独立商户模式 (小区自有商户号)
└── 易宝托收: 子商户模式 (挂靠华南运营平台)
```

**应用场景说明:**
- 小区已有支付宝独立商户资质，但微信需要通过运营平台开通
- 小区希望部分渠道独立结算，部分渠道统一结算
- 历史原因导致不同渠道的商户开通方式不同

---

## 二、功能详细说明

### 2.1 小区主支付配置

#### 2.1.1 功能描述

为小区配置主要使用的支付服务商和商户信息。v1.1.1版本支持两种商户模式:

1. **子商户模式**: 小区在运营平台服务商下申请子商户,仅需配置子商户号,系统自动关联上级服务商信息
2. **独立商户模式**: 小区独立申请普通商户,需配置完整商户信息(商户号、AppID、密钥),不关联运营平台

#### 2.1.2 业务规则

1. **商户模式选择 (v1.1.1新增)**
   - 每个支付配置必须选择商户模式:子商户或独立商户
   - 子商户模式:必须关联运营平台,仅需填写子商户号
   - 独立商户模式:不关联运营平台,需填写完整商户信息

2. **子商户模式规则**
   - 小区必须在支付服务商处开通子商户(在运营平台服务商下申请)
   - 子商户号由服务商提供,必须唯一
   - 支付时使用运营平台的服务商商户号和密钥,子商户号作为子商户参数传递
   - 配置信息展示时显示运营平台在该服务商的服务商商户信息

3. **独立商户模式规则 (v1.1.1新增)**
   - 小区独立向支付服务商申请普通商户资质
   - 需配置完整的商户号、AppID、密钥、证书等信息
   - 支付时直接使用小区配置的商户信息,不经过运营平台服务商
   - 适用于已有商户资质或需要独立结算的小区

4. **多支付服务商配置**
   - 一个小区可以配置多个支付服务商
   - **同一小区不同服务商可以使用不同商户模式** (v1.1.2调整)
     - 例如：微信支付使用子商户模式，支付宝使用独立商户模式
   - 同一小区同一服务商仍只能配置一次（不能重复配置同一服务商）
   - 只能有一个主支付服务商 (is_primary = true)
   - 修改主支付时,原主支付自动变为非主支付

5. **配置验证**
   - 子商户模式:验证运营平台服务商配置是否存在
   - 独立商户模式:验证商户号、密钥配置是否完整
   - 支持测试连接验证商户信息是否正确

6. **状态管理**
   - 停用配置后,小区无法使用该支付服务商发起新支付
   - 停用不影响已有订单的查询和退款

7. **配置模板功能** (v1.2.0新增)
   - 支持从其他小区复制配置
   - 支持预设配置模板(标准物业、商业综合体等)
   - 复制时自动跳过商户号等唯一信息

#### 2.1.3 页面交互

**小区列表页**
- 展示所有小区及其支付配置状态
- 显示字段:小区名称、运营平台、主支付服务商、商户模式概览、已配置服务商数量、**配置健康状态(v1.2.0)**、配置状态、创建时间
- **配置健康状态显示规则 (v1.2.0新增)**:
  - 🟢 正常: 所有配置验证通过
  - 🟡 警告: 存在证书即将过期等预警
  - 🔴 异常: 存在配置验证失败
  - ⚪ 未知: 未进行过健康检查
- 商户模式概览显示规则 (v1.1.2调整):
  - 全部子商户: 显示"子商户"
  - 全部独立商户: 显示"独立商户"
  - 混合模式: 显示"混合模式" (同时有子商户和独立商户配置)
- 支持按小区名称、运营平台、商户模式、**健康状态(v1.2.0)**筛选
- 支持查看配置详情、编辑配置
- 快捷操作:配置支付、查看业务场景配置、**批量测试连接(v1.2.0)**

**向导式配置流程 (v1.2.0新增)**

新建小区支付配置时,采用分步骤向导引导用户完成配置:

```
┌────────────────────────────────────────────────────────────────┐
│  新建小区支付配置                                                │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  步骤指示器: [1.选择小区] → [2.选择模式] → [3.配置服务商] → [4.业务场景] → [5.完成] │
│                                                                │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │ 步骤1: 选择小区                                          │  │
│  │                                                          │  │
│  │ 小区名称*: [阳光花园小区      ▼]                         │  │
│  │                                                          │  │
│  │ [从其他小区复制配置...]  [使用配置模板...]                │  │
│  │                                                          │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                │
│                              [下一步 →]                        │
└────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────┐
│  步骤2: 选择商户模式                                            │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  ┌─────────────────────┐  ┌─────────────────────┐              │
│  │ ☑ 子商户模式        │  │ ☐ 独立商户模式      │              │
│  │                     │  │                     │              │
│  │ 挂靠运营平台服务商  │  │ 独立申请商户资质    │              │
│  │ 统一管理、结算方便  │  │ 独立结算、自主管理  │              │
│  └─────────────────────┘  └─────────────────────┘              │
│                                                                │
│  所属运营平台*: [华南区域运营中心  ▼]                          │
│                                                                │
│                       [← 上一步]  [下一步 →]                   │
└────────────────────────────────────────────────────────────────┘

┌────────────────────────────────────────────────────────────────┐
│  步骤3: 配置支付服务商                                          │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  可用服务商 (华南运营平台已配置):                               │
│                                                                │
│  ┌──────────────┐ ┌──────────────┐ ┌──────────────┐            │
│  │ ☑ 微信支付   │ │ ☑ 支付宝    │ │ ☐ 易宝支付  │            │
│  │ [设为主支付] │ │              │ │              │            │
│  │              │ │              │ │              │            │
│  │ 子商户号*:   │ │ 子商户号*:  │ │ 子商户号:   │            │
│  │ [sub_wx_001] │ │ [sub_ali_01]│ │ [         ] │            │
│  └──────────────┘ └──────────────┘ └──────────────┘            │
│                                                                │
│                       [← 上一步]  [下一步 →]                   │
└────────────────────────────────────────────────────────────────┘
```

**配置模板功能 (v1.2.0新增)**

系统提供预设的配置模板,简化新小区配置:

| 模板名称 | 适用场景 | 预设内容 |
|---------|---------|---------|
| 标准物业 | 普通住宅小区 | 微信+支付宝,物业费+停车费 |
| 商业综合体 | 商业+住宅混合 | 微信+支付宝+银联,全业务场景 |
| 纯停车场 | 独立停车场 | 微信+支付宝,仅停车费 |
| 银行托收 | 需要银行代收 | 微信+易宝托收,物业费托收 |

**配置主支付页面**
- 小区信息区(只读)
  - 小区名称
  - 小区ID

- 商户模式选择 (v1.1.1新增)
  - 商户模式(必填,单选:子商户模式/独立商户模式)
  - 选择后动态显示对应的配置表单

- **子商户模式配置** (merchant_mode = sub_merchant)
  - 所属运营平台(必填,下拉选择)
  - 支付服务商(必填,下拉选择,仅显示该运营平台已配置的服务商)
  - 服务商商户信息展示区(只读,展示运营平台的服务商配置)
    - 服务商商户号
    - 服务商应用ID
    - 沙箱模式状态
  - 子商户配置区
    - 子商户号(必填,文本框)
    - 子商户名称(必填,文本框)
  - 设为主支付(开关,默认开启)

- **独立商户模式配置** (merchant_mode = independent)
  - 支付服务商(必填,下拉选择,显示所有启用的服务商)
  - 商户配置区
    - 商户号(必填,文本框)
    - 商户名称(必填,文本框)
    - 应用ID(可选,根据服务商类型显示)
    - 商户密钥(必填,密码框,支持查看/隐藏)
    - 商户证书(可选,文件上传)
    - 接口基础地址(必填,默认提供常用地址)
    - 沙箱模式(开关,默认关闭)
  - 设为主支付(开关,默认开启)

- 其他
  - 备注说明(可选)

- 操作按钮
  - 保存:保存配置
  - 测试连接:验证配置是否正确
  - 取消:返回列表

**小区支付配置详情页**
- Tab1: 基础配置
  - 配置概览区 (v1.1.2新增)
    - 小区名称
    - 配置模式汇总: 子商户X个、独立商户Y个
    - 主支付服务商及模式
  - 已配置服务商列表
    - 列表字段: 服务商名称、商户模式(标签)、商户号、关联平台(子商户显示)、是否主支付、状态
    - 商户模式标签样式:
      - 子商户: 蓝色标签
      - 独立商户: 绿色标签
  - 支持编辑、停用/启用、删除

- Tab2: 业务场景配置
  - 展示该小区各业务类型的支付配置
  - 支持添加、编辑、删除业务场景配置

#### 2.1.4 表单验证

**子商户模式**
| 字段 | 验证规则 |
|------|---------|
| 运营平台 | 必填,必须选择有效的运营平台 |
| 支付服务商 | 必填,必须选择该运营平台已配置的服务商 |
| 子商户号 | 必填,最长64位,字母数字组合 |
| 子商户名称 | 必填,2-100字符 |

**独立商户模式**
| 字段 | 验证规则 |
|------|---------|
| 支付服务商 | 必填,必须选择已启用的服务商 |
| 商户号 | 必填,最长64位,字母数字组合 |
| 商户名称 | 必填,2-100字符 |
| 应用ID | 可选,最长64位 |
| 商户密钥 | 必填,最长512位 |
| 接口基础地址 | 必填,URL格式验证 |

#### 2.1.5 操作提示

| 操作 | 提示信息 |
|------|---------|
| 保存成功 | "小区支付配置保存成功" |
| 保存失败 | "保存失败:[具体错误原因]" |
| 测试连接成功 | "连接测试成功,商户配置正确" |
| 测试连接失败 | "连接测试失败:[具体错误]" |
| 修改主支付确认 | "修改主支付将影响该小区默认支付方式,确认修改?" |
| 停用确认 | "停用后小区将无法使用该支付方式,确认停用?" |
| 切换商户模式确认 | "切换商户模式将清空当前配置,确认切换?" |

---

### 2.2 小区业务场景配置

#### 2.2.1 功能描述

为小区的不同业务模块(物业费、停车费、商城、增值服务等)配置对应的支付方式。**每种业务类型只能配置一种支付方式。**

#### 2.2.2 业务类型定义

| 业务类型代码 | 业务类型名称 | 说明 |
|------------|------------|------|
| property_fee | 物业费 | 物业管理费、公摊费等 |
| parking | 停车费 | 停车场收费 |
| mall | 商城购物 | 线上商城购物 |
| special_service | 专项服务 | 维修、保洁等专项服务 |
| value_added | 增值服务 | 其他增值服务 |

#### 2.2.3 业务规则

1. **单一支付配置 (v1.1.2调整)**
   - 每个小区的每种业务类型只能配置一种支付方式
   - 如需更换支付方式,需先删除原配置再添加新配置

2. **路由规则**
   - 根据小区ID和业务类型直接获取唯一的支付配置
   - 无需优先级排序

3. **关联关系**
   - 支付服务商必须是该小区已配置的服务商
   - 支付方式必须是该服务商支持的支付方式
   - 业务场景必须是该服务商支持的业务场景(可选配置)

4. **状态管理**
   - 停用配置后,该业务类型无法使用该支付方式
   - 如果某业务类型的配置被停用,则该业务无法支付

#### 2.2.4 页面交互

**业务场景配置列表(在小区详情页的Tab中)**
- 按业务类型分组展示
- 每个业务类型下显示:
  - 支付服务商名称
  - 支付方式名称
  - 业务场景名称(如有)
  - 状态
  - 操作:编辑、删除、启用/停用

- 顶部按钮:添加业务场景配置

**添加/编辑业务场景配置(弹窗)**
- 业务类型(必填,下拉选择)
  - property_fee - 物业费
  - parking - 停车费
  - mall - 商城购物
  - special_service - 专项服务
  - value_added - 增值服务
  - **注:已配置的业务类型不可重复选择**

- 支付配置
  - 支付服务商(必填,下拉选择,仅显示该小区已配置的服务商)
  - 支付方式(可选,下拉选择,显示该服务商支持的支付方式)
  - 业务场景(可选,下拉选择,显示该服务商支持的业务场景)

- 其他
  - 备注(可选)

- 操作按钮
  - 确定:保存配置
  - 取消:关闭弹窗

#### 2.2.5 示例配置

**小区A的配置示例:**

```
物业费 (property_fee)
  └─ 微信支付 - 微信扫码支付 - 生活缴费场景

停车费 (parking)
  └─ 微信支付 - 微信公众号支付 - 普通商户场景

商城购物 (mall)
  └─ 支付宝 - 支付宝当面付 - 普通商户场景
```

#### 2.2.6 表单验证

| 字段 | 验证规则 |
|------|---------|
| 业务类型 | 必填,必须选择预定义的业务类型,不可重复配置 |
| 支付服务商 | 必填,必须选择小区已配置的服务商 |
| 支付方式 | 可选,如填写必须是服务商支持的支付方式 |
| 业务场景 | 可选,如填写必须是服务商支持的业务场景 |

#### 2.2.7 操作提示

| 操作 | 提示信息 |
|------|---------|
| 添加成功 | "业务场景配置添加成功" |
| 编辑成功 | "业务场景配置更新成功" |
| 删除确认 | "删除后该业务将无法支付,确认删除?" |
| 业务类型重复 | "该业务类型已配置支付方式,请编辑现有配置" |

---

### 2.3 配置健康检查 (v1.2.0新增)

#### 2.3.1 功能描述

系统定期对小区支付配置进行健康检查,验证配置有效性并提供预警,确保支付服务正常运行。

#### 2.3.2 检查内容

| 检查项 | 检查内容 | 检查频率 | 预警阈值 |
|-------|---------|---------|---------|
| 连接测试 | 调用服务商接口验证连接 | 每6小时 | 连续3次失败 |
| 证书有效期 | 检查商户证书到期时间 | 每天 | 30天/7天/已过期 |
| 配置完整性 | 必填字段是否完整 | 配置变更时 | 缺少必填项 |
| 服务商状态 | 上游服务商是否可用 | 实时监控 | 服务商异常 |

#### 2.3.3 健康状态定义

| 状态 | 图标 | 说明 | 处理建议 |
|-----|------|------|---------|
| healthy | 🟢 | 配置正常,所有检查通过 | 无需处理 |
| warning | 🟡 | 存在预警(证书30天内到期等) | 建议尽快处理 |
| error | 🔴 | 配置异常(连接失败/证书过期) | 需立即处理 |
| unknown | ⚪ | 未检查或检查中 | 等待检查完成 |

#### 2.3.4 页面交互

**小区配置健康检查面板**

在小区详情页顶部显示健康状态概览:

```
┌────────────────────────────────────────────────────────────────┐
│  配置健康状态                                      [立即检查]  │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  整体状态: 🟡 警告 (1个异常, 1个警告)                          │
│                                                                │
│  ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐   │
│  │ 微信支付  🟢    │ │ 支付宝    🟡    │ │ 易宝支付  🔴    │   │
│  │ 连接正常        │ │ 证书即将到期    │ │ 连接失败        │   │
│  │ 上次检查: 10:30 │ │ 剩余23天        │ │ 网关超时        │   │
│  └─────────────────┘ └─────────────────┘ └─────────────────┘   │
│                                                                │
│  详细信息:                                                     │
│  ⚠️ 支付宝证书将在30天内到期(2026-04-01),请尽快更新           │
│  ❌ 易宝支付连接测试失败: 网关超时,请检查配置或联系服务商       │
│                                                                │
└────────────────────────────────────────────────────────────────┘
```

#### 2.3.5 预警通知

| 预警级别 | 触发条件 | 通知方式 | 通知对象 |
|---------|---------|---------|---------|
| 严重 | 连接失败/证书已过期 | 站内消息+短信 | 运营管理员 |
| 警告 | 证书7天内到期 | 站内消息+短信 | 运营管理员 |
| 提醒 | 证书30天内到期 | 站内消息 | 运营管理员 |

#### 2.3.6 数据库字段

在 community_payment_config 表增加健康检查相关字段:

| 字段名 | 类型 | 说明 |
|-------|------|------|
| last_check_time | DATETIME | 最后检查时间 |
| check_status | VARCHAR(20) | 检查状态:healthy/warning/error/unknown |
| check_message | VARCHAR(500) | 检查结果信息 |

---

### 2.4 业务场景可用性控制 (v1.1.1新增)

#### 2.4.1 功能描述

根据小区配置的支付服务商子商户信息,动态控制业务场景的可用性。不同的支付服务商支持不同的业务场景,小区只有配置了相应的支付服务商才能开通对应的业务场景。

#### 2.4.2 业务场景与支付服务商映射关系

| 业务场景代码 | 业务场景名称 | 支付方式 | 是否需要签约 | 支持的支付服务商 |
|------------|------------|---------|------------|----------------|
| normal_payment | 普通支付 | 用户主动发起线上支付 | 否 | 微信支付、支付宝、银联 |
| living_payment | 生活缴费 | 系统统一唤起支付自动扣款 | 是 | 微信支付、支付宝、银联 |
| bank_collect | 电子托收 | 系统统一唤起支付自动扣款 | 是 | 易宝支付、银联 |
| license_plate | 牌照支付 | 用户主动发起线上支付 | 否 | 微信支付、支付宝、银联 |

#### 2.4.3 业务规则

1. **场景可用性判断**
   - 小区只配置了微信支付子商户:可开通 普通支付、生活缴费、牌照支付;电子托收禁用
   - 小区配置了微信支付+易宝支付:可开通 普通支付、生活缴费、牌照支付、电子托收
   - 小区未配置任何服务商:所有业务场景禁用

2. **支付方式说明**
   - **普通支付/牌照支付**: 用户主动发起的线上支付
     - 用户扫码或点击支付按钮
     - 实时跳转到支付页面完成支付
     - 无需提前签约授权
   - **生活缴费/电子托收**: 系统统一唤起支付自动扣款
     - 用户需提前完成签约授权
     - 系统按照业务规则(如每月固定日期)自动发起扣款
     - 无需用户手动操作,自动从签约账户扣款

3. **配置界面提示**
   - 在业务场景配置界面,根据小区已配置的服务商,动态显示可用/禁用状态
   - 禁用的业务场景显示灰色,并提示"需要配置XX支付服务商"
   - 已配置的业务场景显示绿色,可正常使用

4. **父商户信息展示**
   - 在小区配置页面选择支付服务商时,显示运营平台在该服务商的父商户信息
   - 展示内容:父商户号、父商户名称、父应用ID
   - 提示:子商户需要在此父商户下申请

#### 2.4.4 页面交互

**业务场景可用性展示区**
- 位置:小区详情页的业务场景配置Tab顶部
- 展示四种业务场景的可用状态:
  ```
  业务场景可用性状态

  [✓ 普通支付]  已配置:微信支付
  [✓ 生活缴费]  已配置:微信支付
  [✗ 电子托收]  需配置:易宝支付或银联
  [✓ 牌照支付]  已配置:微信支付
  ```

**添加业务场景配置时的限制**
- 选择业务场景下拉框时:
  - 可用的场景:正常显示,可选择
  - 禁用的场景:灰色显示,不可选择,鼠标悬停提示"需要配置XX支付服务商"

**配置服务商时的父商户信息展示**
- 选择支付服务商后,下方显示父商户信息区:
  ```
  父商户信息 (运营平台在该服务商的商户信息)
  父商户号: 1234567890
  父商户名称: XX运营平台
  父应用ID: wx1234567890abcdef

  提示: 子商户需要在此父商户下申请,请联系服务商开通
  ```

#### 2.4.5 示例场景

**场景1:小区只配置了微信支付**

```
小区A配置状态:
- 已配置服务商:微信支付 (子商户号:wx_sub_12345)

业务场景可用性:
✓ 普通支付  - 可用 (用户主动发起线上支付)
✓ 生活缴费  - 可用 (需签约,系统自动扣款)
✗ 电子托收  - 禁用 (需要易宝支付或银联)
✓ 牌照支付  - 可用 (用户主动发起线上支付)

业务使用说明:
- 用户可以通过普通支付缴纳物业费(扫码支付)
- 用户可以签约生活缴费,每月自动扣物业费(无需手动操作)
- 电子托收场景不可用(需要配置易宝支付)
```

**场景2:小区配置了微信支付+易宝支付**

```
小区B配置状态:
- 已配置服务商:微信支付 (子商户号:wx_sub_12345)、易宝支付 (子商户号:yb_sub_67890)

业务场景可用性:
✓ 普通支付  - 可用 (用户主动发起线上支付)
✓ 生活缴费  - 可用 (需签约,系统自动扣款,微信支付)
✓ 电子托收  - 可用 (需签约,系统自动扣款,易宝支付)
✓ 牌照支付  - 可用 (用户主动发起线上支付)

业务使用说明:
- 用户可以选择普通支付实时缴费(扫码/H5支付)
- 用户可以签约微信生活缴费,系统每月自动从微信账户扣款
- 用户可以签约易宝电子托收,系统每月自动从银行卡扣款
- 所有业务场景均可用,满足不同用户的支付需求
```

**场景3:添加电子托收场景配置**

```
操作流程:
1. 用户点击"添加业务场景配置"
2. 选择业务类型:物业费
3. 选择业务场景:电子托收
   - 如果小区未配置易宝支付:
     下拉框中"电子托收"显示为灰色禁用
     提示:"需要配置易宝支付或银联才能开通电子托收"
   - 如果小区已配置易宝支付:
     下拉框中"电子托收"正常可选
4. 选择支付服务商:易宝支付
5. 保存配置
```

#### 2.4.6 数据库实现

业务场景与支付服务商的映射关系通过配置表实现:

```sql
-- 业务场景配置表 (新增字段)
ALTER TABLE payment_scene
ADD COLUMN supported_providers VARCHAR(255) COMMENT '支持的服务商列表,逗号分隔,如:WECHAT,ALIPAY,UNIONPAY';

-- 示例数据
UPDATE payment_scene SET supported_providers = 'WECHAT,ALIPAY,UNIONPAY' WHERE scene_code = 'normal_payment';
UPDATE payment_scene SET supported_providers = 'WECHAT,ALIPAY,UNIONPAY' WHERE scene_code = 'living_payment';
UPDATE payment_scene SET supported_providers = 'YEEPAY,UNIONPAY' WHERE scene_code = 'bank_collect';
UPDATE payment_scene SET supported_providers = 'WECHAT,ALIPAY,UNIONPAY' WHERE scene_code = 'license_plate';
```

#### 2.4.7 查询逻辑

```sql
-- 查询小区可用的业务场景
SELECT
    ps.id,
    ps.scene_code,
    ps.scene_name,
    ps.supported_providers,
    CASE
        WHEN EXISTS (
            SELECT 1 FROM community_payment_config cpc
            JOIN payment_provider pp ON cpc.provider_id = pp.id
            WHERE cpc.community_id = ?
            AND cpc.status = 'enabled'
            AND FIND_IN_SET(pp.provider_code, ps.supported_providers) > 0
        ) THEN 'available'
        ELSE 'unavailable'
    END AS scene_status
FROM payment_scene ps
WHERE ps.status = 'enabled';
```

---

### 2.5 支付路由服务

#### 2.5.1 功能描述

支付路由服务是系统内部服务,当业务系统发起支付请求时,根据小区ID和业务类型,自动查询该小区的支付配置,返回应使用的支付服务商和支付方式。

#### 2.5.2 路由逻辑 (v1.1.1调整)

```
输入:
  - community_id: 小区ID
  - business_type: 业务类型 (property_fee/parking/mall等)

处理流程:
1. 查询小区支付配置
   └─ 如果小区未配置任何支付方式,返回错误
   └─ 获取 merchant_mode (商户模式)

2. 根据业务类型查询配置 (v1.1.2简化)
   ├─ 查询该业务类型的配置 (状态=enabled)
   ├─ 每个业务类型仅有一条配置
   └─ 如果未配置,返回错误"该业务类型未配置支付方式"

3. 根据商户模式获取支付凭证 (v1.1.1调整)
   ├─ 子商户模式 (merchant_mode = sub_merchant):
   │   ├─ 查询运营平台服务商配置 (platform_provider_config)
   │   ├─ 获取服务商商户号、应用ID、密钥等
   │   └─ 使用服务商商户信息 + 子商户号
   │
   └─ 独立商户模式 (merchant_mode = independent):
       └─ 直接使用小区配置的商户号、密钥等信息

4. 返回路由结果 (v1.1.1调整)
   ├─ merchant_mode: 商户模式 (新增)
   ├─ platform_id: 运营平台ID (子商户模式有值)
   ├─ provider_id: 支付服务商ID
   ├─ provider_code: 服务商代码
   ├─ payment_method_id: 支付方式ID
   ├─ payment_method_code: 支付方式代码
   ├─ payment_scene_id: 业务场景ID (如有)
   ├─ -- 子商户模式返回以下字段 --
   ├─ sp_merchant_no: 服务商商户号
   ├─ sp_app_id: 服务商应用ID
   ├─ sub_merchant_no: 子商户号
   ├─ -- 独立商户模式返回以下字段 --
   ├─ merchant_no: 商户号
   ├─ app_id: 应用ID
   ├─ api_base_url: 接口基础地址
   └─ sandbox_mode: 沙箱模式
```

#### 2.5.3 路由示例

**场景1: 查询物业费支付配置**

```
请求:
{
  "community_id": 10001,
  "business_type": "property_fee",
  "amount": 50000,
  "user_id": "user123"
}

路由过程:
1. 查询小区10001的配置 → 获取platform_id = 1
2. 查询business_type=property_fee的唯一配置
   └─ 微信支付 - 微信扫码 - 生活缴费场景
3. 查询运营平台1的微信支付配置

返回:
{
  "platform_id": 1,
  "provider_id": 1,
  "provider_code": "WECHAT",
  "payment_method_id": 2,
  "payment_method_code": "NATIVE",
  "payment_scene_id": 1,
  "platform_merchant_no": "1234567890",
  "platform_app_id": "wx1234567890abcdef",
  "sub_merchant_no": "1234567890",
  "sub_app_id": "wx1234567890abcdef",
  "notify_url": "https://payment.example.com/notify/wechat"
}
```

**场景2: 业务系统指定支付方式**

```
请求:
{
  "community_id": 10001,
  "business_type": "property_fee",
  "payment_method_id": 7,  // 指定使用易宝银行托收
  "amount": 50000,
  "user_id": "user123"
}

路由过程:
1. 查询小区10001的配置 → 获取platform_id = 1
2. 验证payment_method_id=7是否在配置中
   └─ 存在: 易宝支付 - 银行托收
3. 直接使用指定的支付方式
4. 查询运营平台1的易宝支付配置

返回:
{
  "platform_id": 1,
  "provider_id": 3,
  "provider_code": "YEEPAY",
  "payment_method_id": 7,
  "payment_method_code": "BANK_COLLECT",
  "payment_scene_id": 4,
  "platform_merchant_no": "YB_PLATFORM_1234567890",
  "sub_merchant_no": "YB1234567890",
  "notify_url": "https://payment.example.com/notify/yeepay"
}
```

**场景3: 小区未配置该业务类型**

```
请求:
{
  "community_id": 10002,
  "business_type": "mall",  // 该小区未配置商城支付
  "amount": 10000,
  "user_id": "user456"
}

路由过程:
1. 查询小区10002的配置 → 获取platform_id = 2
2. 查询business_type=mall的配置
   └─ 无配置
3. 回退到主支付配置
   └─ 使用主支付服务商的默认支付方式

返回:
{
  "platform_id": 2,
  "provider_id": 1,
  "provider_code": "WECHAT",
  "payment_method_id": 1,  // 微信公众号支付 (主支付默认方式)
  "payment_method_code": "JSAPI",
  "platform_merchant_no": "0987654321",
  "platform_app_id": "wx0987654321fedcba",
  "sub_merchant_no": "0987654321",
  "notify_url": "https://payment.example.com/notify/wechat"
}
```

#### 2.5.4 异常处理

| 异常场景 | 处理方式 |
|---------|---------|
| 小区未配置任何支付方式 | 返回错误"小区未配置支付方式,请联系管理员" |
| 指定的支付方式不在配置中 | 返回错误"小区未配置该支付方式" |
| 该业务类型无可用配置 | 回退到主支付配置 |
| 主支付配置被停用 | 返回错误"支付配置已停用,请联系管理员" |
| 服务商密钥缺失 | 返回错误"支付配置异常,请联系管理员" |

#### 2.5.5 性能优化方案 (v1.1.1新增)

**问题分析:**

路由服务每次查询需要执行多次数据库操作:
1. 查询小区支付配置(community_payment_config)
2. 查询业务场景配置(community_business_scene_config)
3. 查询运营平台服务商配置(platform_provider_config)

在高并发场景下(TPS>1000),多次数据库查询可能成为性能瓶颈。

**优化方案:**

**1. Redis缓存策略**

```
缓存层级:
├─ 小区支付配置缓存
│  ├─ Key: pay:route:community:{community_id}
│  ├─ TTL: 5分钟
│  └─ 内容: 小区的所有支付配置(JSON)
│
├─ 运营平台服务商配置缓存
│  ├─ Key: pay:route:platform:{platform_id}:{provider_id}
│  ├─ TTL: 10分钟
│  └─ 内容: 平台商户号、应用ID、密钥等
│
└─ 路由结果缓存
   ├─ Key: pay:route:result:{community_id}:{business_type}:{payment_method_id}
   ├─ TTL: 3分钟
   └─ 内容: 完整的路由结果

缓存失效规则:
- 小区支付配置变更: 主动删除 pay:route:community:{community_id}
- 运营平台配置变更: 主动删除 pay:route:platform:{platform_id}:*
- 缓存不存在: 查询数据库并写入缓存
- Redis不可用: 降级到数据库直接查询
```

**2. SQL查询优化**

使用JOIN合并查询,减少数据库往返:

```sql
-- 优化前: 3次查询
SELECT * FROM community_payment_config WHERE community_id = ?;
SELECT * FROM community_business_scene_config WHERE ...;
SELECT * FROM platform_provider_config WHERE ...;

-- 优化后: 1次JOIN查询
SELECT
  cpc.platform_id,
  cpc.provider_id,
  pp.provider_code,
  cpc.sub_merchant_no,
  cbsc.payment_method_id,
  pm.method_code AS payment_method_code,
  cbsc.payment_scene_id,
  ppc.platform_merchant_no,
  ppc.platform_app_id,
  ppc.notify_url
FROM community_payment_config cpc
LEFT JOIN community_business_scene_config cbsc
  ON cpc.id = cbsc.config_id
  AND cbsc.business_type = ?
  AND cbsc.status = 'enabled'
INNER JOIN platform_provider_config ppc
  ON cpc.platform_id = ppc.platform_id
  AND cpc.provider_id = ppc.provider_id
  AND ppc.status = 'enabled'
INNER JOIN payment_provider pp
  ON cpc.provider_id = pp.id
LEFT JOIN payment_method pm
  ON cbsc.payment_method_id = pm.id
WHERE cpc.community_id = ?
  AND cpc.status = 'enabled'
ORDER BY cbsc.priority ASC
LIMIT 1;
```

**3. 缓存更新策略**

```
配置变更时的缓存更新:

1. 小区支付配置变更 (管理端操作)
   ├─ 删除缓存: pay:route:community:{community_id}
   ├─ 删除缓存: pay:route:result:{community_id}:*
   └─ 下次查询时重新加载

2. 运营平台配置变更
   ├─ 删除缓存: pay:route:platform:{platform_id}:{provider_id}
   ├─ 查询该运营平台关联的小区列表
   ├─ 批量删除关联小区的路由缓存: pay:route:result:{community_id}:*
   └─ 下次查询时重新加载

3. 缓存预热 (系统启动时)
   ├─ 加载Top 1000热门小区的配置
   └─ 异步任务定期刷新(每10分钟)
```

**4. 性能指标**

| 场景 | 优化前 | 优化后 | 目标 |
|------|-------|-------|------|
| 缓存命中 | - | <10ms | <50ms |
| 缓存未命中 | 80-150ms | 30-50ms | <100ms |
| 高并发(1000 TPS) | 响应时间波动大 | 响应时间稳定 | P99<50ms |
| 数据库压力 | 3000 QPS | <500 QPS | 减少80% |

**5. 降级策略**

```
Redis故障时的降级方案:

1. 检测Redis不可用
   └─ 连接超时/响应超时/集群故障

2. 自动降级到数据库直接查询
   ├─ 跳过缓存读写
   ├─ 使用优化后的JOIN查询
   └─ 记录降级告警日志

3. 性能影响评估
   ├─ 响应时间: 增加20-30ms
   ├─ 数据库压力: 增加但可控(优化后的SQL)
   └─ 系统可用性: 不受影响

4. 恢复策略
   ├─ 监控Redis健康状态
   ├─ Redis恢复后自动启用缓存
   └─ 触发缓存预热
```

**6. 监控指标**

- 路由查询响应时间(P50/P95/P99)
- 缓存命中率
- 缓存失效次数
- 降级次数和持续时间
- 数据库查询耗时

---

## 三、数据库设计

### 3.1 小区支付配置表 (community_payment_config) - v1.1.1调整

#### 3.1.1 表说明
存储小区的支付服务商配置和商户信息,支持子商户模式和独立商户模式

#### 3.1.2 字段设计

| 字段名 | 类型 | 长度 | 允许空 | 默认值 | 说明 |
|-------|------|------|-------|-------|------|
| id | BIGINT | - | 否 | 自增 | 主键ID |
| community_id | BIGINT | - | 否 | - | 小区ID |
| provider_id | BIGINT | - | 否 | - | 支付服务商ID,外键关联payment_provider.id |
| merchant_mode | VARCHAR | 20 | 否 | sub_merchant | 商户模式:sub_merchant(子商户)/independent(独立商户) (v1.1.1新增) |
| platform_id | BIGINT | - | 是 | NULL | 运营平台ID,子商户模式必填,外键关联operation_platform.id |
| is_primary | TINYINT | 1 | 否 | 0 | 是否主支付:0-否,1-是 |
| merchant_no | VARCHAR | 64 | 否 | - | 商户号(子商户模式为子商户号,独立商户模式为商户号) |
| merchant_name | VARCHAR | 100 | 否 | - | 商户名称 |
| app_id | VARCHAR | 64 | 是 | NULL | 应用ID |
| secret_key | VARCHAR | 512 | 是 | NULL | 商户密钥(加密存储,子商户模式可选,独立商户模式必填) |
| cert | TEXT | - | 是 | NULL | 商户证书(加密存储) |
| api_base_url | VARCHAR | 255 | 是 | NULL | 接口基础地址(独立商户模式必填) |
| sandbox_mode | TINYINT | 1 | 否 | 0 | 是否沙箱环境:0-否,1-是(独立商户模式使用) |
| status | VARCHAR | 20 | 否 | enabled | 状态:enabled(已启用)/disabled(已停用) |
| created_at | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | DATETIME | - | 否 | CURRENT_TIMESTAMP ON UPDATE | 更新时间 |
| remark | VARCHAR | 500 | 是 | NULL | 备注说明 |
| last_check_time | DATETIME | - | 是 | NULL | 最后健康检查时间 (v1.2.0新增) |
| check_status | VARCHAR | 20 | 否 | unknown | 检查状态:healthy/warning/error/unknown (v1.2.0新增) |
| check_message | VARCHAR | 500 | 是 | NULL | 检查结果信息 (v1.2.0新增) |

**v1.1.1变更说明:**
- 新增字段: `merchant_mode` (商户模式)
- 调整字段: `platform_id` 改为可空(独立商户模式无需关联运营平台)
- 重命名字段: `sub_merchant_no` → `merchant_no`, `sub_merchant_name` → `merchant_name`
- 新增字段: `api_base_url`, `sandbox_mode` (独立商户模式使用)
- 删除字段: `notify_url` (回调URL由系统统一处理)

#### 3.1.3 索引设计

| 索引名 | 索引类型 | 字段 | 说明 |
|-------|---------|------|------|
| PRIMARY | 主键 | id | 主键索引 |
| uk_community_provider | 唯一索引 | community_id, provider_id | 同一小区不能重复配置同一服务商 |
| idx_community_id | 普通索引 | community_id | 小区查询 |
| idx_platform_id | 普通索引 | platform_id | 运营平台查询 |
| idx_provider_id | 普通索引 | provider_id | 服务商查询 |
| idx_merchant_mode | 普通索引 | merchant_mode | 商户模式查询 |
| idx_is_primary | 普通索引 | is_primary | 主支付查询 |
| idx_status | 普通索引 | status | 状态查询 |
| idx_check_status | 普通索引 | check_status | 健康状态查询 (v1.2.0新增) |

#### 3.1.4 外键约束

```sql
-- 运营平台外键(可空,独立商户模式无需关联)
-- 说明: 当platform_id为NULL时(独立商户模式),外键约束不生效,这是MySQL外键的正常行为
ALTER TABLE community_payment_config
ADD CONSTRAINT fk_community_platform
FOREIGN KEY (platform_id) REFERENCES operation_platform(id)
ON DELETE RESTRICT ON UPDATE CASCADE;

ALTER TABLE community_payment_config
ADD CONSTRAINT fk_community_payment_provider
FOREIGN KEY (provider_id) REFERENCES payment_provider(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
```

#### 3.1.5 示例数据

```sql
-- =============================================
-- 场景1: 子商户模式 (单一模式)
-- 小区10001 阳光花园 - 全部使用子商户模式,挂靠华南运营平台
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, status, remark) VALUES
(10001, 1, 'sub_merchant', 2, 1, 'sub_wx_10001', '阳光花园物业-微信', 'wx_sub_app_10001', 'enabled', '子商户-微信支付-主支付方式'),
(10001, 2, 'sub_merchant', 2, 0, 'sub_ali_10001', '阳光花园物业-支付宝', NULL, 'enabled', '子商户-支付宝'),
(10001, 3, 'sub_merchant', 2, 0, 'sub_yb_10001', '阳光花园物业-易宝', NULL, 'enabled', '子商户-易宝银行托收');

-- =============================================
-- 场景2: 独立商户模式 (单一模式)
-- 小区10002 绿城花苑 - 全部使用独立商户模式,不挂靠运营平台
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, secret_key, api_base_url, sandbox_mode, status, remark) VALUES
(10002, 1, 'independent', NULL, 1, '1900888001', '绿城花苑物业有限公司', 'wx_ind_10002', 'encrypted_wx_key_10002', 'https://api.mch.weixin.qq.com', 0, 'enabled', '独立商户-微信支付-主支付方式'),
(10002, 2, 'independent', NULL, 0, '2088666001', '绿城花苑物业有限公司', 'ali_ind_10002', 'encrypted_ali_key_10002', 'https://openapi.alipay.com/gateway.do', 0, 'enabled', '独立商户-支付宝');

-- =============================================
-- 场景3: 混合商户模式 (v1.1.2新增)
-- 小区10003 碧水湾花园 - 微信用子商户,支付宝用独立商户
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, secret_key, api_base_url, sandbox_mode, status, remark) VALUES
-- 微信走子商户 (挂靠华南平台)
(10003, 1, 'sub_merchant', 2, 1, 'sub_wx_10003', '碧水湾花园物业-微信', 'wx_sub_app_10003', NULL, NULL, NULL, 'enabled', '混合模式-微信子商户(主支付)'),
-- 支付宝走独立商户 (自有商户号)
(10003, 2, 'independent', NULL, 0, '2088777002', '碧水湾花园物业有限公司', 'ali_ind_10003', 'encrypted_ali_key_10003', 'https://openapi.alipay.com/gateway.do', 0, 'enabled', '混合模式-支付宝独立商户'),
-- 易宝走子商户 (挂靠华南平台)
(10003, 3, 'sub_merchant', 2, 0, 'sub_yb_10003', '碧水湾花园物业-易宝', NULL, NULL, NULL, NULL, 'enabled', '混合模式-易宝子商户');

-- =============================================
-- 场景4: 混合商户模式 - 另一种组合
-- 小区10004 翡翠城 - 微信独立,支付宝子商户,银联独立
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, secret_key, api_base_url, sandbox_mode, status, remark) VALUES
-- 微信走独立商户 (已有自己的商户号)
(10004, 1, 'independent', NULL, 1, '1900999001', '翡翠城物业管理公司', 'wx_ind_10004', 'encrypted_wx_key_10004', 'https://api.mch.weixin.qq.com', 0, 'enabled', '混合模式-微信独立商户(主支付)'),
-- 支付宝走子商户 (挂靠华北平台)
(10004, 2, 'sub_merchant', 3, 0, 'sub_ali_10004', '翡翠城物业-支付宝', NULL, NULL, NULL, NULL, 'enabled', '混合模式-支付宝子商户'),
-- 银联走独立商户
(10004, 4, 'independent', NULL, 0, 'union_ind_10004', '翡翠城物业管理公司', NULL, 'encrypted_union_key_10004', 'https://gateway.95516.com', 0, 'enabled', '混合模式-银联独立商户');

-- =============================================
-- 场景5: 华东区域小区 - 子商户模式
-- 小区10005 江南水乡 - 挂靠华东运营平台
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, status, remark) VALUES
(10005, 1, 'sub_merchant', 4, 1, 'sub_wx_10005', '江南水乡物业-微信', 'wx_sub_app_10005', 'enabled', '华东-子商户-微信支付'),
(10005, 2, 'sub_merchant', 4, 0, 'sub_ali_10005', '江南水乡物业-支付宝', NULL, 'enabled', '华东-子商户-支付宝'),
(10005, 5, 'sub_merchant', 4, 0, 'sub_lkl_10005', '江南水乡物业-拉卡拉', NULL, 'enabled', '华东-子商户-拉卡拉');

-- =============================================
-- 场景6: 总部直营小区 - 独立商户模式
-- 小区10006 中央公馆 - 总部直接管理,使用独立商户
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, secret_key, api_base_url, sandbox_mode, status, remark) VALUES
(10006, 1, 'independent', NULL, 1, '1900head001', '中央公馆物业服务中心', 'wx_head_10006', 'encrypted_wx_key_10006', 'https://api.mch.weixin.qq.com', 0, 'enabled', '总部直营-独立商户-微信'),
(10006, 2, 'independent', NULL, 0, '2088head001', '中央公馆物业服务中心', 'ali_head_10006', 'encrypted_ali_key_10006', 'https://openapi.alipay.com/gateway.do', 0, 'enabled', '总部直营-独立商户-支付宝'),
(10006, 6, 'independent', NULL, 0, 'icbc_head_10006', '中央公馆物业服务中心', NULL, 'encrypted_icbc_key_10006', 'https://b2c.icbc.com.cn', 0, 'enabled', '总部直营-独立商户-工行代收');

-- =============================================
-- 场景7: 部分服务商停用
-- 小区10007 锦绣园 - 有停用的服务商配置
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, status, remark) VALUES
(10007, 1, 'sub_merchant', 2, 1, 'sub_wx_10007', '锦绣园物业-微信', 'wx_sub_app_10007', 'enabled', '正常使用'),
(10007, 2, 'sub_merchant', 2, 0, 'sub_ali_10007', '锦绣园物业-支付宝', NULL, 'disabled', '已停用-支付宝渠道暂停'),
(10007, 3, 'sub_merchant', 2, 0, 'sub_yb_10007', '锦绣园物业-易宝', NULL, 'enabled', '正常使用');

-- =============================================
-- 场景8: 沙箱测试小区
-- 小区99999 测试小区 - 沙箱模式用于测试
-- =============================================
INSERT INTO community_payment_config (community_id, provider_id, merchant_mode, platform_id, is_primary, merchant_no, merchant_name, app_id, secret_key, api_base_url, sandbox_mode, status, remark) VALUES
(99999, 1, 'independent', NULL, 1, 'sandbox_wx_001', '测试小区物业', 'wx_sandbox_app', 'sandbox_wx_key', 'https://api.mch.weixin.qq.com/sandboxnew', 1, 'enabled', '沙箱测试-微信'),
(99999, 2, 'independent', NULL, 0, 'sandbox_ali_001', '测试小区物业', 'sandbox_ali_app', 'sandbox_ali_key', 'https://openapi.alipaydev.com/gateway.do', 1, 'enabled', '沙箱测试-支付宝');
```

---

### 3.2 小区业务场景配置表 (community_business_scene_config) - v1.1.2调整

#### 3.2.1 表说明
存储小区不同业务类型对应的支付方式配置。**每个小区的每种业务类型只能配置一种支付方式。**

#### 3.2.2 字段设计

| 字段名 | 类型 | 长度 | 允许空 | 默认值 | 说明 |
|-------|------|------|-------|-------|------|
| id | BIGINT | - | 否 | 自增 | 主键ID |
| community_id | BIGINT | - | 否 | - | 小区ID |
| business_type | VARCHAR | 32 | 否 | - | 业务类型:property_fee/parking/mall/special_service/value_added |
| provider_id | BIGINT | - | 否 | - | 支付服务商ID,外键关联payment_provider.id |
| payment_method_id | BIGINT | - | 是 | NULL | 支付方式ID,外键关联payment_method.id (可选) |
| payment_scene_id | BIGINT | - | 是 | NULL | 业务场景ID,外键关联payment_scene.id (可选) |
| status | VARCHAR | 20 | 否 | enabled | 状态:enabled(已启用)/disabled(已停用) |
| created_at | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | DATETIME | - | 否 | CURRENT_TIMESTAMP ON UPDATE | 更新时间 |
| remark | VARCHAR | 500 | 是 | NULL | 备注说明 |

#### 3.2.3 索引设计

| 索引名 | 索引类型 | 字段 | 说明 |
|-------|---------|------|------|
| PRIMARY | 主键 | id | 主键索引 |
| uk_community_business | 唯一索引 | community_id, business_type | 每个小区每种业务类型只能配置一种支付 |
| idx_provider_id | 普通索引 | provider_id | 服务商查询 |
| idx_status | 普通索引 | status | 状态查询 |

#### 3.2.4 外键约束

```sql
ALTER TABLE community_business_scene_config
ADD CONSTRAINT fk_community_business_provider
FOREIGN KEY (provider_id) REFERENCES payment_provider(id)
ON DELETE RESTRICT ON UPDATE CASCADE;

ALTER TABLE community_business_scene_config
ADD CONSTRAINT fk_community_business_method
FOREIGN KEY (payment_method_id) REFERENCES payment_method(id)
ON DELETE RESTRICT ON UPDATE CASCADE;

ALTER TABLE community_business_scene_config
ADD CONSTRAINT fk_community_business_scene
FOREIGN KEY (payment_scene_id) REFERENCES payment_scene(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
```

#### 3.2.5 示例数据

```sql
INSERT INTO community_business_scene_config (community_id, business_type, provider_id, payment_method_id, payment_scene_id, status, remark) VALUES
-- =============================================
-- 小区10001 阳光花园 - 子商户模式
-- 每个业务类型只配置一种支付方式
-- =============================================
(10001, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码-生活缴费'),
(10001, 'parking', 1, 1, 2, 'enabled', '停车费-微信公众号-普通商户'),
(10001, 'mall', 1, 3, 2, 'enabled', '商城-微信小程序-普通商户'),
(10001, 'special_service', 1, 2, 2, 'enabled', '特约服务-微信扫码-普通商户'),

-- =============================================
-- 小区10002 绿城花苑 - 独立商户模式
-- =============================================
(10002, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码-生活缴费'),
(10002, 'parking', 2, 4, 2, 'enabled', '停车费-支付宝扫码-普通商户'),

-- =============================================
-- 小区10003 碧水湾花园 - 混合商户模式
-- 不同业务使用不同服务商(体现混合模式)
-- =============================================
(10003, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码(子商户)-生活缴费'),
(10003, 'parking', 2, 5, 2, 'enabled', '停车费-支付宝H5(独立商户)-普通商户'),
(10003, 'mall', 1, 3, 2, 'enabled', '商城-微信小程序(子商户)-普通商户'),
(10003, 'value_added', 2, 4, 2, 'enabled', '增值服务-支付宝扫码(独立商户)-普通商户'),

-- =============================================
-- 小区10004 翡翠城 - 混合商户模式(另一组合)
-- =============================================
(10004, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码(独立商户)-生活缴费'),
(10004, 'parking', 4, 8, 2, 'enabled', '停车费-银联云闪付(独立商户)-普通商户'),

-- =============================================
-- 小区10005 江南水乡 - 华东区域,子商户模式
-- =============================================
(10005, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码-生活缴费'),
(10005, 'parking', 1, 3, 2, 'enabled', '停车费-微信小程序-普通商户'),
(10005, 'mall', 5, 9, 2, 'enabled', '商城-拉卡拉聚合-普通商户'),

-- =============================================
-- 小区10006 中央公馆 - 总部直营,独立商户
-- =============================================
(10006, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码-生活缴费(总部)'),
(10006, 'parking', 1, 1, 2, 'enabled', '停车费-微信公众号(总部)-普通商户'),
(10006, 'mall', 2, 4, 2, 'enabled', '商城-支付宝扫码(总部)-普通商户'),
(10006, 'value_added', 2, 5, 2, 'enabled', '增值服务-支付宝H5(总部)-普通商户'),

-- =============================================
-- 小区10007 锦绣园 - 子商户模式,有停用配置
-- =============================================
(10007, 'property_fee', 1, 2, 1, 'enabled', '物业费-微信扫码(使用中)'),
(10007, 'parking', 1, 1, 2, 'disabled', '停车费-微信公众号(已停用)'),

-- =============================================
-- 小区99999 测试小区 - 沙箱环境
-- =============================================
(99999, 'property_fee', 1, 2, 2, 'enabled', '测试-物业费-微信扫码'),
(99999, 'parking', 2, 4, 2, 'enabled', '测试-停车费-支付宝扫码');
```

---

## 四、业务流程

### 4.1 配置小区主支付流程 (v1.1调整)

```
运营平台管理员
  │
  ├─ 1. 进入"小区支付配置"模块
  │
  ├─ 2. 选择要配置的小区
  │
  ├─ 3. 选择运营平台 (v1.1新增)
  │    └─ 下拉列表显示该小区所属的运营平台
  │
  ├─ 4. 点击"配置主支付"按钮
  │
  ├─ 5. 选择支付服务商
  │    └─ 仅显示该运营平台已配置的服务商
  │
  ├─ 6. 填写子商户信息
  │    ├─ 输入子商户号 (从服务商处获取)
  │    ├─ 输入子商户名称
  │    ├─ 输入子商户应用ID (如需要)
  │    └─ 设置回调地址 (可选)
  │
  ├─ 7. 点击"测试连接"验证配置
  │    ├─ 系统调用服务商接口测试
  │    ├─ 成功:提示"连接测试成功"
  │    └─ 失败:提示具体错误原因
  │
  ├─ 8. 点击"保存"
  │    ├─ 系统验证表单
  │    ├─ 如果之前有主支付,自动将其改为非主支付
  │    ├─ 保存新配置为主支付 (is_primary=1)
  │    └─ 保存成功,返回列表页
  │
  └─ 9. 继续配置业务场景
```

### 4.2 配置小区业务场景流程

```
运营平台管理员
  │
  ├─ 1. 进入小区详情页
  │
  ├─ 2. 切换到"业务场景配置"Tab
  │
  ├─ 3. 点击"添加业务场景配置"按钮
  │
  ├─ 4. 在弹窗中配置
  │    ├─ 选择业务类型 (物业费/停车费/商城等,已配置的类型不可选)
  │    ├─ 选择支付服务商 (仅显示该小区已配置的服务商)
  │    ├─ 选择支付方式 (可选,显示该服务商支持的支付方式)
  │    └─ 选择业务场景 (可选,显示该服务商支持的业务场景)
  │
  ├─ 5. 点击"确定"
  │    ├─ 系统验证表单
  │    ├─ 检查业务类型是否已配置
  │    └─ 保存成功,刷新列表
  │
  └─ 6. 如需更换支付方式,删除原配置后重新添加
```

### 4.3 支付路由流程 (v1.1.2简化)

```
业务系统
  │
  ├─ 1. 调用支付中台下单接口
  │    └─ 传递: community_id, business_type, amount, user_id
  │
  ▼
支付中台 - 路由服务
  │
  ├─ 2. 接收请求参数
  │    ├─ community_id: 小区ID
  │    └─ business_type: 业务类型
  │
  ├─ 3. 查询小区支付配置
  │    └─ SELECT * FROM community_payment_config
  │        WHERE community_id = ? AND is_primary = 1
  │    └─ 获取 platform_id, provider_id (v1.1新增)
  │
  ├─ 4. 查询业务场景配置 (v1.1.2简化)
  │    └─ SELECT * FROM community_business_scene_config
  │        WHERE community_id = ? AND business_type = ?
  │        AND status = 'enabled'
  │    └─ 每个业务类型仅有一条配置
  │
  ├─ 5. 获取运营平台服务商配置 (v1.1新增)
  │    ├─ SELECT * FROM platform_provider_config
  │    │   WHERE platform_id = ? AND provider_id = ?
  │    ├─ 查询平台商户号、平台密钥、平台证书
  │    └─ 合并子商户配置
  │
  ├─ 6. 返回路由结果
  │    ├─ platform_id (v1.1新增)
  │    ├─ provider_id
  │    ├─ provider_code
  │    ├─ payment_method_id
  │    ├─ payment_method_code
  │    ├─ payment_scene_id
  │    ├─ platform_merchant_no (v1.1新增)
  │    ├─ platform_app_id (v1.1新增)
  │    ├─ sub_merchant_no
  │    └─ notify_url
  │
  ▼
业务系统
  └─ 使用路由结果继续支付流程
```

---

## 五、v1.0到v1.1数据迁移

### 5.1 迁移步骤

```sql
-- 步骤1: 为现有小区配置补充platform_id
-- 假设所有现有小区都属于默认运营平台(platform_id=1)
UPDATE community_payment_config
SET platform_id = (SELECT id FROM operation_platform WHERE platform_code = 'default_platform')
WHERE platform_id IS NULL;

-- 步骤2: 删除community_name字段(如需保留数据,先备份)
-- 备份
CREATE TABLE community_payment_config_backup AS
SELECT * FROM community_payment_config;

-- 删除字段
ALTER TABLE community_payment_config
DROP COLUMN community_name;

-- 步骤3: 调整唯一索引
ALTER TABLE community_payment_config
DROP INDEX uk_community_provider;

ALTER TABLE community_payment_config
ADD UNIQUE INDEX uk_platform_community_provider (platform_id, community_id, provider_id);

-- 步骤4: 增加外键约束
ALTER TABLE community_payment_config
ADD CONSTRAINT fk_community_platform
FOREIGN KEY (platform_id) REFERENCES operation_platform(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
```

### 5.2 迁移验证

```sql
-- 验证1: 检查所有记录都有platform_id
SELECT COUNT(*) FROM community_payment_config WHERE platform_id IS NULL;
-- 结果应该为0

-- 验证2: 检查唯一索引
SHOW INDEX FROM community_payment_config WHERE Key_name = 'uk_platform_community_provider';

-- 验证3: 检查外键约束
SELECT * FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'community_payment_config'
AND REFERENCED_TABLE_NAME = 'operation_platform';
```

---

## 六、异常处理

### 6.1 配置异常

| 异常场景 | 处理方式 |
|---------|---------|
| 小区未选择运营平台 | 提示"请选择运营平台" |
| 选择的服务商不在运营平台配置中 | 提示"该运营平台未配置该服务商,请先在运营平台中配置" |
| 小区重复配置同一服务商 | 提示"该服务商已配置,请勿重复添加" |
| 子商户号格式错误 | 提示"子商户号格式不正确" |
| 测试连接失败 | 提示具体错误,不允许保存 |
| 修改主支付时已有主支付 | 自动将原主支付改为非主支付,提示用户确认 |
| 删除正在使用的配置 | 提示"该配置正在使用中,无法删除" |

### 6.2 路由异常

| 异常场景 | 处理方式 |
|---------|---------|
| 小区未配置任何支付方式 | 返回错误码+错误信息 |
| 指定的支付方式不在配置中 | 返回错误码+错误信息 |
| 业务类型无可用配置 | 回退到主支付配置 |
| 主支付配置被停用 | 返回错误码+错误信息 |
| 运营平台服务商配置缺失 | 返回错误码+错误信息 |
| 服务商配置缺失 | 返回错误码+错误信息 |

---

## 七、数据约束

### 7.1 必填字段

**小区支付配置**
- 运营平台ID (v1.1新增)
- 小区ID
- 支付服务商ID
- 子商户号
- 子商户名称

**业务场景配置**
- 小区ID
- 业务类型
- 支付服务商ID
- 优先级

### 7.2 唯一性约束

| 表 | 唯一性约束 |
|----|-----------|
| community_payment_config | platform_id + community_id + provider_id (v1.1调整) |
| community_business_scene_config | community_id + business_type + provider_id + payment_method_id |

### 7.3 外键约束

| 表 | 外键字段 | 引用表 | 引用字段 | 删除规则 |
|----|---------|--------|---------|---------|
| community_payment_config | platform_id | operation_platform | id | RESTRICT |
| community_payment_config | provider_id | payment_provider | id | RESTRICT |
| community_business_scene_config | provider_id | payment_provider | id | RESTRICT |
| community_business_scene_config | payment_method_id | payment_method | id | RESTRICT |
| community_business_scene_config | payment_scene_id | payment_scene | id | RESTRICT |

---

## 八、与其他模块的关系

### 8.1 依赖关系

本模块依赖以下模块:

1. **运营平台管理模块** (v1.1新增)
   - 引用 operation_platform (选择运营平台)

2. **支付渠道管理模块**
   - 引用 payment_provider (选择支付服务商)
   - 引用 payment_method (选择支付方式)
   - 引用 payment_scene (选择业务场景)
   - 引用 platform_provider_config (获取运营平台服务商配置) (v1.1新增)

### 8.2 被依赖关系

本模块被以下模块依赖:

1. **支付交易管理模块**
   - 调用路由服务获取支付配置
   - 使用子商户号发起支付

2. **用户签约管理模块**
   - 查询小区配置的支付服务商
   - 验证签约支付方式是否可用

3. **流水与对账模块**
   - 查询小区配置信息用于数据展示

4. **支付报表模块**
   - 按小区统计支付数据

### 8.3 数据流向

```
运营平台管理
  │
  └─ 提供运营平台信息
       ↓
支付渠道管理
  │
  └─ 提供服务商、支付方式、业务场景信息
       ↓
小区支付配置 (配置小区使用的支付方式)
  │
  └─ 提供路由结果
       ↓
支付交易管理 (使用路由结果发起支付)
```

---

## 九、验收标准

### 9.1 功能验收

- [ ] 支持为小区配置主支付服务商
- [ ] 支持选择运营平台 (v1.1新增)
- [ ] 仅显示该运营平台已配置的服务商 (v1.1新增)
- [ ] 支持为小区配置子商户信息
- [ ] 支持测试连接功能验证配置正确性
- [ ] 支持为小区配置业务场景 (每业务类型一种支付) (v1.1.2调整)
- [ ] 支持启用/停用配置
- [ ] 路由服务正确返回支付配置 (包含运营平台信息) (v1.1调整)
- [ ] 路由服务支持回退到主支付
- [ ] 所有配置操作记录日志
- [ ] v1.0数据成功迁移到v1.1 (v1.1新增)

### 9.2 性能验收

- [ ] 路由查询响应时间 ≤ 50ms (核心性能指标)
- [ ] 配置列表查询响应时间 ≤ 200ms
- [ ] 配置保存响应时间 ≤ 300ms
- [ ] 支持10000+小区配置

### 9.3 安全验收

- [ ] 子商户密钥加密存储
- [ ] 密钥显示时脱敏
- [ ] 关键操作记录审计日志
- [ ] 路由服务防止SQL注入

---

## 十、FAQ

### 10.1 为什么要区分主支付和业务场景配置?

**回答**:
- **主支付**: 是小区的默认支付方式,大部分业务场景都会使用,简化配置
- **业务场景配置**: 针对特定业务使用不同的支付方式,提供灵活性

例如:小区主支付是微信,大部分业务用微信;但停车费可以单独配置支付宝。

### 10.2 路由服务如何选择支付方式?

**回答**: 根据小区ID和业务类型直接获取唯一的支付配置,每个业务类型只能配置一种支付方式。

### 10.3 可以为同一业务配置多个支付方式吗? (v1.1.2调整)

**回答**: 不可以。每个业务类型只能配置一种支付方式,如需更换,需先删除原配置再添加新配置。

### 10.4 如果小区未配置某个业务类型会怎样?

**回答**: 系统会回退到主支付配置,使用主支付服务商的默认支付方式。这样可以保证即使没有配置业务场景,也能正常支付。

### 10.5 v1.1版本中运营平台如何选择? (新增)

**回答**:
- 小区配置时需要选择所属运营平台
- 选择运营平台后,只能配置该运营平台已配置的服务商
- 一个小区只能属于一个运营平台
- 不同运营平台的小区使用各自平台的商户号

### 10.6 v1.0数据如何迁移到v1.1? (新增)

**回答**:
- 系统会自动创建"默认运营平台"
- 所有现有小区配置都关联到默认运营平台
- payment_provider表的平台配置迁移到platform_provider_config表
- 删除community_name冗余字段,查询时JOIN获取
- 详见"五、v1.0到v1.1数据迁移"章节

### 10.7 小区可以配置多个支付服务商吗? (v1.1.1新增)

**回答**: 可以。小区可以配置多个支付服务商的子商户信息,例如:
- 配置微信支付子商户 - 用于普通支付、生活缴费、牌照支付
- 配置易宝支付子商户 - 用于电子托收
- 配置支付宝子商户 - 用于商城购物

不同的服务商支持不同的业务场景,小区根据业务需要配置相应的服务商。

### 10.8 如何知道哪些业务场景可以开通? (v1.1.1新增)

**回答**: 系统会根据小区已配置的服务商自动判断:
- 普通支付/生活缴费/牌照支付 - 需要微信支付、支付宝或银联
- 电子托收 - 需要易宝支付或银联

在业务场景配置界面,未配置对应服务商的场景会显示为禁用状态,并提示需要配置哪个服务商。

### 10.9 父商户信息在哪里查看? (v1.1.1新增)

**回答**: 在小区配置支付服务商时,选择服务商后会自动显示运营平台在该服务商的父商户信息,包括:
- 父商户号
- 父商户名称
- 父应用ID

这些信息用于提醒管理员,子商户需要在该父商户下申请。

### 10.10 同一小区可以混合使用子商户和独立商户吗? (v1.1.2新增)

**回答**: 可以。v1.1.2版本支持同一小区对不同支付服务商使用不同的商户模式:

**场景示例:**
```
小区A 配置
├── 微信支付: 子商户模式 (挂靠华南运营平台,统一结算)
├── 支付宝: 独立商户模式 (小区自有商户号,独立结算)
└── 易宝托收: 子商户模式 (挂靠华南运营平台)
```

**适用场景:**
- 小区已有某渠道的独立商户资质
- 部分渠道需要独立结算,部分需要统一管理
- 历史原因导致不同渠道的开通方式不同

**注意事项:**
- 同一服务商仍只能配置一次(不能同时配置子商户和独立商户)
- 混合模式下,报表会分别统计不同模式的交易数据
- 建议统一主支付的商户模式,便于管理

| 版本 | 日期 | 修改人 | 修改内容 |
|------|------|-------|---------|
| v1.0 | 2026-02-25 | 产品经理 | 初始版本 |
| v1.1 | 2026-02-26 | 产品经理 | 1. 增加运营平台维度<br>2. community_payment_config表增加platform_id字段<br>3. 删除community_name冗余字段<br>4. 调整配置流程和路由逻辑<br>5. 调整唯一索引<br>6. 增加外键约束<br>7. 路由服务返回增加运营平台信息<br>8. 新增v1.0到v1.1数据迁移章节 |
| v1.1.1 | 2026-03-05 | 产品经理 | 1. 支持子商户模式和独立商户模式<br>2. 新增merchant_mode字段<br>3. platform_id改为可空(独立商户模式无需关联运营平台)<br>4. 重命名sub_merchant_no为merchant_no<br>5. 新增api_base_url、sandbox_mode字段(独立商户模式)<br>6. 调整路由逻辑支持两种商户模式<br>7. 更新页面交互支持商户模式切换<br>8. 更新FAQ增加商户模式相关问答 |
| v1.1.2 | 2026-03-06 | 产品经理 | 1. 支持混合商户模式:同一小区不同服务商可使用不同商户模式<br>2. 移除"同一小区同一服务商只能配置一种商户模式"限制<br>3. 列表页增加"混合模式"显示<br>4. 详情页增加配置概览区<br>5. 业务场景配置简化:每业务类型只能配置一种支付方式<br>6. 移除priority字段和优先级管理功能<br>7. 简化支付路由逻辑<br>8. 更新FAQ相关问答 |
| v1.2.0 | 2026-03-09 | 产品经理 | 1. 新增向导式配置流程,分步骤引导完成小区支付配置<br>2. 新增配置模板功能,支持从其他小区复制配置或使用预设模板<br>3. 新增配置健康检查功能,定期验证配置有效性并预警<br>4. 列表页增加健康状态显示(🟢🟡🔴⚪)<br>5. 新增批量测试连接功能<br>6. 数据库新增last_check_time、check_status、check_message字段<br>7. 新增idx_check_status索引 |
