💳 支付核心流程设计
本章详述即时配送小程序的支付核心流程,包括:微信支付对接、支付回调处理、支付状态机、超时关单逻辑、资金流向设计,以及相关数据表结构。
支付安全必选
微信支付
T+1结算
安全提示:支付是核心金融链路,必须保证幂等性、防止重复扣款、做好回调验签、保障资金安全。所有支付操作必须记录审计日志。
一、支付流程详细时序图
1.1 用户下单支付流程
sequenceDiagram
participant U as 用户
participant APP as 微信小程序
participant API as 后端服务
participant PAY as 微信支付
participant DB as 数据库
U->>APP: 选择支付方式下单
APP->>API: 创建订单请求
API->>DB: 写入订单(状态:待支付)
DB-->>API: 订单创建成功
API-->>APP: 返回订单号order_id
APP->>PAY: 调起微信支付统一下单API
PAY-->>APP: 返回预支付会话标识prepay_id
APP->>PAY: 调起微信支付收银台
PAY-->>U: 展示支付界面
U-->>PAY: 输入密码确认支付
PAY-->>API: 支付结果通知回调
API->>API: 验签(异步)
API->>DB: 更新订单状态(已支付)
API->>DB: 记录支付流水
API-->>PAY: 返回SUCCESS确认
PAY-->>APP: 支付成功回调
APP-->>U: 展示支付成功页面
1.2 支付状态机
stateDiagram-v2
[*] --> 待支付: 创建订单
待支付 --> 支付中: 用户发起支付
待支付 --> 已取消: 超时取消/用户取消
支付中 --> 已支付: 回调成功
支付中 --> 待支付: 支付失败
支付中 --> 已取消: 支付取消
已支付 --> 已完成: 确认收货
已支付 --> 已退款: 申请退款
已取消 --> [*]
已完成 --> [*]
已退款 --> [*]
1.3 超时自动关单逻辑
订单创建(待支付) → 启动30分钟倒计时
→ 用户支付成功 → 取消关单
→ 30分钟无支付 → 触发关单
→ 调用微信支付关单API
→ 更新订单状态为"已取消"
→ 释放库存(如已锁定)
二、担保交易资金流向设计
2.1 资金流向图
flowchart LR
subgraph 用户侧
U[用户付款]
end
subgraph 微信支付
PAY[微信支付
资金托管]
end
subgraph 平台侧
PLAT[平台账户]
end
subgraph 骑手侧
C[骑手账户]
end
U -->|¥12.00| PAY
PAY -->|冻结| PLAT
PLAT -->|确认送达| PAY
PAY -->|¥9.60(80%)| C
PAY -->|¥2.40(20%)| PLAT
2.2 分账比例配置
| 角色 | 分账比例 | 说明 |
| 骑手 | 80% | 配送服务费 |
| 平台 | 20% | 平台服务费/抽成 |
* 分账比例可通过后台配置,支持按订单类型、骑手等级差异化设置
三、支付安全设计
3.1 微信支付验签流程
接收微信支付回调 → 判断通信是否成功
→ 验证签名(使用API密钥+应答原文)
→ 验证订单号+金额+支付状态
→ 处理业务逻辑(更新订单)
→ 返回SUCCESS(否则微信会多次通知)
3.2 幂等性保证
| 场景 | 幂等方案 |
| 创建订单 | 前端生成唯一order_id,后端检查是否存在 |
| 支付回调 | 使用transaction_id作为幂等键,已处理则直接返回SUCCESS |
| 关闭订单 | 先查询订单状态,已关闭则直接返回成功 |
3.3 风控规则
| 规则 | 触发条件 | 处理方式 |
| 单笔限额 | 单笔超过5000元 | 提示限额,需拆单 |
| 日累计限额 | 单用户日累计超过20000元 | 暂停支付,提示客服 |
| 异地登录 | IP地址与常用地不符 | 增加验证码校验 |
| 频繁失败 | 5分钟内连续失败3次 | 锁定15分钟后重试 |
四、支付相关数据表
4.1 支付流水表 ot_payment
| 字段 | 类型 | 说明 |
| id | bigint | 主键 |
| payment_no | varchar(32) | 支付单号(平台生成) |
| order_id | bigint | 关联订单ID |
| user_id | bigint | 用户ID |
| transaction_id | varchar(64) | 微信支付订单号 |
| pay_type | tinyint | 支付类型(1微信/2余额) |
| amount | decimal(10,2) | 支付金额 |
| status | tinyint | 状态(0待支付/1已支付/2已取消) |
| pay_time | datetime | 支付时间 |
| notify_time | datetime | 回调通知时间 |
| notify_raw | text | 回调原始数据 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
4.2 订单表(支付相关字段)
| 字段 | 类型 | 说明 |
| order_no | varchar(32) | 订单号 |
| pay_status | tinyint | 支付状态(0待支付/1已支付/2已取消/3已退款) |
| total_amount | decimal(10,2) | 订单总金额 |
| pay_amount | decimal(10,2) | 实付金额 |
| coupon_amount | decimal(10,2) | 优惠券减免 |
| platform_fee | decimal(10,2) | 平台抽成 |
| courier_fee | decimal(10,2) | 骑手收入 |
| pay_time | datetime | 支付时间 |
| expire_time | datetime | 支付过期时间 |
4.3 用户钱包表 ot_wallet
| 字段 | 类型 | 说明 |
| id | bigint | 主键 |
| user_id | bigint | 用户ID |
| balance | decimal(12,2) | 账户余额 |
| freeze_balance | decimal(12,2) | 冻结金额 |
| total_recharge | decimal(12,2) | 累计充值 |
| total_consume | decimal(12,2) | 累计消费 |
| pay_password | varchar(64) | 支付密码(加密) |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
4.4 钱包流水表 ot_wallet_log
| 字段 | 类型 | 说明 |
| id | bigint | 主键 |
| log_no | varchar(32) | 流水号 |
| user_id | bigint | 用户ID |
| type | tinyint | 类型(1充值/2消费/3退款/4提现) |
| amount | decimal(10,2) | 变动金额 |
| balance_before | decimal(12,2) | 变动前余额 |
| balance_after | decimal(12,2) | 变动后余额 |
| source_type | varchar(20) | 来源类型(order/refund/recharge) |
| source_id | bigint | 来源ID |
| remark | varchar(200) | 备注 |
| created_at | datetime | 创建时间 |
五、支付核心API
| 接口 | 说明 | 关键参数 |
POST /app/ot/payment/create | 创建支付订单 | order_id, pay_type |
GET /app/ot/payment/status | 查询支付状态 | order_id |
POST /app/ot/payment/cancel | 取消支付 | order_id |
POST /app/ot/wallet/recharge | 钱包充值 | amount, pay_type |
POST /app/ot/wallet/withdraw | 钱包提现 | amount, bank_card |
GET /app/ot/wallet/info | 钱包信息 | - |
GET /app/ot/wallet/logs | 钱包流水 | page, size |
六、骑手钱包与结算
6.1 骑手钱包表 ot_courier_wallet
| 字段 | 类型 | 说明 |
| id | bigint | 主键 |
| courier_id | bigint | 骑手ID |
| balance | decimal(12,2) | 可提现余额 |
| freeze_balance | decimal(12,2) | 冻结金额(提现中) |
| total_income | decimal(12,2) | 累计收入 |
| total_withdraw | decimal(12,2) | 累计提现 |
| bank_account | varchar(32) | 银行账户 |
| bank_name | varchar(64) | 开户行 |
| created_at | datetime | 创建时间 |
| updated_at | datetime | 更新时间 |
6.2 骑手收入流水表 ot_courier_income_log
| 字段 | 类型 | 说明 |
| id | bigint | 主键 |
| log_no | varchar(32) | 流水号 |
| courier_id | bigint | 骑手ID |
| order_id | bigint | 订单ID |
| type | tinyint | 类型(1配送收入/2平台奖励/3罚款/4提现) |
| amount | decimal(10,2) | 金额 |
| balance_before | decimal(12,2) | 变动前余额 |
| balance_after | decimal(12,2) | 变动后余额 |
| remark | varchar(200) | 备注 |
| created_at | datetime | 创建时间 |
6.3 骑手结算规则
- 结算周期:T+1 结算(完成配送后次日可提现)
- 收入计算:配送费 × 80%(分账比例)
- 提现规则:最低提现50元,单笔最高5000元
- 提现审核:大额提现(>1000元)需人工审核
- 异常扣款:差评扣50元/次,投诉扣100元/次
文档同步:requirements_v2.md 支付模块 | 维护:项目团队