银联商务支付回调nginx返回499HTTP状态码浅析

2022-03-17 23:56 栏目:技术开发 查看(5131)

今天得到一个项目的反馈:你们新增加的支付方式支付正常,但原来支付的流程总是付了钱却没反应。这消息本身是很常见的支付回调异常。而这个项目比较特殊,原来开发并不是我们,很多比较流程都是原来就有的,支付流程的业务逻辑也是比较复杂的,因此在新增加的流程中支付也调用原来的就已经存在支付业务逻辑的(主要是不想动原来的核心流程,陈年老项目可不敢轻易动,哈哈);而且原来的支付流程一直都是通畅的,包括接入到原来支付模块的新增流程也是正常的,说明已经存在的支付业务逻辑是可用的。

其实支付回调异常是很常规的问题,一般来说是可以非常快速定位的,最典型的两个问题就是:1、支付商户号异常更新导致异常;2、支付回调业务代码执行错误或逻辑错误。

首先,笔者注意到的是数据库的支付订单id号是间断的,而id号本来是原来开发设置为自动自增的,理论上是连续的。说明在此过程中,有订单会被删除的过程。后面发现原来的支付业务逻辑确实会不停删除支付订单,基本逻辑就是二次发起支付会先删除原来已经存在但没支付完成的订单,然后生成新的支付订单。本质的目的就是为了刷新支付订单号(可能原来的开发者是为了避免支付订单超时等问题吧)。

但上述设计本身也是不够优雅的,比如删除、新增数据的开销比更新数据要大很多,同时不做任何判断就直接刷新订单号也不是优雅的做法。

结合此前支付流程都是没问题的,首先我们怀疑的是不是某个bug引起原来支付流程中删除订单+创建新订单的(也就是刷新订单号)问题,导致a订单在用户支付到银联商务这个支付平台发送回调这个时间差内,系统错误的删除了a订单,而创建了新的b订单,这样回调的信息是a订单,自然不能正常完成回调逻辑。

然而实际上通过程序debug模式的日志发现,压根就没有查看到支付回调相关的日志,而其它所有操作流程的日志都是准确无误的。

这个时候联想到银联商务平台后台操作体验与支付宝微信的差距很大,笔者甚至怀疑其银联商务这个支付平台起来,怀疑是不是平台的bug导致部分订单回调消息没有及时发送(差点就误会了,哈哈)。但细想起来,人家那么大的平台而且跟钱有关的东西不可能犯这么低级的错误。

所以再次查看了服务器nginx的日志,发现在nginx日志里面出现了支付回调的痕迹。而且发现返回的状态码是非常少见的499状态码。

1

大家一般常见的http状态码有2xx有200,3xx有301、302,4xx有401、404、403、405,5xx有500、502等等,但499状态码很少见。

大家都知道4xx状态码意味着客户端的错误,比如401意味着用户身份认证不通过,404意味着查找的资源不存在(非常常见的错误码),403禁止访问,405请求的方法被禁止。当然虽然说4xx状态码都说客户端的错误,但实际上还是服务端没有相关的资源或者客户端的请求不符合服务端的要求。

通过查询相关的资料得知:

499错误码是由于客户端发起请求后,一段时间内没有收到代理服务器的应答,导致连接失败。可能原因包括:1. 代理服务器认为客户端发起的请求过于危险,所以主动给断了; 2. 代理服务器实在么得办法连接到其他服务,导致超时。

1、排除是由于银联商务平台稳定性问题。

不更改支付流程的任何逻辑,只是把回调通知地址改成其它服务器的某个回调接口地址。结果发现在新的回调地址都能返回200正常的状态码。所以可用排除时银联商务平台发送的回调数据有啥问题的可能。

1

2、排除是由于回调信息被服务器拒绝。

因为之前是一直被回调信息请求到并完成整个业务流程的,而且这种正规的支付平台原来开发者也没必要做特别的限制。而且上面通知到其它接口也是正常的状态码,因此这个可能也可用排除。

3、排除是由于项目所在服务器配置的问题。

在当前服务器创建一个全新的空白项目,新项目就是提供一个回调接口,测试发现该新项目测试接口得到的结果是跟上面测试一样正常的,因此也可用排除。

4、排除是由于整个项目底层框架对回调信息的错误处理。

在当前项目,新建一个空白控制器,提供一个空白的访问接口。经过回调测试发现跟上面的结果还是一样,还是返回预期内的结果。

排除了这么多,说明问题的根源还是在于原来开发者开发的这个支付回调逻辑中除了问题,很可能就是因为某种故障造成的请求超时。结果笔者发现原来开发者在处理回调信息的时候,非常复杂,走了很多完全跟项目业务逻辑关系不大的流程,而且拐弯抹角(我甚至怀疑这些代码是不是东拼西凑来的)。结果通过不停断点测试,外加溯源n层方法调用,发现了这么一段。

1

通过这么一段的逻辑我们可用判断原开发者的逻辑:1、信息推送测试,但是在上线前竟然没撤掉,也没做任何处理;2、是不是信息非法提交的后门逻辑,毕竟这些信息都是姓名、身份证号码、身份证照片等敏感信息。

 最终的问题所在也是出在这个地方,由于这里请求的外部接口之前是正常访问的,而限制接口已经失效了,再加上没有做任何处理。而去刚好原来已经有的支付流程的传入参数在某些情况下刚好符合这段代码的执行条件,于是就执行了这些业务逻辑。之前外部接口是正常的自然回调也是正常的,现在外部接口失效了,于是回调请求就一直卡着不动,银联商户那边作为客户端也不会太傻,可能直接断开服务链接,于是就造成了499返回码。

看了这个案例你还敢随随便便使用某些来历不明的源代码么,即便你敢用,你还会觉得用这些不明来源的源代码会帮你省钱吗?即便有人愿意修改,这修改维护的代价可能比新开发还要大,因为接手的其它任何开发者可能排查各种坑所花的时间比自己新开发还要多。

与我们的项目经理联系
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流

转载请注明出处:银联商务支付回调nginx返回499HTTP状态码浅析 - 微构网络
分享: