这两天一直在捣鼓微信支付,跟大家分享一下我趟平的坑儿,方便大家,也便于以后的熟悉研究~

   结果微信支付H5页面文档就有两套,下载PHP(最新的v3)源代码测试官方代码也有错误(能对上算怪了),我性子比较急,官方文档写的又比较精炼,经常看漏字拉字就掉坑里了。在本篇文章中我写一写我不理解的地方在对接微信支付时我走的一些弯路。顺便也让大家少走些弯路。
两套文档
微信H5支付有两份文档,在微信公众平台有一份,在商户平台又有另外一份,而且内容还不一样。下面是新版的前端代码。(后端太多了,贴上前端把思路理顺就可以了)

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.      <meta charset="UTF-8">  
  5.      <title>微信支付页面</title>  
  6.      <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no">    
  7.      <script type="text/javascript" src="Public/js/jquery.min.js"></script>  
  8.      <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>  
  9.      <script type="text/javascript">  
  10.          $(function() {  
  11.  
  12.                  wx.config({  
  13.                      debug: true,
  14.                      appId: '<?php echo $signPackage["appId"];?>',
  15.                      timestamp: <?php echo $signPackage["timestamp"];?>,
  16.                      nonceStr: '<?php echo $signPackage["nonceStr"];?>',
  17.                      signature: '<?php echo $signPackage["signature"];?>', 
  18.                      jsApiList: [  
  19.                              "chooseWXPay"  //支付
  20.                          ] // 所有要调用的 API 都要加到这个列表中  
  21.                  }); 
  22.              $('#aaa').on('click', function() {  
  23.                  wx.ready(function() { // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。  
  24.                      wx.chooseWXPay({  
  25.                          appId: '<?php echo $da['appId']  ?>',  
  26.                          timestamp: '<?php echo $da['timeStamp']  ?>', // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符  
  27.                          nonceStr: '<?php echo $da['nonceStr']  ?>', // 支付签名随机串,不长于 32 位  
  28.                          package: '<?php echo $da['package']  ?>', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)  
  29.                          signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'  
  30.                          paySign: '<?php echo $da['paySign']  ?>', // 支付签名  
  31.                          success: function(res) {  
  32.                              // 支付成功后的回调函数  
  33.                              if (res.errMsg == "chooseWXPay:ok") {  
  34.                                  //支付成功  
  35.                                  alert('支付成功');  
  36.                              } else {  
  37.                                  alert(res.errMsg);  
  38.                              }  
  39.                          },  
  40.                          cancel: function(res) {  
  41.                              //支付取消  
  42.                              alert('支付取消');  
  43.                          }  
  44.                      });  
  45.                  });   
  46.              });    
  47.          });  
  48.      </script>  
  49. </head>  
  50.      <body>  
  51.          <a id="aaa" style="font-size: 20px;">贡献一下</a>  
  52.      </body>  
  53. </html>

这里的$da数组是在后台使用微信支付的DEMO里面提供的。两份支付文档的区别在于前端。就是拿到预支付标识prepay_id后选择哪套前端都能走得通。
何时商户订单号重复
看到官方文档有在调用统一下单接口时有一个错误是商户订单号重复。但是我拿着官方的php DEMO 点击支付(不支付)又返回,来回十几次也没见提示重复啊(订单号一直是同一个)?什么场景会重复官方文档也没有。我就在网上找答案并且来回试。终于知道了:简单来说,要想重复提交不出现错误,就商品描述、商品金额商户订单号这三个必须跟创建订单时候一样。也就是说调用统一订单API时,这三个参数提交的相同就不会提示重复。任何一个变了就会提示重复。关于签名签名这个地方也挺容易出错误。不管用微信jssdk支付还是微信DEMO那种方法,都是两次签名。签名方法一样:

1、将要POST到微信服务器的参数除sign外的参数赋值,放到一个数组array里面,按照字典顺序排序,其实在PHP中就是用ksort排序。

2、将数组转换成字符串string,格式为 k1=v1&k2=v2&...kN=vN

3、在此string后加上KEY值(在微信支付商户后台用户自己设定的)现在string = k1=v1&k2=v2&...kN=vN&key=KEY。

4、string = md5(string)

5、sign = strtoupper(string)
签名方式都是这样
签名还有一个坑就是看上面的代码25行。在js中时间戳这样写timestamp,后端(php端)中就要求timeStamp这样写。
对此我不想对腾讯说什么(#‵′)
其他还有一堆问题比如官方注释写错等我就不一一列举了,毕竟跟上面那些坑比比这都不是问题。

支付授权目录问题

最后还是有个问题是我想问问大家有没有碰到的,我是在是想不通啥子逻辑。我觉得是微信支付授权目录有问题。我的情况是这样的:
前一天下午我发起支付的页面是域名/abc/def/pay.php。测试目录我写的是域名/abc/
下午好用,晚上给老板测试支付就不好用了,提示的大体意思就是支付授权目录不对,我仔细一检查还真不对,应该是域名/abc/def/
但是把测试目录改正确后再把真正的支付授权目录改成注目礼后并且把微信号加入白名单还是不行。正当我纳闷中半小时后又支付可以了
第二天我再测试官方DEMO。竟然放在域名下任何一个文件夹都能正常支付。不管目录有没有授权。我从白名单把我删除在我的测试目录下的支付中也是成功的。直到我取消关注公众号再关注这时提示不在白名单。
其实上面可以汇成一个句话的问题:为什么支付授权目录一会管用一会不管用呢?期待大大们的回复,关注“泰斗社区”了解更多