收藏
回答

关于开发微信支付下单接口的几点关于严谨性方面的疑问?

我终于开始鼓起勇气写支付下单接口,一直不敢触碰,因为这个接口算的上是整个系统里面,最复杂最需要严谨的那个,毕竟和金钱相关,没有足够的知识准备,没有能力去写,写出来也是经不起高并发、异常的考验的,可能平时状态下没什么问题罢了,我是对自己这样要求的。

所以我不断的去找资源学习,发现每个老师都有自己的处理方案,其实我一直想寻求一套统一的公式。废话不多说,进入正文。

Native支付举例:比如下单接口第一步校验幂等性,防止重复下单(这一步可以用lua脚本或者其他token机制,我只知道lua脚本搭配redis),第二步校验通过,创建订单数据(根据前端传过来的商品id去数据库查询对应的金额、商品描述、利用雪花算法生成订单号、订单状态设置为‘待支付’、设置回调通知地址等等),第三步请求官方下单接口,如果请求成功则返回二维码,至此下单这一步完成。接下来是notify_url回调的处理,这一步给的感觉就是很严谨,比下单还严谨,我说一下。首先获取返回的响应体,解析,验签,校验金额。验签失败则抛出异常,否则继续,接下来响应码不是Success则抛出异常,否则继续。好,都无误,先加锁,然后查询订单状态是否被处理,没有改为‘已支付’则修改订单状态(先查一下,再做处理其实是考虑到了微信可能会发多次通知),然后响应给微信SUCCESS字符串或者XML。

至此!一套支付完成。

接下来,我提几点疑问,其实上面所说的,也只不过是我照着老师的代码翻译的意思罢了。

  1. 幂等性,为什么要幂等性,为什么防止重复请求支付接口,难道说我手速极快,一下子点支付按钮点了两次或者更多?难道说我手机卡顿,我还是点按钮点了好几次?当我点击第一次的时候,前端ui已经将按钮置为disable或者弹出提示性的遮罩mask,我又怎么能点击多次呢?难道说防止有人不走页面,走postman,不过那样,也是有先后的呀?
  2. 雪花算法,为什么不用uuid,难道是怕高并发的时候,即使uuid也会重复,我和你同时下单,uuid重复了,你和我之间,只有一人会下单成功?
  3. 校验金额,为什么要校验金额,已经验过签了还怕有人心怀不轨篡改响应,形成‘假通知’,签名你都不信了?
  4. 加锁以及校验订单状态保证幂等性,微信说回调需要加锁,避免函数重入,函数就是方法吧,应该就是notify_url地址对应的那个方法被调用多次吧,为什么会出现此场景?这是一个问题,其次如果函数重入,如果我后续只是修改订单状态从‘未支付’到‘已支付’,那即使重入几次也没关系吧,你永远都是更新为‘已支付’,多几次数据库的操作,结果也还是一样。但是如果我后续还需要加订单日志到数据库,那是不是就需要考虑函数重入,避免写多条日志?其实我一直想不通为什么会多次调用,官方文档说

这又不是并发级别的,第一次15s,第二次15s...真的搞不懂,难道还有其他情况会重复通知,而且还是并发级别的?

5.先本地生成订单、调用下单接口还是先调用下单接口,再生成本地订单,听有些博客说,如果是后者,那么如果数据库写入慢一点的话,但是notify已经回来了,然后查看订单是否支付的时候,会查询不到,你可以想象一下这个过程,是否存在这种可能?

好了,差不多就这么多了,对了还有个JsApi的支付,听说即使下单之后回调的结果是‘requestPayment:ok’也可能会失败,严谨的是再查单一次,是吗?

提了很多问题, 这些问题都是日思夜想的问题,无奈身边没有大神,希望有懂的兄弟可以回答一下,感激不尽,谢谢!


回答关注问题邀请回答
收藏

2 个回答

  • Memory
    Memory
    2022-12-13

    补充一条:关于get_brand_wcpay_request:ok 不可靠的说明,这里不是指你获取到返回ok实际支付失败的情况,而是支付成功,无回调或者返回了“cancel”,所以不建议依赖这个处理,可以优先异步支付结果通知,收不到通知在进行主动查单

    2022-12-13
    有用 3
    回复 6
    • 那一年,我在搬砖
      那一年,我在搬砖
      发表于移动端
      2022-12-13
      我大概理解了,我说下我的理解。jsapi支付其实有两个接收结果的方式,一个是前端的success回调,你说不可靠的这个。还有一个是下单时传过去的notify_url,建议用这个。然后防止notify_url也失败,再加一道保障,主动查询订单。那我什么时候查?
      2022-12-13
      回复
    • 那一年,我在搬砖
      那一年,我在搬砖
      发表于移动端
      2022-12-13
      我怎么确定,就是微信支付服务器没给我回调呢,导致我这笔订单实际支付成功,但回调没触发、支付状态没改成呢。当回调接口一直不触发时,我完全可以认为这个用户一直没支付或者打算放弃这个订单,让它超时自动关单,我不会去想着是不是微信没给我回调。
      2022-12-13
      回复
    • Memory
      Memory
      2022-12-13回复那一年,我在搬砖
      根据你自己业务需求,我之前设计的是3秒
      2022-12-13
      回复
    • Memory
      Memory
      2022-12-13回复那一年,我在搬砖
      2022-12-13
      回复
    • Memory
      Memory
      2022-12-13回复那一年,我在搬砖
      你这逻辑就是有问题的,你是需要去确定用户的支付状态,假设你服务崩了收不到回调,你就把这些客户当未支付关单处理?客诉会教你做人的
      2022-12-13
      回复
    查看更多(1)
  • 北望沣渭
    北望沣渭
    2022-12-13

    HTTP是无状态协议,幂等说法就是指明了一种解决方案,X情况下,操作0次和操作N次,结果一致;

    至于雪花算法,那是为了性能考虑,字符串排序和数字排序,在大数据量情况下是不一样的,数字排序效能高于字符串,雪花算法就是为解决这个问题的;

    校验金额 是指,当一笔订单含优惠时,用户实付和商户实收不一致,所以需要自行计算比对一下;

    加锁以及校验订单状态保证幂等性 也是基于HTTP无状态协议所赐...

    2022-12-13
    有用 2
    回复
登录 后发表内容