退款不翻车:从两步确认到自动回滚的工程实践
退款不翻车:从两步确认到自动回滚的工程实践
收银员小王手一抖,把一笔128元的订单退了。
老板问:“能撤回吗?”
小王说:“已经退了……”
老板叹气:“退款这事儿,能不能慢一点?”
01 钱的事,不能快
退款是收银系统最危险的操作。龙讯POS的退款设计原则:能慢就慢,能确认就确认,能校验就校验。
02 两步确认
- 发起退款:选择要退的菜品,选择退款原因(按钮选择,非手打),系统自动计算可退金额
- 确认退款:核对信息,点击"确认退款",系统调用支付平台原路退回
退款原因按钮选择:客户要求退款、菜品质量问题、上错菜、重复下单、价格异议、其他原因。
03 原路退回
电子支付走支付平台退款API,现金只记录退款记录。混合支付按比例分配退款到各渠道。
04 技术实现:事务重试 + 回滚
事务重试:3次指数退避
扫码支付成功但数据库事务失败时,200ms→400ms→600ms重试3次。全部失败则自动Cancel撤销支付,防止"钱扣了但订单没更新"。
混合支付回滚
逐渠道执行支付,任一渠道失败则回滚已完成渠道:
- 现金渠道:标记
rollback_pending(无法自动回滚) - 电子渠道:Cancel(撤销)→ Refund(退款)→ rollback_pending
退款回滚
退款失败时,回滚退款记录和订单状态,保证数据一致性。
退款分配
前N-1个渠道按比例分配退款金额,最后一个渠道分配剩余金额,消除浮点舍入误差。
05 退款时限
默认支付完成后1小时内可退款(可配置),团购订单不受时限限制。
06 部分退款
支持按菜品项退款,折扣按比例分配。
07 总结
| 机制 | 解决的问题 |
|---|---|
| 两步确认 | 防止手滑误退 |
| 事务重试 | 钱扣了但订单没更新 |
| 混合支付回滚 | 部分渠道成功部分失败 |
| 退款回滚 | 退款失败但记录已创建 |
| 最后渠道兜底 | 浮点舍入误差 |
支付系统的可靠性,不在于"正常流程多顺畅",而在于"异常流程多安全"。
下期预告:《团购核销的工程难题:从短链解析到智能匹配》