技术支持:解决浮数点计算问题导致支付异步通知校验失败问题

2017-10-30 22:54 栏目:技术开发 查看(7247)

最近,收到一个已经在运行的第三方开发的项目,这个项目所在团队其他的项目经常让我们做一些技术支持服务,其实技术支持服务就是考虑综合性价比然后分包出去;可能是因为我们更加擅长,可能是因为我们的效率比较高。

这个需求,其实是个问题的大致情况就是,在一般情况下这个项目的支付及支付异步回调通知都是正常,但个别情况下是错误的,比如说32.30元。而这个问题在用户面前的表现就是:支付成功,但订单依然是未支付状态;翻译成技术术语就是,发起支付并支付成功,但回调处理出错了。

而且我们发现这个bug出现在的是在微信支付的子模块中,因为大家知道微信支付在进行发送请求和校验的时候都有一个100的的倍率问题,比如1元的金额,微信支付是100;而支付宝模块是不存在这个异常的。

这个问题在我本人在很久以前也遇到过,而且在不久前其他的同学也出现过这个错误,为此还发过一篇名为《开发童鞋偶遇php作为弱类型语言的坑》的文章,这篇文章描述的其实就是这个问题。

比如以上的问题,其实就是原开发者在写这个校验的时候把接收到支付平台通知的金额假设为$a(单位是分),而实际的金额为$b(单位是元)。比如上面的32.30元,那么$a应该是3230,而$b就是32.30。如果$b直接乘以100然后转为int。这里就会出问题了。

1214

看到上图的结果,很明显这样是不行的,因为转成int后结果成了3229,而不是3230,显然是不能够校验通过的,于是以下代码都不能够正常执行啦。

关于这个问题,是因为实际上对于机器来讲,32.30并不是我们意识中的32.30,实际上是一个非常接近的一个数,因此intval后就是3329了,这个可以搜索“php浮数点计算问题”来查阅更多相关文章。

最后针对这个问题,可以参考php的BC高精确度函数库。包含了相加、比较、相除、相减、求余、相乘、n次方,、配置默认小数点数目、求平方等;这些函数在涉及到电商及金融项目有关金钱的计算时比较有用。自 PHP 4.0.4,libbcmath 随同 PHP 一起发布。该扩展不需要任何外部的库。

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

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

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

转载请注明出处:技术支持:解决浮数点计算问题导致支付异步通知校验失败问题 - 微构网络
分享: