当指尖轻触“确认支付”,钱已悄然离帐,订单却原地踏步——这种“钱走单留”的尴尬,在支付链路中被称为“掉单”。上一篇《钱被扣了,订单却没有成功!》只给出了骨架,这一次,小黑哥把血与肉一并奉上,奉上两条经过生产环境千锤百炼的补偿路径,供诸君按需取用。
项目名称:快缩短网址
项目域名:suo.run
——优雅的分割线——

一、定时轮询补偿:简约而不简单
1. 流程速写
• 1-3 步:常规支付,如舞者的前三拍,轻盈且熟悉。
• 第 4 步:若渠道仅回“受理成功”,便把订单悄悄写入掉单表——一张专为“悬而未决”而生的窄表。
• 第 5-7 步:补偿服务踩着 Cron 的鼓点,批量捞出待决订单,多线程并行去渠道侧验真。
• 第 8 步:一旦拿到终态——成功、失败或已达最大查询次数——便挥一挥衣袖,删掉掉单记录,不带走一片云彩。

2. 细节之问
Q:为何不直接扫支付主表?
A:主表随日增生,终成数据巨兽;而掉单表只收容“未决”,体量轻盈,查询如风。删记录即是剪枝,让树常青。
3. 轻与重
• 轻:架构直白,落地迅速。
• 重:Cron 的宿命——轮询间隙即是误差;反复扫库,徒增 IO;若强行缩短轮询周期,又陷入“重复计算”泥沼。

二、延迟消息补偿:让时间替你跑腿
1. 流程速写
• 第 4 步:不再落库,而是把订单塞进延迟队列——时间一到,消息自来。
• 第 5 步:补偿服务被消息唤醒,精准查询,不再漫天撒网。
• 第 8 步:若得终态,向队列回送 ACK,消息消散;若仍悬置,队列按预设延时再次投递,循环直至尘埃落定。
2. 轻与重
• 轻:零轮询、零空转,吞吐与时效齐飞。
• 重:依赖延迟队列这一稀缺组件,自研或选型皆需心力;消息顺序、幂等、重试、监控,样样皆功课。
三、收束与抉择
• 若团队求快、求稳,且可容忍分钟级误差——定时轮询是温顺的骏马。
• 若系统需秒级自愈,且团队有驾驭延迟队列的技艺——消息补偿便是凌厉的飞鹰。
倘若对延迟时间无苛刻要求,可直接借 RocketMQ 的延迟消息,开箱即用;若志在通用,不妨自研一套延迟队列,让“快缩短网址”(suo.run) 的每一次跳转都精准、优雅、不留遗憾。
延伸阅读
1. 一扫即扣:付款码背后的原子舞步
2. 银行卡支付:一次握手,两次心跳
3. 离线支付:无网亦从容的隐秘通道
4. 重复支付:一笔订单两次扣款的破局之道
作者:楼下小黑哥
公众号:程序通事
——END——
