mirror of
https://gitee.com/technical-laohu/mpay_v2_webman.git
synced 2026-03-25 20:24:27 +08:00
7.5 KiB
7.5 KiB
支付订单表设计说明
一、订单表设计原因
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 退款相关字段
如果后续需要支持部分退款或多次退款,可以考虑添加:
`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 结算相关字段
如果后续需要分账/结算功能,可以考虑添加:
`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 风控相关字段
如果需要风控功能,可以考虑添加:
`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:关闭原因(用户取消/超时/管理员关闭等)
四、设计原则总结
- 幂等性:通过
uk_mch_order_no保证同一商户下订单号唯一 - 可追溯性:记录完整的订单信息、渠道信息、时间信息
- 可扩展性:通过
extraJSON 字段存储扩展信息 - 性能优化:合理的索引设计,支持常见查询场景
- 业务完整性:覆盖订单全生命周期(创建→支付→退款→关闭)
五、与代码的对应关系
| 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) |
六、注意事项
- 字段命名统一:SQL 和代码中的字段名必须一致
- 索引维护:定期检查索引使用情况,优化慢查询
- 数据归档:历史订单数据量大时,考虑归档策略
- JSON 字段:
extra字段使用 JSON 类型,便于扩展但查询性能略低 - 时间字段:
pay_time、expire_time等时间字段使用datetime类型,便于查询和统计