一、什么是掉单
在任何交易场景中,大家有些人经常会听到 掉单 该问题词汇,那什么是掉单呢?
大家应该都有购物过,当你支付成功后,但订单详情页的订单状态没有扭转为已支付状态 ,这种情况统称为:掉单
二、掉单的影响
而这种异常现象,导致的业务影响有哪些呢:
1) 客诉反馈
2) 订单退款
3) 投诉平台
用户内心旁白:我被骗钱了,而且有证据 ,送商家一个12315
三、为什么会掉单
那好好滴为什么无缘无故会掉单呢?上交易流程图【当前流程我们只考虑支付成功场景】
1.用户下单:用户在应用内选择商品发起下单
2.平台发起支付:商家平台向支付渠道商发起支付,生成支付页
3.拉起支付页:与用户拉起支付页,并支付成功
4.支付回调: 支付渠道通知商家平台服务端订单支付成功
5.渠道验单:商家平台调用渠道接口进行检查订单状态是否为已支付
6.更新订单状态:扭转为已支付
7.支付完成. 返回到应用内
8.订单详情页查询支付结果
流程:
1.用户下单:用户在应用内选择商品发起下单
2.平台发起支付:商家平台向支付渠道商发起支付,生成支付页
3.拉起支付页:与用户拉起支付页,并支付成功
4.支付回调: 支付渠道通知商家平台服务端订单支付成功
5.渠道验单:商家平台调用渠道接口进行检查订单状态是否为已支付
6.更新订单状态:扭转为已支付
7.支付完成. 返回到应用内
8.订单详情页查询支付结果
其中有4个标红流程,都会让用户感觉是 掉单现象
支付回调通知异常
支付渠道 因 (1/ 自身网络问题 2/ 商家平台宕机 )等异常情况,导致通知失败
渠道验单异常
平台商家 因 (1/ 自身网络问题 2/ 渠道接口异常 3/ 渠道订单状态延迟..)等异常情况,导致查询不到订单准确的状态
更新订单状态异常
支付服务通知订单服务更新订单状态(1/ 自身服务内部DB异常 2/内网通信异常 ),导致更新订单失败
订单详情页查询支付结果异常
客户端 因 (1/ 用户网络问题 2/ 商家平台接口异常 ),导致获取订单状态异常
四、掉单措施
有哪些优化措施解决掉单问题,首先针对上面的问题我们分为两类:
1)内部掉单:平台内部运行异常导致掉单 ,如:更新订单状态异常,订单详情页查询支付结果异常
2)外部掉单:平台跟外部渠道通信异常导致掉单,如:渠道验单异常,支付回调通知异常
1) 如何防止内部掉单
回顾内部掉单场景1: 更新订单异常
支付服务和订单服务之间防止掉单,关键就在于尽可能保证支付通知订单支付结果成功,我们一般通过这两种方式:
打法:异步补偿 + 网络异常重试
目的:提高投递可靠性
异步补偿 :
- 在原有的同步更新订单状态下,我们新增一个异步入队列的行为
- 再起一个任务去订阅支付成功队列:检查是否订单是否已经支付成功,如果未扭转成功,则进行订单状态补偿处理
网络异常重试:
- 支付服务调用订单服务的时候,要进行失败重试,防止网络抖动情况下的调用失败。
回顾内部掉单场景2 :订单详情页查询订单状态异常
查询订单详情,主要的目的是让用户更加快速的感知的订单的支付情况。
目的:主要降低用户对订单状态的误导
打法:网络异常重试 + 合理引导 + 支持主动查询 + 异步推送支付结果
1)网络异常重试:客户端调用订单服务的时候,要进行失败重试,防止网络抖动情况下的调用失败。
2)合理引导:如果因网络或订单内部异常订单详情页应该合理引导,减少用户的错误理解:
- 订单详情页呈现:支付处理中,禁止直接呈现未支付或支付失败
3)支持主动查询:允许用户主动刷新订单状态
4)异步推送支付结果:支付详情页查询订单异常行为,则存储到本地内存,在定时查询订单状态,直到查到准确的支付成功订单状态,再异步推送知用户。
注意事项: 1.需要考虑业务产品的推送方式和时机 2.本地内存的订单维护-不细讲
2) 如何防止外部掉单
相较于内部掉单嘛,外部掉单的概率就大很多哦,毕竟和外部渠道的对接,有好多不可控的因素呢!
比如说网络抽风,服务崩溃,还有订单状态迟迟不更新之类的问题~
虽然不可控因数很多,但要防止外部掉单,其实有一个超级重要的秘诀,就是"主动查询"啦!不要只等第三方的通知回调,那风险可是挺高的。我们支付服务要主动去问第三方支付状态,这样哪怕出现异常情况,我们也能及时发现~
主动查询呢,大概有两种的措施:
措施1:定时查询
主要定时将支付中的订单主动去跟支付渠道获取最新第三方的支付状态,并更新订单状态
定时任务确实是一种简单的方式来进行支付状态查询,但也存在一些问题注意事项:
-
定时任务频率:
- 问题:如果时间设置的较长,会影响导致查询支付结果不够实时,如果设置的时间较短,又会导致DB的压力过大
- 措施:最好做一些频率递减策略【举例:第1次查询 = 延迟1分钟,第2次查询 = 延迟4分钟 ,第n次 = 延迟n * n分钟】
-
数据库压力:
- 问题:定时扫表毕竟还是会对数据库产生一定的压力,如果订单数据量过大,压力会更加明细,直接影响订单表相关业务
- 措施:拆一个订单临时表,如果查询到订单状态就删除记录(压力转移)
措施2:延迟查询
主要在用户每次下单的时候生成一个延迟队列, 再异步消费延迟队列查询订单状态,如果还是查询不到最终的订单状态则继续丢入延迟队列继续处理,延迟策略可参考【举例:第1次查询 = 延迟1分钟,第2次查询 = 延迟4分钟 ,第n次 = 延迟n * n分钟】】
这种延迟队列方案有对应的好处:
-
无需扫表,数据库压力较低(1.走订单号索引,2.有延迟策略)
-
时效性会更好点
以上是针对不同掉单场景的处理方案,当然我们在对订单做异步处理时,一定要考虑好订单的原子性哈
总结
支付掉单主要分为两类:内部掉单和外部掉单
内部掉单分为两个场景
-
更新订单异常场景,措施:当网络出现异常时进行重试;同时,可以利用异步队列补偿机制,确保订单的更新操作能够成功完成
-
查询订单异常场景,措施:当网络出现异常时同样要重试;合理引导用户感知支付结果,支持用户主动查询订单状态,并通过异步推送支付结果的方式,让用户及时了解支付的结果
而外部掉单的解决关键在于主动查询 , 我们有两种常用的方案可供选择:定时任务查询和延时消息查询。定时任务查询相对来说更简单直接,而延时消息查询在功能上更加出色,为用户提供更优质的体验。
因此,无论是内部掉单还是外部掉单,我们都有解决办法来应对,确保支付过程的顺利进行。
参考
解决支付掉单问题 www.woshipm.com/pd/4213699....