一、前言
最近正在做电商相关的项目,整理一下解决方案并帮助自己巩固知识点,此方案是结合了目前的业务环境,若有更好的解决的方式很高兴与大家一起讨论。
二、什么是掉单
我们先看一下正常的支付流程:
- 首先创建订单。
- 用户进行支付。
- 系统接收三方支付回调信息。
- 系统处理回调信息。
那什么是掉单呢,掉单就是在我们支付后,系统没有及时的响应、收到订单的支付结果。例如在三方支付回调时
,因为其他原因没有收到信息。
三、什么情况下会出现掉单
我们逐一分析,订单创建、订单超时、用户支付、支付回调、回调处理这几个操作的先后顺序,分析掉单发生的情景。
1. 无支付情况
在这种情况下,订单会在创建后的30min
后自动超时,也就是失效(同时查询三方支付结果),修改订单状态。也就是说,掉单会发生在这30min
之内。
2. 正常情况
一切都在合理的时间内进行,没有异常,不会出现掉单的情况。
3. 回调延迟
当我们支付后,回调信息没有及时/处理回调信息,会出现掉单的情况,在图中选中的时间内,出现掉单的情况。(订单超时后会主动查询三方支付结果)
- 倘若在
服务端
是以微服务架构,系统在处理订单的状态,用户触发了查询。 - 倘若在
服务端
是以微服务架构,支付模块调用订单模块途中,用户触发了查询。 - 上图中
三方支付回调时
出现了异常
以上情况均会导致实际情况
与用户查询到的结果不一致,导致掉单
。
四、如何防止掉单
从问题的角度出发,分为两个方面,一是内部,另外一个是外部。
内部
内部也就是服务与服务之间进行的通讯,一般的,支付服务在收到三方回调结果后,会立即调用订单服务,但是这种调用存在失败的可能性,所以使用的方案是同步+异步。
在同步调用的同时,使用MQ消息的方式,往队列里添加支付成功的消息,订单服务去订阅消费(注意接口的幂等性),这样双重保障的方案保证支付结果正确传递。
外部
外部因为主要是因为三方回调没有调通,或者因为网络问题,接收不到信息等。因为我们在用户支付后,把这个消息
加入到队列中,每隔一段时间去查询当前订单的支付结果,保证在这个30min
中,防止意外情况没有更新到订单状态。