问题

2017年9月份,商城项目在运行过程中,购买某商品时如果在下单时没有完成付款,而是稍后再从“个人中心-我的订单”发起付款,则无法调起微信支付界面

思路

其他商品正常,说明导致问题的原因大概率是商品本身

只有从会员中心发起的付款存在此问题,说明大概率是会员中心的代码存在问题

需要先观察问题出现时“统一下单”是否能够成功,检查是否是参数问题导致订单无法在微信端创建

观察统一下单返回值

result_code=FAIL

err_code=OUT_TRADE_NO_USED

err_code_des=商户订单号重复

微信官方对于此问题的描述如下:

image.png

出现这个问题的时候建议核查订单号是否重复提交,但实际上在这个使用场景下,我们是“故意”重复提交订单号的。因为从会员中心发起支付的时候订单已经创建了,系统会再次请求微信统一下单接口,即便如此,我们也没有必要每一次请求支付都创建一个新的订单号。

那为什么返回了这个错误

我先给出结论再描述排错过程:

所谓的同一笔交易不能多次提交,实际上指的是在商品描述、标价金额不相同的情况下,用同一个订单号访问了统一下单接口。

image.png

这里的错误实际上是因为:从会员中心发起支付时“标价金额”与提交订单时的不相同。

PHP浮点型运算

以下是某位程序员写的微信支付代码:

$total_fee = (int)($order_total * 100);

微信要求金额的单位必须为分,而数据库中订单金额单位是元,所以使用订单金额*100是正确的做法。

订单支付金额的计算非常复杂,所以单位转化为分之后再转化为整型,可以保证微信支付参数不出错,也是正确的做法。

但这里面隐藏了一个问题,还记得我们问题发生的条件必须是“购买某商品时”吗?如果单独购买这个商品的话,订单的金额是19.9。我们可以尝试:

echo (int)(19.9 * 100);

// 结果为1989,而非1990

这就导致了订单创建时给微信的支付数据是1990,而再次支付时却是1980,所以接口返回了“订单号重复”的错误。

为什么会少了1分钱呢?PHP的官方文档中是这么说:

image.png

随后我又实验了很多数字,结果如下:

echo (int)(19.1 * 100);// 1910

echo (int)(19.2 * 100);// 1920

echo (int)(19.3 * 100);// 1930

echo (int)(19.4 * 100);// 1939 注意这里出现了问题

echo (int)(19.5 * 100);// 1950

echo (int)(19.6 * 100);// 1960

echo (int)(19.7 * 100);// 1970

echo (int)(19.8 * 100);// 1980

这个问题的产生,似乎存在规律,例如19.4、18.4和17.4转化后是错误的,而8.4转化后返回了正确的结果。

更有趣的是:

echo (int)((19.8+0.1) * 100);

// 1990 注意此时结果是正确的

var_dump(19.9 == (19.8 + 0.1));

// false

调试过程

实际上这种奇怪的问题排查起来没有什么捷径,无非就是打日志追踪变量,最多也就是细心点罢了。

最终使用了一个比较讨巧的方式解决了这个问题,将代码改为了:

$total_fee = (int)(($order_total + 0.00001) * 100);

至于更加严谨的浮点数计算方法,今后遇到的时候,再研究吧。

