扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
最近接手了客户一个去年花了一年时间找省外某软件公司开发的一套智能硬件项目,客户反馈说支付的时候存在报错,而且强调以前是没有问题的。这种情况也是我们最不喜欢接手第三方开发后的项目升级维护的,因为这个项目在此时我们压根还没涉及修改原来系统的相关模块,也就不可能是我们的迭代工作造成系统的异常。
根据分析,这个错误信息是系统根据支付系统接口反馈的错误信息,这种错误如果支付配置信息没问题,往往就是发送的数据本身有问题。当笔者根据客户反馈的信息进行分析后发现,这个订单的金额是一个特别的数字1.1元(这个系统实际正式使用的时候金额都是正整数,不会是小数)。看到这个立马就想到是数字计算的问题了,结果查看原系统支付模块的源代码,发现还真是这样的。
两个环节导致该问题出现:
1、由于本系统使用的是银联在线支付通道(聚合银行卡、微信、支付宝等支付方式),但对于技术对接上的金额部分,跟微信一样采用的是以分为单位,比如1.1元,传给系统的数据应该是110的整数。而原来的开发人员直接把浮点型的金额数据乘以100(即金额*100)。
2、在系统向银联在线发送支付请求是,需要对内容数据转化成json字符串,在php中使用json_encode方法。
安装我们正常的数学逻辑,1.1元换算成分,就是乘以100就行了结果肯定等于110,也是我们想要的数据了。然而在php中,浮点运算是存在精度的问题的,甚至不同php版本运算得到的结果是不一样的。比如就以例子中1.1举例。在PHP7.4版本中得到的结果如下:
期望的结果应该是{“amount”:110},而实际得到的结果却是{“amount”:110.00000000000001}。而且不同的php软件版本和不同的数字得到的结果正确与否的结果也不同,比如同样的是php7.4版本下,1.20通过计算得到的结果跟预期一样是{“amount”:120}。
所以,这种异常的结果没有确定的规律可言,而且跟我们所需要的预期结果并不一致,于是在程序计算中必然会存在某些金额导致出错的情况。
如何解决?
解决的办法就是在进行数学运算的时候,我们可以利用一些高精度的计算函数来完成。比如我们之前就介绍过的BC高精度计算类(关于这个类的基本使用可以参考我们几年前分享的文章《利用PHP高精确度运算BC函数库解决小数计算异常问题》),当然除此之外还有更多的工具和方法。总而言之,我们遇到此类场景的时候切不可随意为之,否则会让自己或者你的协作者掉进大大的坑里。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流