电商项目之同一笔单多次收款成功

1 问题背景

有个收单系统(简称S系统),作用是收单,相当于支付渠道,能够作为第三方服务对接其他支付平台。电商系统(简称A系统)与S系统是隔离的。A系统发起支付请求给S系统,S系统包装一下(AB站逻辑)再发起支付请求给Stripe。Stripe系统处理完逻辑后会跳回到发起支付时传过去的returnUrlreturnUrl到达的前端页面会通过js代码发起请求(假设请求路径是/pull/pay/result)给S系统,S系统会拉取支付结果。如下图所示:

电商项目之同一笔单多次收款成功_第1张图片

问题出现在步骤4,导致A系统的订单状态无法及时翻转。买家看见未支付成功,就第二次发起支付,导致Stripe后台出现了同一笔单多次收款成功。

这个问题,在买家角度去看,核心是支付结果没有及时翻转。在卖家角度去看,买家后续会发起拒付,导致卖家的收款账号被封的可能性提高。

2 前言

本篇为笔者遇到的真实案例

3 S系统的设计初衷

S系统设计的初衷是为了保护商家的收款账号不被封(业务是做不发货业务),因此S系统暂时没有做webhook订阅(如果要做,要做好ab逻辑),导致无法及时从Stripe拿到订单的支付结果,只能依靠自己主动查询。因此在订单状态翻转这块无法100%保证时效性。

由于业务类型不同,S系统在设计之初就做了重点倾斜。针对不发货业务,核心是保护收款账号,收到款就行。针对仿品、普货这些业务,核心是订单状态的翻转,因为卖家要发货。

S系统无法同时兼顾两类不同的业务,必须要有所倾斜。

4 思考产生问题的原因

分别从业务角度、技术角度去分析产生问题的原因(产生bug的场景),并思考对应的解决方案

业务上:

  1. 客户做什么业务?仿品、普货属于都要发货的类型;不发货业务是属于不发货的类型。如果是不发货类型,由于要保护收款账号从而没有接入webhook及时反转订单状态,因此在时效上无法100%保证翻转订单状态。因此,如果是做仿品、普货的业务,无法保证及时翻转订单状态。如实告知客户系统设计如此,建议客户采用另外的收款渠道,而不是采用S系统

  2. 客户投放什么国家?因为问题的核心是没有调用到S系统的接口,是否存在网络问题,导致调不通?需要询问客户投放什么国家,因为S系统没有做全球加速,可能会存在某些国家访问S系统失败。

技术上:

  1. webhook是否有发送成功?可以做个重试机制发送webhook,但必须限制最大发送次数。

  2. 主动拉取支付结果的延迟消息是否生效?根据排查结果,买家发起第一次支付会投递1个延迟时间为10min的消息给MQ,而买家在4min后又发起支付并且支付成功了。而等到MQ开始消费时,买家已经支付完并成功了。因此,我们可以降低延迟时间,比如1min,并且在消费时如果还是拉取到未支付成功,可以再投递一个延迟时间为3min、5min的MQ(查询频率递减)

5 解决方案

  1. 如实跟客户阐述S系统的设计初衷,并将风险告知。(如订单状态无法及时翻转)
  2. 如果是由于网络问题导致流程图中的步骤4 调用/pull/pay/result/报错,需要询问客户投放的国家,看看该国家是否与S系统之间存在网络问题,根据情况 让运维加入全球加速,但是经济成本会增加。
  3. 针对异步延迟拉取支付结果,可以提高拉取频率,或降低延迟时间
  4. 做一个定时调度,将当天内待支付的订单,每隔1min都拉取支付结果
  5. 实现同一笔订单不能支付多次,这样就杜绝Stripe后台出现同一笔单多次收款成功
  6. 针对流程图中的步骤4 调用/pull/pay/result/,前端页面引入监控机制(监控前端页面在调接口的时候是否报错了),但是项目经济成本会提升。同时调用改接口可以加入重试机制。

5 总结

发生生产级别的问题,先不要慌,要从业务角度、技术角度思考什么场景会导致该问题发生?有解决方法吗?运用任何数据去分析排查并结合现有情况给出解决方案。处理问题的方法论见电商项目之处理生产级别问题的方法论。

你可能感兴趣的:(解决方案,电商项目)