支付中的微信支付在上线中出了问题,反思了下原因:
1.测试时因为不能在测试环境支付,所以就没有测试,自己也没有再去验证。(即使是无法测试环境测的,没有把握也还是要自己测一遍,最起码代码要全,流程假数据能走通)
2.微信支付分普通浏览器支付和微信浏览器调起微信支付。其中微信浏览器调起微信支付会比较麻烦
3.微信浏览器调起微信支付需要商户配置允许的支付链接,否则会提示支付的链接无效。
———————————————————————————————————————
下面就是如何进行的微信支付
可参考的微信支付的官网文档链接
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6
首先要在微信商户平台(pay.weixin.qq.com)上配支付的链接,否则在实际操作中,最后支付时提示“当前页面的ULR未注册”。
支付时,接口中要求传用户openid,而获取openid则需要在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。(这也是为什么测试环境无法测试的原因,因为域名不同)
对于前端来说,首先页面要做的第一步分辨是否是微信浏览器还是普通浏览器
if(navigator.userAgent.indexOf("MicroMessenger")>-1){//微信浏览器
terminalType=3;
}else if(/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {//普通浏览器
terminalType=2;
}
当发现是微信浏览器后区分是IOS还是安卓手机,分别请求不同的链接(相当于调用接口)
if (navigator.userAgent.indexOf("MicroMessenger") > -1) { //微信浏览器
if (!!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { //ios
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxxxxx&redirect_uri=https://执行支付页面.html&response_type=code&scope=snsapi_base&state=1#wechat_redirect";
} else {//安卓手机
window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=xxxxxxxxx&redirect_uri=https://执行支付页面.html%0A&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
}
}
这里其实我没懂为什么区分IOS还是安卓,上网看的案例没有区分安卓还是IOS,但是之前的是这么写的,而且这样确实可以成功,所以还是照着之前的逻辑没有动。
这个链接其实是个Get方法请求的接口。关于这个链接(接口)的相关配置参数可以参考这个链接
https://www.cnblogs.com/hejun26/p/9908887.html,里面讲的很详细。
5.请求上述链接(接口)后会得到一个返回链接:https://充值页面.html?code=xxxxxxxxxxxxx&state=123
这个链接里有code参数,利用一个函数getQueryString得到,(注意:获得的参数不包括state=123部分哦)
code = getQueryString("code");
//获得url参数
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
6.对于我就是前台传包括code的一些参数给后台。对于后台,把code传进去获得返回值
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+ WECHAT_ACCOUNT_APPID +"&secret="+WECHAT_ACCOUNT_SECRET + "&code=" + code + "&grant_type=" + WECHAT_ACCOUNT_GRANTTYPE ;
7.前端获得后端返回值后,得到appid,timeStamp,noceStr,package,paySign这几个参数,进行判断,执行以下代码
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(appid,timeStamp,nonceStr,package,paySign);
}
onBridgeReady: function(appId, timeStamp, nonceStr, package, paySign) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": appId, //公众号名称,由商户传入
"timeStamp": timeStamp, //时间戳,自1970年以来的秒数
"nonceStr": nonceStr, //随机串
"package": package,
"signType": "MD5", //微信签名方式:
"paySign": paySign //微信签名
},
function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
window.location.href = "支付成功跳转页面";
}
}
);
}
其中碰到的问题
1.自测的时候,想页面调试,但是微信浏览器的链接无法在电脑打开。就是下面的这个链接
https://open.weixin.qq.com/connect/oauth2/authorize?appid=XXXXXXXXX&redirect_uri=https://ABC.html%0A&response_type=code&scope=snsapi_base&state=123#wechat_redirect
这种类型的链接是无法在普通浏览器(电脑端)打开的,在电脑上下载微信开发者工具,然后再打开。会提示要公众号绑定你的开发者微信号。(我没绑定,实际上我把链接传手机上,用手机打开,然后复制链接,获得Get方法请求这个微信链接的返回值。怕麻烦的童鞋可以这样试试,但是只限于线上环境存在https://ABC.html这个页面才可以)。
2.在微信开发者工具里模拟支付时,最后 WeixinJSBridge.invoke会报错:chooseWXPay:fail, the permission value is offline verifying,但是实际上用真机的时候可以调通。
3.前端传后台时需要一个cip参数,用来放用户的位置和IP信息,这里我们用的是http://pv.sohu.com/cityjson?ie=utf-8这个链接直接获得。在测试环境里引入这个链接没有问题。
cip = returnCitySN.cip;
但在实际线上环境里会报错,因为我们的域名是https,在https里引入http现在被判断为不合法,[ HTTPS页面里动态的引入HTTP资源,比如引入一个js文件,会被直接block掉的。在HTTPS页面里通过AJAX的方式请求HTTP资源,也会被直接block掉的。]
参考链接:https://www.cnblogs.com/webARM/p/5728695.html
网上有的解决方法是引入方式改为:
但是在电脑端微信开发者工具上,我测试的时候发现依然报错:https://pv.sohu.com/cityjson?ie=utf-8 net::ERR_CONNECTION_ABORTED; Uncaught ReferenceError: returnCitySN is not defined
不过在实际的手机上可以正常运行。