最近搞了个公众号,因为是新手,微信支付那一块其中就遇到了很多的坑,为此商家由于个人失误就丢了差很少1000块。。下面总结一下遇到的坑php
图为微信支付的官方文档前端
图为实际文档的代码mysql
若是你用过微信支付的sdk,就会发现支付的设置是在jsapi.php这个文件下面,其中上面的那段代码是微信支付js api的调用,若是有支付行为就会调用function里面的函数,若是是返回的信息是"get_brand_wcpay_request:ok",就会执行if里面你的写的代码,按道理来讲if里面通常放置支付成功后的操做,可是这个是前端页面。。使用者能够去修改前端的页面,包括js。。这个是问题关键,我一开始觉得是微信网页,在电脑打不开,就比较安全了,就没深思那么多,没想到上线以后仍是有人能够修改前端页面,看来我仍是太年轻了,直接跳过判断。。执行下一步操做,为此商家损失了几百块。因为那时候微信支付那一块我不懂,是找别人作这一块,我作另外一块的,因此果断掉坑了,而那我的又不太负责任,听说那我的如今还去一个相似于慕课网的授课网站写微信支付的教程,我tm也是呵呵了,最后那我的想了一下给我建议,就是用微信的查询订单api功能去查询有没有该订单,若是没有该订单号,则证实他是跳过支付来执行下一段代码的。至于订单号,我是经过js的获取微秒级别的函数获取的时间戳做为商家的订单号的。ajax
我想了一下大概可能出现的状况,作了个微信支付判断,若是有不法分子留意,有如下几种状况:sql
1.没有该微信订单号存在(经过修改前端支付判断的代码跳过支付直接进行下一步)数据库
2.该订单号没有支付成功api
3.该微信订单号为空数组
4.传过来的订单号是已经使用过的(旧的订单号,这样就可能会形成支付成功一次,之后买一样商品不用钱了)安全
5.传过来的订单支付的金额和你的商品价格不对(若是有人有心,买了个便宜商品,再把前端js代码改了一下,不把时间戳的微信单号传过来,下次买个贵的商品再把该单号传过来,你也gg了)微信
下面是个人判断代码
// 订单号不空, if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != "") { $out_trade_no = $_REQUEST["out_trade_no"]; $input = new WxPayOrderQuery(); $input->SetOut_trade_no($out_trade_no); $message =WxPayApi::orderQuery($input); /** 这里是一个数组 */ // 存在该微信订单号 if(!empty($message)) { // 该订单号支付成功 if($message['trade_state'] =="SUCCESS") { /** 支付成功 */ // 判断价格是否和商品对应 $a = $nowPrice*100; if($message['total_fee']!=$a) {// } } // 订单号没有不成功支付 else { echo "订单不存在."; mysql_query($sql); exit(0); /** 错误码 0*/ } } // 该订单号不存在 else { exit(-1); } } // 没有存过来单号 else { echo "呵呵,玩你妹"; exit(0); } // 记录微信单号 $sql = "select tradeid from OddNumber where tradeid = {$out_trade_no};"; $res = mysql_query($sql); $arr = mysql_fetch_assoc($res); //不空证实订单存在,就是已经用过了 if(!empty($arr) ){ echo "订单存在"; exit(-1); } // 下面是支付成功后的代码
好了。。这就是微信支付的坑。。我感受还有更多的坑面对着我,昨晚又遇到一个坑。。微信支付文档原本写着$message['total_fee']是int,可是到了php又是string型,和数据库数据判断又出错了.
最后实验证实,仍是用回调处理支付成功操做比较好...根据前端ajax发送来后台去判断,总会出现漏单,并且你须要去写逻辑去处理..