本文主要是梳理在微信浏览器中调起微信支付的整个过程,以及主要过程当中界面的展现效果。虽然整个交易过程看起来很简单,就是输入金额,而后调起微信支付,输入密码完成交易,可是在实现过程当中,是须要对接微信公众平台和微信商户平台的,这块比较繁琐。javascript
流程图:
在微信浏览器中调起微信支付,有那么几方面的交互:h5微信、h5服务器、服务器微信服务器。三方面一个不能少。总体流程大体以下:php
下面具体说明下每一个环节要作的事情。
注册公众平台
这里注意一点,目前支付能力只支持服务号,对于我的的订阅号是不支持的。申请支付能力须要提交的信息可能比较繁琐。在开发->基本配置中便可看到AppId
绑定域名
必定按照微信规定的格式填写域名,而且将MP_verify_3GXUmRy2Q1SznaIC.txt文件拷贝到与名对应的服务器根目录下。
h5请求微信服务器获取codehtml
//服务器接口
var baseURL = 'http://192.168.1.46:8080/alipay';
sessionStorage.setItem('baseURL', baseURL);
//公众号appid
var appId = "wx62343e380757XXXX";
sessionStorage.setItem('appId', appId);
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;
}
// 微信平台,支付宝,其余
var browserType = (function() {
var ua = window.navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i) == 'micromessenger') {
return 1;
} else
if(ua.match(/AlipayClient/i) == 'alipayclient') {
return 2;
} else {
return 3;
}
})();
// 获取
var userId, code;
try {
userId = getQueryString('userId');
//测试
// userId = "10914918196281681006";
if(userId) {
sessionStorage.setItem('userId', userId);
}
code = getQueryString('code');
if(code) {
sessionStorage.setItem('code', code);
}
} catch(e) {
weui.alert('获取数据出错!');
throw new Error('upload error');
}
var currentUrl = location.href;
// 判断平台
if(browserType == 1) {
if(!code) {
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + currentUrl + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
return;
}
} else if(browserType == 2) {} else { //其余浏览器
weui.alert('当前浏览器不支持!');
return;
}
//直接跳转到支付界面
location.replace('userPayDesk.html');
h5请求服务器获取openId
中间有个过程,即服务器请求微信服务器获取openId后返回给前端。
h5跨域请求能够用ajax,或者axios跨域。服务器端请求在此不讨论。前端
// 请求后台,获取openId等
var instance = axios.create({
baseURL: baseURL,
timeout: 10000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
instance.post(
'/scan/getOpenID',
'code=' + code
)
.then(function(response) {
var res = response.data;
//
if(res.code == '0000') {
var openId = res.response.openId;
try {
sessionStorage.setItem('openId', openId);
//跳转到支付页面
location.replace('userPayDesk.html');
} catch(e) {
weui.alert('当前手机版本不支持!');
throw new Error('sessionStoragr unsurpport');
}
} else {
weui.alert(res.msg);
}
})
.catch(function(error) {
});
输入金额
界面展示以下:java
最后会将源码上传上去,界面样式你们能够参考下。ios
付款,请求统一下单
这里传递的参数能够根据需求来定,我须要用到商户的userId以便服务器区分是支付给哪一个商户方便记帐。web
// 系统下单
instance.post(
' /pay/appScanPay',
'transAmount=' + moneyFloat + '&userId=' + userId + '&openId=' + openId + '&browserType=' + browserType
)
.then(function(response) {
var res = response.data;
code = '';
if(res.code == '0000') {
if(res.response.hasOwnProperty('payInfo') && res.response.payInfo) {
//保存订单号和建立日期
sessionStorage.setItem('transTime', res.response.transTime);
sessionStorage.setItem('orderId', res.response.orderId);
sessionStorage.setItem('amount', res.response.amount);
wxPay(res.response.payInfo);
} else if(res.response.hasOwnProperty('qrCode')) {
location.href = res.response.qrCode;
}
} else {
weui.alert(res.msg, function() {
location.replace('userPay.html');
});
}
setTimeout(function() {
loading2.hide();
}, 200);
})
.catch(function(error) {
weui.alert('系统繁忙');
});
h5调起微信支付
这里利用微信浏览器的私有操做方法WeixinJSBridge.invoke,对于想用jweixin-1.0.0.js的,能够参照其官方文档来,这里就不赘述了,文档地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115ajax
// 调用微信支付接口
function wxPay(payInfo) {
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(payInfo);
}
function onBridgeReady(payInfo) {
WeixinJSBridge.invoke(
'getBrandWCPayRequest', {
"appId": payInfo.appId, //公众号名称,由商户传入
"timeStamp": payInfo.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr": payInfo.nonceStr, //随机串
"package": payInfo.package, //订单详情扩展字符串
"signType": payInfo.signType, //微信签名方式:
"paySign": payInfo.paySign //微信签名
},
function(res) {
if(res.err_msg == "get_brand_wcpay_request:ok") {
//
location.replace('userPaySuccess.html');
// weui.alert("付款成功", function() {
// WeixinJSBridge.call('closeWindow');
// });
} else {
weui.alert("付款失败", function() {
location.replace('userPay.html');
});
}
}
);
}
}
支付成功,重定向到成功页面:
成功页面以下:axios
小技巧:
这里分享一个在微信浏览器操做的小技巧,就是对于安卓用户,可能会点击物理返回键,这时候你可能不但愿重定向到上一页,这里能够参考下个人作法,就是点返回键直接退出微信浏览器:api
pushHistory();
var bool = false;
setTimeout(function() {
bool = true;
}, 1500);
window.addEventListener("popstate", function(e) {
if(bool) {
WeixinJSBridge.call('closeWindow');
}
pushHistory();
}, false);
function pushHistory() {
var state = {
title: "title",
url: "#"
};
window.history.pushState(state, "title", "#");
}