退款不翻车:从两步确认到自动回滚的工程实践

退款不翻车:从两步确认到自动回滚的工程实践

收银员小王手一抖,把一笔128元的订单退了。
老板问:“能撤回吗?”
小王说:“已经退了……”
老板叹气:“退款这事儿,能不能慢一点?”

01 钱的事,不能快

退款是收银系统最危险的操作。龙讯POS的退款设计原则:能慢就慢,能确认就确认,能校验就校验。

02 两步确认

  1. 发起退款:选择要退的菜品,选择退款原因(按钮选择,非手打),系统自动计算可退金额
  2. 确认退款:核对信息,点击"确认退款",系统调用支付平台原路退回

退款原因按钮选择:客户要求退款、菜品质量问题、上错菜、重复下单、价格异议、其他原因。

03 原路退回

电子支付走支付平台退款API,现金只记录退款记录。混合支付按比例分配退款到各渠道。

04 技术实现:事务重试 + 回滚

事务重试:3次指数退避

扫码支付成功但数据库事务失败时,200ms→400ms→600ms重试3次。全部失败则自动Cancel撤销支付,防止"钱扣了但订单没更新"。

混合支付回滚

逐渠道执行支付,任一渠道失败则回滚已完成渠道:

  • 现金渠道:标记 rollback_pending(无法自动回滚)
  • 电子渠道:Cancel(撤销)→ Refund(退款)→ rollback_pending

退款回滚

退款失败时,回滚退款记录和订单状态,保证数据一致性。

退款分配

前N-1个渠道按比例分配退款金额,最后一个渠道分配剩余金额,消除浮点舍入误差。

05 退款时限

默认支付完成后1小时内可退款(可配置),团购订单不受时限限制。

06 部分退款

支持按菜品项退款,折扣按比例分配。

07 总结

机制 解决的问题
两步确认 防止手滑误退
事务重试 钱扣了但订单没更新
混合支付回滚 部分渠道成功部分失败
退款回滚 退款失败但记录已创建
最后渠道兜底 浮点舍入误差

支付系统的可靠性,不在于"正常流程多顺畅",而在于"异常流程多安全"。


下期预告:《团购核销的工程难题:从短链解析到智能匹配》