文章目录
- 前言
- 背景
- 订单支付大致流程
- 订单支付流程中的注意细节
- 防止订单重复创建
- 为何会出现重复创建订单
- 处理措施
- 掉单导致的重复支付
- 为何会出现这种场景
- 处理措施
- 已支付流水退款
- 为何会出现这种场景
前言
最近感觉应该把自己在工作中遇到的一些比较有意思的核心流程进行总结以此来提高自己对项目的总结能力。由于能力有限希望本篇有问题的地方各位网友可以支出,感谢。
背景
这是个NFT的电商,该需求是要做一个抢购的功能,要求一个用户只能抢购一个NFT,NFT数量有限,并且编号唯一,卖出的编号不能重复,总数量不能多卖、编号不能多卖、每个用户账号不能多买。这里只先讲支付的流程,因为这部分涉及到的第三方交互较多,比较不好把控。
订单支付大致流程
订单支付流程中的注意细节
防止订单重复创建
为何会出现重复创建订单
因为客户端以及服务端没做幂等操作。
处理措施
需要客户端做防止表单重复提交以及服务端做订单不许重复创建的判断。
这里结合业务需求可以根据商品信息以及活动策略生成唯一订单号进行服务端的幂等保障。
掉单导致的重复支付
为何会出现这种场景
-
外部掉单:三方支付的支付状态没有同步或者没有及时同步到商城,这叫外部掉单。
-
内部掉单:支付服务的状态没有同步到订单,或者客户端没有及时获取到订单状态,这叫内部掉单。
处理措施
采用主动查询和被动等待结合的方式处理。
主动等待支付服务回调订单服务支付成功信息。但是由于可能出现网络问题导致迟迟无法接收到回调信息,所以最好加上主动查询的方式进行。但是不能马上就主动查询,这样太过于频繁容易导致第三方支付平台对我们的限流,我们一般设置在第三方服务正常回调时间之后还未接收到支付信息才进行回调。
我们这里采用延时任务来进行主动查询。因为此方案比起定时任务以及延时队列更加实时,对于数据库的查询频率更低。对于主动查询和被动接收在更新订单、支付流水状态时需要判断更新是否成功,成功代表该线程更新到数据,更新记录为0表示发生并发,没更新到需要再次查询订单、支付流水信息是否已被更新状态,更新了则返回更新成功信息,失败了做更新失败提示,同时这部分需要对失败场景进行归类,哪些需要告警,哪些不需要告警。
已支付流水退款
为何会出现这种场景
假如发起支付的时候,有流水正在支付中,如果第三方支付平台不支持取消支付,或者用户新的支付是通过不同的渠道,我们希望尽可能提高用户的支付成功率,怎么办呢?
我们可以在发起支付的时候,订单还在支付中的情况下,允许用户发起多笔支付,在支付回调的时候,检查用户是否已经有成功流水,对后来的流水进行退款处理。
当然,退款是个很危险的操作,毕竟钱退了,可就很难追回来,我们可以采用审核的方式来让运营人员审核退单。因为本身就没多少的订单量。