更新数据库结构

This commit is contained in:
技术老胡
2026-03-10 13:47:28 +08:00
parent 54ad21ac8f
commit 9de902231f
54 changed files with 5070 additions and 501 deletions

214
doc/order_table_design.md Normal file
View File

@@ -0,0 +1,214 @@
# 支付订单表设计说明
## 一、订单表设计原因
### 1.1 订单号设计(双重订单号)
**系统订单号 (`pay_order_id`)**
- **作用**:系统内部唯一标识,用于查询、对账、退款等操作
- **生成规则**`P` + `YYYYMMDDHHmmss` + `6位随机数`P20240101120000123456
- **唯一性**:通过 `uk_pay_order_id` 唯一索引保证
- **优势**
- 全局唯一,不受商户影响
- 便于系统内部查询和关联
- 对账时作为主键
**商户订单号 (`mch_order_no`)**
- **作用**:商户传入的订单号,用于幂等性校验
- **唯一性**:通过 `uk_mch_order_no(merchant_id, mch_order_no)` 联合唯一索引保证
- **优势**
- 同一商户下订单号唯一,防止重复提交
- 商户侧可以自定义订单号规则
- 支持商户订单号查询订单
**为什么需要两个订单号?**
- 系统订单号:保证全局唯一,便于系统内部管理
- 商户订单号:保证商户侧唯一,防止重复支付(幂等性)
### 1.2 关联关系设计
**商户与应用关联 (`merchant_id` + `app_id`)**
- **作用**:标识订单所属商户和应用
- **用途**
- 权限控制(商户只能查询自己的订单)
- 对账统计(按商户/应用维度)
- 通知路由(根据应用配置的通知地址)
**支付通道关联 (`channel_id`)**
- **作用**:记录实际使用的支付通道
- **用途**
- 退款时找到对应的插件和配置
- 对账时关联通道信息
- 统计通道使用情况
**支付方式与产品 (`method_code` + `product_code`)**
- **method_code**支付方式alipay/wechat/unionpay
- 用于统计、筛选、报表
- **product_code**支付产品alipay_h5/alipay_life/wechat_jsapi等
- 由插件根据用户环境自动选择
- 用于记录实际使用的支付产品
### 1.3 金额字段设计
**订单金额 (`amount`)**
- 商户实际收款金额(扣除手续费前)
- 用于退款金额校验、对账
**手续费 (`fee`)**
- 可选字段,记录通道手续费
- 用于对账、结算、利润统计
- 如果不需要详细记录手续费,可以留空或通过 `extra` 存储
**币种 (`currency`)**
- 默认 CNY支持国际化扩展
- 预留字段,便于后续支持多币种
### 1.4 状态流转设计
```
PENDING待支付
├─> SUCCESS支付成功← 收到渠道回调并验签通过
├─> FAIL支付失败← 用户取消、超时、渠道返回失败
└─> CLOSED已关闭← 全额退款后
```
**状态说明**
- **PENDING**:订单创建后,等待用户支付
- **SUCCESS**:支付成功,已收到渠道回调并验签通过
- **FAIL**:支付失败(用户取消、订单超时、渠道返回失败等)
- **CLOSED**:已关闭(全额退款后)
### 1.5 渠道信息设计
**渠道订单号 (`channel_order_no`)**
- 渠道返回的订单号
- 用于查询订单状态、退款等操作
**渠道交易号 (`channel_trade_no`)**
- 部分渠道有交易号概念(如支付宝的 trade_no
- 用于对账、查询等
### 1.6 通知机制设计
**通知状态 (`notify_status`)**
- 0未通知
- 1已通知成功
**通知次数 (`notify_count`)**
- 记录通知次数,用于重试控制
- 配合 `ma_notify_task` 表实现异步通知
### 1.7 扩展性设计
**扩展字段 (`extra`)**
- JSON 格式,存储:
- 支付参数(`pay_params`):前端支付所需的参数
- 退款信息(`refund_info`):退款结果
- 自定义字段:业务扩展字段
**订单过期时间 (`expire_time`)**
- 用于自动关闭超时订单
- 默认 30 分钟,可配置
## 二、索引设计说明
### 2.1 唯一索引
- **`uk_pay_order_id`**:保证系统订单号唯一
- **`uk_mch_order_no(merchant_id, mch_order_no)`**:保证同一商户下商户订单号唯一(幂等性)
### 2.2 普通索引
- **`idx_merchant_app(merchant_id, app_id)`**:商户/应用维度查询
- **`idx_channel_id`**:通道维度查询
- **`idx_method_code`**:支付方式维度统计
- **`idx_status`**:状态筛选
- **`idx_pay_time`**:按支付时间查询(对账、统计)
- **`idx_created_at`**:按创建时间查询(分页、统计)
## 三、可能遗漏的字段(后续扩展)
### 3.1 退款相关字段
如果后续需要支持**部分退款**或**多次退款**,可以考虑添加:
```sql
`refund_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '已退款金额(累计)',
`refund_status` varchar(20) NOT NULL DEFAULT '' COMMENT '退款状态PENDING-退款中, SUCCESS-退款成功, FAIL-退款失败',
`refund_time` datetime DEFAULT NULL COMMENT '最后退款时间',
```
**当前设计**
- 退款信息存储在 `extra['refund_info']`
- 全额退款后订单状态改为 `CLOSED`
- 如果只需要全额退款,当前设计已足够
### 3.2 结算相关字段
如果后续需要**分账/结算**功能,可以考虑添加:
```sql
`settlement_status` varchar(20) NOT NULL DEFAULT '' COMMENT '结算状态PENDING-待结算, SUCCESS-已结算, FAIL-结算失败',
`settlement_time` datetime DEFAULT NULL COMMENT '结算时间',
`settlement_amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '结算金额',
```
**当前设计**
- 结算信息可以通过 `extra` 存储
- 如果不需要复杂的结算流程,当前设计已足够
### 3.3 风控相关字段
如果需要**风控功能**,可以考虑添加:
```sql
`risk_level` varchar(20) NOT NULL DEFAULT '' COMMENT '风险等级LOW-低, MEDIUM-中, HIGH-高',
`risk_score` int(11) NOT NULL DEFAULT 0 COMMENT '风险评分',
`risk_reason` varchar(255) NOT NULL DEFAULT '' COMMENT '风险原因',
```
**当前设计**
- 风控信息可以通过 `extra` 存储
- 如果不需要复杂的风控系统,当前设计已足够
### 3.4 其他扩展字段
- **`user_id`**用户ID如果需要关联用户
- **`device_info`**:设备信息(用于风控)
- **`remark`**:备注(管理员备注)
- **`close_reason`**:关闭原因(用户取消/超时/管理员关闭等)
## 四、设计原则总结
1. **幂等性**:通过 `uk_mch_order_no` 保证同一商户下订单号唯一
2. **可追溯性**:记录完整的订单信息、渠道信息、时间信息
3. **可扩展性**:通过 `extra` JSON 字段存储扩展信息
4. **性能优化**:合理的索引设计,支持常见查询场景
5. **业务完整性**:覆盖订单全生命周期(创建→支付→退款→关闭)
## 五、与代码的对应关系
| SQL 字段 | 代码字段 | 说明 |
|---------|---------|------|
| `pay_order_id` | `pay_order_id` | 系统订单号 |
| `merchant_id` | `merchant_id` | 商户ID |
| `app_id` | `app_id` | 应用ID |
| `mch_order_no` | `mch_order_no` | 商户订单号 |
| `method_code` | `method_code` | 支付方式 |
| `product_code` | `product_code` | 支付产品 |
| `channel_id` | `channel_id` | 通道ID |
| `amount` | `amount` | 订单金额 |
| `currency` | `currency` | 币种 |
| `status` | `status` | 订单状态 |
| `channel_order_no` | `channel_order_no` | 渠道订单号 |
| `channel_trade_no` | `channel_trade_no` | 渠道交易号 |
| `extra` | `extra` | 扩展字段JSON |
## 六、注意事项
1. **字段命名统一**SQL 和代码中的字段名必须一致
2. **索引维护**:定期检查索引使用情况,优化慢查询
3. **数据归档**:历史订单数据量大时,考虑归档策略
4. **JSON 字段**`extra` 字段使用 JSON 类型,便于扩展但查询性能略低
5. **时间字段**`pay_time``expire_time` 等时间字段使用 `datetime` 类型,便于查询和统计