订单支付相关问题总结

订单支付相关问题总结最近公司商城系统要重做,我接手了支付相关的需求,发现里面弯弯绕绕的地方还是有不少的,所以把碰到的问题记录一下。支付问题在第一次对接微信支付时,生成预支付单的接口会让使用微信商家平台的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)


相关推荐

  • 重构什么意思_直接重购

    重构什么意思_直接重购Percona PT-kill重构版(PHP)

  • 具体说明 Flume介绍、安装和配置

    具体说明 Flume介绍、安装和配置

  • J2ME开发环境配置(MyEclipse插件+WTK+jdk)

    J2ME开发环境配置(MyEclipse插件+WTK+jdk)MyeclipseJ2ME开发之环境配置的前言随着移动设备的普及和应用,在小型存储设备方面的研发进入了一个全新的时期,比如数字电视,PDA,移动存储通信设备等。而各方面的技术也进入了一个飞速发展的时期。尤其是近几年J2ME技术的发展。  而开发MIDlet应用程序有很多种开发工具可以选择,这些开发工具盒开发环境主要分为三大类:第一种是Sun公司的J2ME通用开发工具,例如J2ME无线开发工具包

  • css怎么改鼠标样式,如何利用CSS改变鼠标的样式

    css怎么改鼠标样式,如何利用CSS改变鼠标的样式各种各样的鼠标样式,对于经常使用电脑的人而言一定不会生疏。当鼠标移动到不同的地方时,当鼠标执行不同的功能时,鼠标的外形都会发生变化。但在网页上,貌似只有当鼠标在超级链接上时才出现一个手形,在其它地方似乎没有什么变化,同布满动感的网页显得不怎么和谐。实际上,用css可以方便地定义许多种鼠标外形。下面小编就为大家介绍一下怎样利用CSS改变鼠标的样式。用CSS改变鼠标的样式,我们使用cursor属性,现…

  • 钟表代码分享

    今天分享一个时钟的源码,效果如图所示:最后附上源码<!DOCTYPEhtml><html><head><metahttp-equiv=”Content-Type”content=”text/html;charset=UTF-8″><title>时钟</title><styletype=”text/c…

  • pipeline语法_plain词根

    pipeline语法_plain词根Pipeline语法2021-08-0317:10更新本节基于“入门指南”中介绍的信息,并应作为参考。有关如何在实际示例中使用Pipeline语法的更多信息,请参阅本章的Jenkinsfile部分。从Pipeline插件2.5版开始,Pipeline支持两种离散语法,详细说明如下。对于每个的利弊,请参阅语法比较(下文中)。如“入门指南”所述,Pipeline最基本的部分是“步骤”。基本上,步骤告诉Jenkins要做什么,并且作为Declarative和Scripted…

发表回复

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

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