订单支付相关问题总结

订单支付相关问题总结最近公司商城系统要重做,我接手了支付相关的需求,发现里面弯弯绕绕的地方还是有不少的,所以把碰到的问题记录一下。支付问题在第一次对接微信支付时,生成预支付单的接口会让使用微信商家平台的API密钥进行加签,但是就算你使用的API密钥确定没有问题,也可能会返回验签失败,一点办法也没有。解决方法:使用UUID重新生成了32位纯小写的密钥(我怀疑就是密钥格式问题引起的,从来没有见过密钥让用户手…

大家好,又见面了,我是你们的朋友全栈君。

最近公司商城系统要重做,我接手了支付相关的需求,发现里面弯弯绕绕的地方还是有不少的,所以把碰到的问题记录一下。

支付问题

  1. 在第一次对接微信支付时,生成预支付单的接口会让使用微信商家平台的API密钥进行加签,但是就算你使用的API密钥确定没有问题,也可能会返回验签失败,一点办法也没有。 解决方法:使用UUID重新生成了32位纯小写的密钥(我怀疑就是密钥格式问题引起的,从来没有见过密钥让用户手填的),然后等待15分钟新的API密钥生效,重新调用接口即可。
  2. 支付宝统一下单接口中可以设置超时时间timeout_express,这个字段的含义是以用户点击了 “支付宝支付” 这一刻算起的TTL,有可能与业务上要求的订单超时时间并不一致。 解决方法:使用time_expire字段,该字段含义为在time_expire后的支付都为超时支付。

订单金额问题(划重点)

这个可以说是一个我碰到过的严重线上问题了,之前我一直认为,创建订单的所有参数都要经过加签,所以参数都是不可修改的。
万万没有想到,对于订单的支付金额,支付宝那里居然没有进行加签验证,这样会导致一个什么样的问题呢?
如果你的App被人恶意攻破了,拿到从服务端返回的用于唤起支付的链接后,客户端或者H5就可以去修改链接中的订单金额参数,比方说,我服务端生成的订单金额为100元,客户端就能改成0.1元。。
由于支付宝没有对订单金额进行校验,就会导致用户能唤起支付,能支付成功,能触发服务端的回调,然后你人就离职了 #_#

所以服务端在创建订单的时候,一定要在订单表记录一下用户需要支付的金额,并在回调的时候进行金额校验(对比支付宝返回的实际支付金额和预存的需要支付金额)

支付回调问题

支付回调的问题是最严重的,以支付宝举例(不管是微信还是支付宝,支付完成都有回调通知的)。支付宝的统一下单接口中可以传两个参数,return_url(页面跳转地址)和notify_url(结果通知地址)。
一般做法是在notify_url对应的接口中根据支付接口触发订单的后续逻辑的(更改订单状态什么的),因为这样做会比较安全,可以对参数设置加密返回或者对返回结果验签。这样做就会碰到以下几个问题。

  1. 因为notify_url是异步通知的,所以就会必然存在一个问题,用户收到了支付宝同步返回的支付结果,提示支付成功了,但是这时候,服务端还没有收到异步回调,相应的订单状态还没有进行修改,用户查看订单时显示的可能还是未支付状态。
  2. 可能因为网络问题、域名问题、或者支付宝本身问题(是系统就会出问题的= =),导致服务端根本就没有接收到回调,订单状态一直无法修改,直到超时取消。
  3. 支付宝发送异步通知时,如果服务端没有返回success,则支付宝有自身的重试机制,会进行重推,导致订单后续逻辑会重复执行。

针对问题三,这个是无法避免的,所以在异步通知的接口中订单处理逻辑一定要做幂等。
针对问题二,起定时任务,对待支付订单主动查询支付状态进行补偿。
针对问题一,成本最低的做法,可以让用户在收到支付成功时在页面上强制多停留几秒钟(测试的时候,用户收到支付成功和服务端收到回调的时间差也就一两秒钟以内,有时候收到回调可能还会更快。。),但是该种做法只能解决90%的场景,毕竟是网络环境,也可能几分钟才回调过来,或者网络直接崩了。

完美的办法(开发成本也是最高的),在用户收到支付成功后,由客户端调用接口执行订单后续逻辑的触发(加密啊、加签啊什么的都要做,为了安全),并且服务端收到调用后,也要主动去支付宝查询该笔订单的支付结果,进行再次确认。并且,为了防止因服务器处理异常产生的订单没有支付成功的现象,同时启动定时任务,定时轮询待支付的订单,查看支付到底有没有成功,进行补偿(会发生与客户端回调并发处理的问题,所以要加锁控制)。虽然这样基本上能够杜绝99%的问题发生了,但是性能上一定会有损耗,编码的难度也上升了。

所以,为了权衡,使用异步回调 + 定时任务的方式下,发生问题的概率就已经比较小了(会牺牲一下用户体验,就是用户支付成功了,可能要过个十分钟,订单状态才会变为已支付)。
毕竟系统越简单,bug才会越少。

SDK相关

支付宝的java sdk支持的很好,微信就一言难尽了(不过我在2021年又看到微信也提供了官方支付SDK https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1)
微信SDK也可以用一个开源的SDK接入,地址如下 https://github.com/Wechat-Group/WxJava,功能维护的很全,我之前一直在使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134946.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java项目中的classpath到底指向的哪里[通俗易懂]

    今天在项目里看到好多地方都用到了类路径,并且自己对路径还不是很清楚,所以就在网上百度了一下!上面图片的意思简单来说,就是classpath只能表示lib目录和WEB-inf/classes路径下的文件,calsspath不能表示的src路径下面的文件,但是从项目结构来看,配置文件一般是不放在放在WEB-INF下面啊,并且也没有看到classes路径,lib目录不是放依赖ja…

  • Linux常用命令(面试题)

    Linux常用命令(面试题)Linux常用命令因为热爱,所以拼搏。–RuiDer常用指令ls  显示文件或目录-l列出文件详细信息l(list)-a列出当前目录下所有文件及目录,包括隐藏的a(all)mkdir创建目录-p创建目录,若…

  • js匿名函数和命名函数_jsp调用java方法

    js匿名函数和命名函数_jsp调用java方法由衷的感叹,js真是烦。学到现在,渐渐理解了什么是:语言都是通用的,没有好不好,只有擅长不擅长。继承,多态,甚至指针,c能实现,c++,java有,javascript(和java是雷锋和雷峰塔的区别,名字上不知道坑了多少人)也能变通实现。温故知新,今天又回味了一遍,匿名函数作为函数参数。代码很短,五脏俱全。functiontest(a,b){a+=1;b(a);}test(3,func…

  • 如何彻底删除kvm虚拟机_虚拟机命令怎么删除

    如何彻底删除kvm虚拟机_虚拟机命令怎么删除(转)virsh命令速查表VirshVirshconnectVirshdisplaynodeinformation:VirshlistalldomainsListonlyactivedomainsVirshstartvmVirshautostartvmVirshautostartdisableVirshstopvm,virshshutd…

  • 复制文件到一个文件夹并进行排序copy_imgs_to_dir

    复制文件到一个文件夹并进行排序copy_imgs_to_dir

  • DatagramSocket编程

    DatagramSocket编程importjava.awt.BorderLayout;importjava.awt.Container;importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.io.IOException;importjava.ne

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号