h5调用微信支付相关记录
步骤流程
- 微信授权拿到code(https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html)
- 用code换取openid(这一步一般是后台提供接口)
- 用生成的openid去获取微信支付需要的参数(也是接口处理)
- 前端调用微信方法,拉起微信支付
根据上面的流程执行
- 添加微信授权逻辑,完成微信授权获取code,通过code拿到openid存在本地
<!-- 先获取地址栏参数code -->
const code = getUrlParam('code');
<!-- 获取cookie,wx-openid为微信授权成功后,通过code向服务端接口获取到的openid,存入本地,两个小时后失效 -->
const wxOpenid = getCookie('wx-openid');
if(!wxOpenid){
// 1.没有微信授权,需要先去授权
if(!code){
var link = window.location.href.split("?")[0];
<!-- scope = snsapi_base 表示静默授权 -->
var wxAuthUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的服务号id&redirect_uri="+link+"&response_type=code&scope=snsapi_base&state=code#wechat_redirect";
location.href = wxAuthUrl;
}else{
// 地址栏里能取到code,且cookie里面没有wxOpenid,此时需要调用接口用code换取token
codeToToken();
}
}
// 用微信授权的code去接口换取token,并存入本地cookie
function codeToToken(){
$.ajax({
type: "POST",
dataType: "json",
url: "http://111/111/111",
data:{code:code},
success: function (data) {
console.log(data);//打印服务端返回的数据(调试用)
if (data.code === 200) {
// 将取到的token存入cookie,1.8小时
setCookie("wx-openid",data.data,1.8);
}
}
});
}
function getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
var r = window.location.search.substr(1).match(reg); //匹配目标参数
if (r != null) return unescape(r[2]); return null; //返回参数值
}
function setCookie(objName, objValue, objHours) {
var str = objName + "=" + escape(objValue); //编码
if (objHours > 0) {//为0时不设定过期时间,浏览器关闭时cookie自动消失
var date = new Date();
var ms = objHours * 3600 * 1000;
date.setTime(date.getTime() + ms);
str += "; expires=" + date.toGMTString();
}
document.cookie = str;
}
function getCookie(key){
var arr1=document.cookie.split("; ");//由于cookie是通过一个分号+空格的形式串联起来的,所以这里需要先按分号空格截断,变成[name=Jack,pwd=123456,age=22]数组类型;
for(var i=0;i<arr1.length;i++){
var arr2=arr1[i].split("=");//通过=截断,把name=Jack截断成[name,Jack]数组;
if(arr2[0]==key){
return decodeURI(arr2[1]);
}
}
}
- 用生成的openid去获取微信支付需要的参数(也是接口处理)
<!-- 引入微信js -->
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<!-- 这一步一般是用点击页面的按钮触发一个方法 -->
// 判断是否有wx-openid,没有wx-openid就刷新页面重新开始微信授权和获取wx-openid(当进入页面时wx-openid没有过期,当准备支付时改cookie过期了)
if(!getCookie('wx-openid')){
location.href=window.location.href.split("?")[0];
}
let payParam = {}
$.ajax({
type: "POST",//方法类型
dataType: "json",//预期服务器返回的数据类型
async:false,
url: "http://222/222/222" ,//url
data:{"接口需要的参数":"根据接口需要提供的参数值"},
success: function (date) {
if (date.code == 200) {
payParam = JSON.parse(date.data);
weixinPay()
}else {
alert("接口调用失败,拉去微信授权失败")
}
},
});
function weixinPay() {
if (typeof WeixinJSBridge !== 'undefined') {
onBridgeReady();
return;
}
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
}
function onBridgeReady() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId:payParam.appId, // 公众号名称,由商户传入
// timeStamp:时间戳,自1970年以来的秒数,需要传递string类型,测试过程中发现如果传递的是number类型,android拉起微信支付会报错,提示调用支付JSAPI缺少参数:timeStamp,ios正常可以拉起微信支付
timeStamp:"" + payParam.timeStamp,
nonceStr:payParam.nonceStr, // 随机串
package: payParam.package,
signType:payParam.signType, // 微信签名方式:
paySign:payParam.paySign, // 微信签名
}, res => {
switch (res.err_msg) {
case 'get_brand_wcpay_request:ok':
alert("支付成功,可以在此添加支付成功的回调");
break;
case 'get_brand_wcpay_request:cancel':
alert("取消支付");
break;
case 'get_brand_wcpay_request:fail':
alert("失败");
break;
default: break;
}
<!-- 好了,到此就已经拉起了微信支付了 -->
});
}
在开发中遇到的问题
-
微信授权获取code,这一步操作在调用接口http://222/222/222时,接口那边操作的,非前端处理
这一步当时是行不通的,因为调用接口http://222/222/222时,接口响应的是this.ctx.redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的服务号id&redirect_uri="+link+"&response_type=code&scope=snsapi_base&state=code#wechat_redirect',302);
但是我们需要接口响应的是json数据,通过抓包工具分析后,我们更换了方案,由前端来进行微信授权 -
前端微信授权,由于302来回跳转,页面有跳转记录,在ios的微信上,底部会出现回退操作栏,产品要求去掉
找了很多方案,发现去不掉,最后使用了node渲染页面,在node层进行微信授权,发现可以解决这个问题 -
开发过程中,刚开始存入cookie的不是通过code获取的openid 而是code,当第一次授权成功,超过5分钟进入页面,从cookie里面拿到code,调起微信支付时,传给接口的是code,接口通过code去换取openid
但是此时code已经过期,code只有5分钟有效期,openid有两个小时的有效期