微信支付金额浮点分计算php,复盘微信支付金额不正确问题解决过程——PHP浮点型计算...相关推荐

  1. php微信支付金额隐藏,【php】复盘微信支付金额不正确问题—PHP浮点型计算

    首页 专栏 php 文章详情 1 复盘微信支付金额不正确问题-PHP浮点型计算 喝醉的清茶发布于 2020-11-12 一.背景 在做微信支付项目的时候,微信要求金额的单位必须为分,而数据库中订单金额 ...

  2. php计算用户实际付的金额,复盘微信支付金额不正确问题—PHP浮点型计算

    复盘微信支付金额不正确问题-PHP浮点型计算2020-11-15 11:58:29 一.背景 在做微信支付项目的时候,微信要求金额的单位必须为分,而数据库中订单金额单位是元,所以使用订单金额*100是 ...

  3. 超级简单thinkphp微信小程序服务商分账。以及小程序普通支付,微信特约商户

    产品介绍 服务商分账,主要用于服务商帮助特约商户完成订单收单成功后的资金分配. 使用场景举例 1.服务商抽成 在各个行业中,服务商为特约商户提供增值服务,服务商与特约商户协商,可以从特约商户的交易流水 ...

  4. 微信分账功能与微信支付企业付款相关内容详解(payjs版)

    PAYJS开通微信分账功能以来,有很多同学咨询相关情况.很多同学关心有没有什么办法,可以让自己的商户号快速开通企业付款功能.这里就介绍下微信分账的具体相关内容,可以完美解决问题. 一.什么是微信分账? ...

  5. 微信支付 postman_微信版花呗“分付”开通入口在哪?2020年微信分付开通最全攻略!...

    阅读本文前,请您先点击上面的蓝色字体,再点击"关注",这样您就可以继续免费收到文章了.每天都有分享,完全是免费订阅,请放心关注 免责声明图文来源于网络侵权请联系删除         ...

  6. 计算贷款的每月支付额。程序要求用户输入贷款的年利率、总金额 和年数,程序计算每月支付金额,并将结果显示输出。计算贷款的月支付额公式如下:(Java课本练习题 题目要求 )

    2.7 package booksTest;import java.util.Scanner;public class p34_2_7 {public static void main(String[ ...

  7. 利用Java计算计算贷款的月支付金额和总偿还金额

    计算贷款的月支付金额和总偿还金额 #公式:贷款总额x月利率/(1-1/(1+月利率)^年数x12) import java.util.Scanner;public class Meiyuezhifue ...

  8. 微信支付普通商户分账-添加分账接收方

    微信支付普通商户分账-添加分账接收方 写在前面: 微信官方文档 SIGN值校验检查地址 调试中可能遇到的问题 直接上代码 写在前面: 微信官方文档 https://pay.weixin.qq.com/ ...

  9. html如何自动打开手机微信支付,微信支付分正式上线!微信支付分开通教程

    原标题:微信支付分正式上线!微信支付分开通教程 [PConline资讯]腾讯最新功能悄悄上线,开通微信支付分! 相信很多朋友都不知道,微信支付分是怎么回事,更不知道如何去开通.微信支付分怎么开通?今天 ...

最新文章

  1. 【数学建模】MATLAB应用实战系列(九十二)-教你怎么挑对象,层次分析法应用案例(附MATLAB代码)
  2. 5、leetcode剑指offer53 二分查找之0~n-1缺失的数字**
  3. LL-verilog卡诺图sop和pos
  4. 前端学习(1115):call apply bind的区别
  5. php显示图片缩略图,使用ThinkPHP生成缩略图及显示的方法
  6. java 反射 动态_java实现反射,动态配置
  7. VMware知识库中文文章列表 (更新2013年6月)
  8. Android手机健康类APP市场分析
  9. 第十一章 缓存机制——《跟我学Shiro》[张开涛]
  10. office之转置EXCEL表格
  11. 基于EV/EBITDA的量化策略(基于python,附代码)
  12. 游戏启动流程的逆向分析与多开的实现
  13. ORA-01830: date format picture ends before converting entire input string
  14. 【历史上的今天】5 月 25 日:雅虎与 eBay 联盟;第一次国际万维网会议;Google 街景发布
  15. 对于解决新版unity5.x的license error 问题
  16. Sparrow操作系统的回顾与总结
  17. 【虚拟机/UBunTu】VMBox下UBunTu扩容磁盘
  18. c语言把字符变成asc11值,PLC字符与数据之间如何进行转换?
  19. 路由器R473g虚拟服务器设置,TL-R473G上网方式配置详解 路由器
  20. 因果推断, 因果效应概述

热门文章

  1. 订单失效怎么做的_数据库压力降低90%,携程机票订单缓存系统实践
  2. 【CAN】CANopen简介
  3. nohup、tmux使用;指定GPU运行python程序
  4. 【Scratch】青少年蓝桥杯_每日一题_12.09_地球绕太阳转,月球绕地球转
  5. RecyclerView刷新跳到顶部
  6. 小程序对七牛云文件上传删除批量删除生成token封装无需服务器一个小程序搞定
  7. 2021高考江门成绩查询,2021江门中考成绩查询时间及入口
  8. “饿了么”外卖系统开源了!
  9. element el-input 只能输入正整数完美解决不闪动
  10. 基于OpenCV(C++)的简单哈哈镜实现