电商系统中的掉单问题

什么是掉单?
所谓掉单,就是指用户下单支付后,在钱包里完成了支付,结果回到电商系统中查看,订单还是处于未支付的状态 。
掉单的产生
用户从电商应用点击支付,客户端向服务端发起支付请求支付服务会向第三方的支付渠道发起支付,支付渠道会响应对应的 url以 APP 为例,客户端通常是会拉起对应的钱包,然后用户跳转到对应的钱包用户在钱包里完成支付用户在完成支付后,跳转回对应的电商 APP客户端轮询订单服务,获取订单状态支付渠道回调支付服务,通知支付结果支付服务通知订单服务,更新订单状态
对于支付订单而言,大体可划分为以下几种状态 。
在用户点击支付之后,支付服务请求支付渠道之前,处于未支付状态 。
在用户发起支付之后,跳转到支付钱包完成支付,支付服务获取到最终的支付结果之间,处于支付中状态 。在这个状态下,电商系统对于用户的支付结果是不确定的 。
电商系统最终确定了用户在第三方钱包的最终支付结果 。
综上所述,发生掉单就是因为支付状态没有同步,或者没有及时同步 。
发生了异常,导致支付服务没有收到支付渠道的回调通知 。
服务内部出现了异常,导致支付状态没有同步到订单服务 。
客户端通常是轮询获取状态,可能会在轮询期间内没有获取到订单状态,导致用户看到订单一直处于未支付状态 。
【电商系统中的掉单问题】其中第一类可以称之为外部掉单,其余的可以称之为内部掉单 。

电商系统中的掉单问题

文章插图
防止内部掉单
服务端防止掉单
支付服务和订单服务之间防止掉单,关键在于要尽可能地保证支付服务通知订单服务支付结果成功,一般可以采用以下两种方式 。
在支付服务调用接口通知订单服务的时候,要进行失败重试,防止因网络抖动而导致的调用失败 。
同步不稳妥,那就再加上一个异步 。支付服务投递一个支付成功的消息,订单服务消费消息,这整个过程要尽可能保证可靠性(例如订单服务要在完成订单状态更新后,再确认完成消息消费) 。
客户端防止掉单
用户在支付完成后,跳转回电商系统,客户端会轮询一下订单的状态,通常是在两到三秒内,就能得到订单支付完成的结果,这个过程出现问题的概率相对较低 。
但是也不能排除,客户端在轮询了一段时间,还没能得到结果,那么只能结束轮询,给用户展示未支付 。
这种情况,通常问题也是出在服务端没有及时更新订单的状态,最主要的还是要处理服务端的掉单,保证服务端能及时同步支付订单的状态 。
但是一旦服务端的订单状态变更了,也要尽可能同步到客户端,不能让用户一直看到订单处于未支付 。
客户端判断用户未支付之后,通常会进行订单倒计时 。
通常是客户端组件倒计时,定期向服务端请求,检查倒计时时间 。这种情况下,客户端也可以检查支付状态 。
防止外部掉单
相较于内部掉单,外部掉单发生的概率大很多,毕竟和外部渠道的对接,不可控的因素更多 。
电商系统中的掉单问题

文章插图
要防止外部掉单,核心要以是四个字:“主动查询”,如果只是单纯地等待第三方的回调通知,风险还是比较大的,支付服务要主动向第三方查询支付状态,这样即使有什么异常,也能及时感知到 。
定时任务查询
支付服务,定时查询在一段时间内支付中的支付订单,向第三方渠道查询支付结果,查询到终态后,就去更新支付订单的状态,并通知订单服务 。