背景
一大早运营报来了一个问题:
问题描述:有一个订单客户支付成功了,订单状态却显示过期。
预期:客户应该支付不了失效的订单。
问题猜想:1 是处理回调通知时,程序处理错误导致修改订单状态不成功。
2 用户停留在支付宝的支付时间过长,导致过了订单失效期后,进行了支付。
作为程序开发者,其他的问题都是小问题,但是遇到支付问题就是大问题,大家都懂得,于是开始紧急排查。
问题排查
查看错误日志,果然找到了该订单已过期的信息,说明问题应该是问题2。
找到订单相应的支付回调通知参数,果然找到第三方支付的成功通知。
解决方案1
- 下单时给第三方支付系统,设置订单过期时间。
- 订单过期通知第三方系统订单已经过期。
预支付时设置过期时间
微信支付订单过期参数: time_expire
支付宝支付订单过期参数:time_expire
温馨提示:在排查时,看到同事写的支付代码里传了time_express , 这个不代表我们的订单过期时间,代表的是用户正确输入密码支付宝受理这笔订单业务开始计时时间,千万不要混淆了。
聪明的细致的你肯定想到了,还需要做一步服务器时间和第三方支付系统的服务器时间校验,不然可能出现不准的情况。
校验服务器时间和标准时间
# 比较当前服务器时间和目标主机时间是否相差比较比较远
clockdiff NTP.aliyun.com
需要关注delta,就是NTP服务时间和本地时间的差值。
如果相差较大可以同步服务器时间,这种方式是最简单的:
ntpdate ntp.aliyun.com
实际操作大家可以用一个定时任务,每天去同步一次。
解决方案2
如果你的服务器比较多,并且同步时间会存在风险,或者你没有操作正式服务器的权限,那么可以在自己处理失效订单时,主动通知给第三方系统你的订单已经失效。
微信调用 closeorder 方法
对于支付宝的创建订单,是在用户输入了密码后才会创建订单,在预支付时,我们系统虽然创建了订单,但是用户没有输入密码,支付宝那边是没有订单的,所以这种方案是不适用的。
比较2种方案的优劣
1 第一种方案的优点是,代码量少,只需要多添加一个参数即可。缺点是可能存在时间不准。
2 第二种方案优点,可以保证订单失效时的决定时间。缺点代码量稍微大些。
感悟
通过这个问题,我们可以看到,很多问题都有多种解决方案,当身处不同位置时,解决方案不同,需要我们自己权衡方案的利弊找出最优方案。如果大家有更好的解决方案,欢迎大家留言与评论。
演示视频