收藏
回答

问一个微信支付下单前,限制重复支付的业务流程问

调用微信支付下单接口,是可以同时多个进行的。问业务系统设计问题。请从后端的角度理解。

注:文中的支付订单是支付纬度,不是商城纬度的那个订单。

现在用户想结算购物车的A+B+C物品,生成一条微信支付订单,当弹出“确认支付”框的时候,用点关闭窗口(或者杀微信进程),这个微信支付订单会关闭并回调支付失败吗?

如果不会,那就会产生一情况,用户现在再次发起结算,但单独结算A物品,就会又生成一条微信支付订单了。因为微信支付关单接口要下单5分钟后才能关,所以第一笔微信支付订单是没关的(https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_3)。

你们是怎么防止A物品重复支付的?

第一种方案:结算ABC三个物品时的微信支付订单,要锁定三个物品的状态为处理中,让第二次单独结算A物品时不能发起支付,但是这样要用户等5分钟,用户体验就不是很好。

第二种方案:结算ABC三个物品时,生成了微信支付订单,用户看到小程序弹出“确认支付”那个按钮的框,但是关闭这个框,去结算A物品,生成一条新微信支付订单(因为金额不一样了)。那这样系统是没有限制A是否重复购买的。用户如果得到h5页面,看f12,其实可以同时调用jsapi根据prepare_id唤出“确认支付”那个窗口,然后都去支付。最后就要退款处理重复部分。

其实看麦当劳点餐,买ABC唤起“确认支付”弹窗后,点关闭窗口(或者杀微信进程),可以去买A,他们就不怕遇到作的用户,触发两个微信订单然后都支付吗?因为两个发起两次微信统一下单是可以先后执行,所以分布式锁拦不住的。

图:

确认支付弹框



待支付状态

最后一次编辑于  2020-11-28
回答关注问题邀请回答
收藏

3 个回答

  • 常楠。
    常楠。
    2020-11-28

    我理解一下,第一次下单的时候ABC都已经减库存并生成订单,没有支付而已 。第二次对A下单,在生成订单前要去判断库存是否够,不够无法下单,够的话直接购买,不冲突 。

    至于你说的第一次里面已经有商品A了,所以第二次不允许购买A,这是业务需求的,而不是程序能不能和该不该的问题 。

    比如说我去超市,第一次买了1瓶农夫和1瓶怡宝,觉得农夫有点甜,所以想再买1瓶,这个时候超市说对不起你已经买过1瓶农夫了,不允许再次购买 。 你咋想 ? 农夫超级稀有1人限购1瓶 ? 搞促销只能参加1次?

    这些都是规则(你公司的业务要求)。跟微信支付毛线关系都没有。

    2020-11-28
    有用
    回复 2
    • 俊
      2020-11-28
      你说的下单,是指商城纬度的下单,我说的下单文中说的是微信支付统一下单接口(支付的下单)。意思是防止那一瓶农夫在柜台支付两次。所以是允许别人买多一瓶农夫,但是要不允许别人同一瓶农夫买两次。
      2020-11-28
      回复
    • 俊
      2020-11-28回复
      所以有个环节,我拿农夫A1和怡宝B去结账那一刻时,想想怡宝放一边想只结账农夫A1。就是去支付的时候防止两笔支付订单重复(不是买多一瓶新的农夫A2)
      2020-11-28
      回复
  • 俊
    2020-11-28

    我找到方案了。

    瑞幸小程序是ABC三个货物提交订单,扣库存后,3个物品都进入待支付状态,就会调微信支付统一下单接口,生成好流水。A物品不会允许再次单独调用微信支付统一下单接口。

    但是麦当劳点餐,因为没有购物车到商城订单环节,只有微信支付统一下单接口的环节,所以与瑞幸小程序不同。

    淘宝做法是,ABC三个物品(三个在不同的店铺中)提交订单,进入待支付状态时,为每个店铺都生成不同的支付流水。支付时是可以三个流水一起进入支付把三个流水的加起来总金额一起去银行扣钱。

    2020-11-28
    有用
    回复 3
  • 老张
    老张
    2020-11-28

    和支付毫无关系。支付只是和付费费用有关,和商品其他属性无关。

    商品库存或者锁表啥的,这些都是你自己业务逻辑的事。

    建议把支付环节看作是一个黑箱开关而已,只有两个状态:成功和失败,

    let status = pay(...)

    if(status){。。。}else{。。。}

    把上面的代码替换你流程中的支付环节,如果能够走通,才说明你的业务流程是正确的。

    然后再去理顺你的流程吧。

    2020-11-28
    有用
    回复 4
    • 俊
      2020-11-28
      是和支付、商品无关。问的不是这方面的问题。描述中已经把支付环节作为黑箱了。主要是如何防止购买的相同的物品重复下“微信支付的订单而已”
      2020-11-28
      回复
    • 俊
      2020-11-28
      用这个前端代码代替没有作用,
      let status = pay(...)
      if(status){。。。}else{。。。}
      因为可以开两个h5页面分别触发结算,我描述的是两个订单,有重复的物品,同时结算的问题。可能问题比较长,没理解。
      2020-11-28
      回复
    • 老张
      老张
      2020-11-28回复
      最后不还是归结为:库存为n的时候,n+x个用户同时下单的问题呗。不管啥重复物品,啥结算,无非是你哪个环节去库存-1;这不是数据库锁表,冲突的简单问题了吗?
      2020-11-28
      回复
    • 俊
      2020-11-28回复老张
      不是扣库存环节了。已经过了扣库存的环节了,如淘宝提交订单,就会库存扣好1个。
      是扣完库存后,待支付的状态下,提交微信支付统一下单接口把ABC3个物品100块都去支付,当看到“确认支付”弹框后,然后又发起把A物品10块提交微信支付统一下单接口支付(不是与前一次同一瞬间发起)。
      这时就有两个“微信支付统一订单”out_trade_order里都包含A物品了。你是否会不允许第二次单独支付A走“微信统一支付订单”?
      2020-11-28
      回复
登录 后发表内容
问题标签