jsapi 调起微信支付的的踩坑

问题:

公众微信号调起微信支付的时候,有的时候调起支付成功,有的时候调起支付失败。利用抓包工具抓取数据显示授权和调用后台的微信预支付订单接口都成功并且都返回正确的数据。但是调起支付的时候传入的data老是弹出{‘isTrusted:false’},正常的data应该是调用生成预支付订单的返回数据,即后台给返回的调起微信支付所需要的数据参数。我的代码:

<script src="./js/jquery.js"></script>
<script src="http://res2.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script src="./js/commom.js"></script>
<script>
var code = GET('code');
var data = JSON.parse(window.localStorage.getItem('data'));

weixinPayFor(data);

//微信生成预支付订单(微信端)
function weixinPayFor(data){
var required_parameter = {
totalprice:data.totalprice,
orderNo:data.orderNo,
code:code,
url:'http://stg.keyidabj.com/mp/wx/cameraVipApp/payment.html',
};
postNet({
param: required_parameter,
action: "/getWeixinPayForPatriarch",
successFull: function successFull(data) {
// console.log(data);
var result = data.result;
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady',onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady',onBridgeReady);
}
}else{
onBridgeReady(result);
}
},
failFull: function failFull(data){
$('.loading').hide();
$('.result-container').show();
$('.result-main i').hide();
$('.result-text').addClass('fail-text');
toastText(data.info);
let time = 5;
setInterval(function () {
time--;
if(time>0){
$('.result-text').text(time+'s后页面关闭');
}else {
window.history.go(-1);
}
},1000)
}
});
}

function onBridgeReady(data){
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId":data.appid, //公众号名称,由商户传入
"timeStamp":data.timestamp, //时间戳,自1970年以来的秒数
"nonceStr":data.nonce_str, //随机串
"package":data.packageStr,
"signType":data.signType, //微信签名方式:
"paySign":data.paySign //微信签名
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok"){
$('.loading').hide();
$('.result-container').show();
$('.result-main i').addClass('success');
$('.result-text').text('支付成功');
$('.result-text').addClass('success-text');

}else if(res.err_msg == "get_brand_wcpay_request:cancel"){
// toastText('支付取消啦');
// errorAlert('您已取消支付');
$('.loading').hide();
$('.result-container').show();
$('.result-main i').addClass('fail');
$('.result-text').text('支付取消');
$('.result-text').addClass('fail-text');
}else if(res.err_msg == "get_brand_wcpay_request:fail"){
$('.loading').hide();
$('.result-container').show();
$('.result-main i').addClass('fail');
$('.result-text').text('支付失败');
$('.result-text').addClass('fail-text');
}
});
}

function backIndex(){
window.location.href='./index.html';
}
</script>

原因:
调起微信支付的时候,页面会加载微信的js,会在所有的script标签后面添加一行script用来加载微信的js,而我自己写的js代码没有在所有的js文件加载完成之后调用。即没有用$(function(){ }); 代码包裹起来我的逻辑。会导致加载此页面的时候从上往下执行。
而调用微信预支付订单的接口是异步请求。如果异步请求返回的数据慢于微信js加载。则正常走调起微信支付。如果微信js加载完成慢于调用微信预支付订单的接口返回数据。由于
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}else{
onBridgeReady(result);
}

这段判断,此时WeixinJSBridge 未初始化完成,故值为undefined 走if语句,此时的onBridgeReady方法没有要求传参数,故取不到data数据,调起支付的参数全都找不到,故调起支付失败。

解决方法:
1.修改if语句。
将if语句修改为如下:
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', function (){
onBridgeReady(result);
}, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', function (){
onBridgeReady(result);
});
document.attachEvent('onWeixinJSBridgeReady', function (){
onBridgeReady(result);
});
}
}else{
onBridgeReady(result);
}
当微信预支付订单调用完成且微信js未加载完成时,走if判断,此时页面会监听有没有WeixinJSBridgeReady,此时是没有,调起微信支付的时候将预支付订单返回的数据传给onBridgeReady函数作为参数。就仍可以调起微信支付。

方法2:
将自己的js逻辑代码用$(function(){});包裹起来,即在所有的js代码加载完成之后执行$(function(){});里面的函数代码,也可以达到想要的效果。

总结:
1.理解微信浏览器的运行机制,异步函数的运行机制。
2.写代码要注意走查,每一步要清除是做什么的,代码如何在浏览器上运行。
3.有目的性的排查问题,多思考,少些盲从的摸索会事半功倍。
原文地址:https://www.cnblogs.com/fsx77/p/10252114.html