最近做的项目是H5的要实现在微信浏览器调起微信支付,先讲下大概流程:想要再微信浏览器调起微信支付 而且正常H5的调起微信支付不能改变 就要先判断一下浏览器,然后调起微信支付,想要调起微信支付首先要获取到openId想要获取openId就要先获取一个code 把code 发送给后端 然后获取token token里携带openid 然后 咱们再调接口 获取调起微信支付的所需参数。
H5调起微信支付就很简单就直接加载后端的一个h5_url 就可以调起微信支付 这里不做重点讲。
咱们先看下官方文档:
现在第一步判断浏览器:
//判断微信浏览器
export function isWechatBrowser() {
let status = navigator.userAgent.toLowerCase();
if (status.match(/MicroMessenger/i) == "micromessenger") {
//微信浏览器
return true
}else{
return false
}
}
因为这个判断浏览器再开发时经常用到我就给封装了一下。
然后就到了业务页面我们业务是这样的正常登录然后到了购买页面 点击立即购买先判断数据库里有没有这个账号的openId,如果没有的话就正常获取code,获取openId 然后调起微信支付,如果有openId 就直接调起微信支付
然后判断有没有openId 这个后端写个接口咱们请求一下就OK了
// 判断是否是微信浏览器
if (this.isWechatBrowser) {
// 调接口查看是否有openId
this.checkOpenIds(params)
}else{
//普通浏览器正常请求H5调起微信支付的链接
request.getpay(params).then((res) => {
if (res.code == 200) {
// #ifdef H5
window.location.href = href //调起微信支付
// #endif
}
})
}
调接口查看是否有openId
checkOpenIds(params) {
request.checkOpenId().then(res => {
if (res.code == 22) {
//接口返回结果 没有openId 然后就要获取code
const href = getCodeUrl(this.evaluationId)
window.location.href = href
} else {
this.getWxpay(params)
}
})
},
获取code链接我也封装了一下:
REDIRECT_URI:就是你公众号绑定域名下的地址 可以是详细地址可以直接是域名
今天调试微信用户授权功能时发现一个很是奇怪的问题,就是静默获取 加载href后链接里的地址无法复制出来,需要授权获取的可以复制出来链接里面携带code(这是个不小的坑 我就踩了 其实加载以后用alert(window.location.href) 是可以把携带code的url打印出来的)
尤其注意:跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。
//获取codeUrl
export function getCodeUrl(id) {
const APPID = 'your APPID '
const REDIRECT_URI = encodeURIComponent('https://***.*****.com/#/pages/details/index?id='+id)
const SCOPE = 'snsapi_base' //静默获取无需确定snsapi_base 需用户手动确定snsapi_userinfo
var href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=` + APPID +
`&redirect_uri=` + REDIRECT_URI + `&response_type=code&scope=` + SCOPE +
`&state=STATE#wechat_redirect`
return href
}
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
下一步就是要从url中把code给拿出来
onShow(option) {
// 判断浏览器
this.isWechatBrowser = isWechatBrowser()
// 打印url中是否存在code
// alert(window.location.href)
if(this.isWechatBrowser){
//调起获取code和把code发送给后端的方法
this.judgeCode()
}
},
//获取code和把code发送给后端的方法
judgeCode() {
var CODE = this.getQueryObject().code; //获取url中的code值
this.coode = CODE.toString()
// alert(this.coode)
if (this.coode) {
// 把code发送给后端
this.sendeCodeGetOpenId()
}
},
// 获取url中的code值
getQueryObject(url) { //可当成一个公用方法
url = url == null ? window.location.href : url;
let search = url.substring(url.indexOf("?") + 1);
// indexOf() 和 lastIndexOf() 都是索引文件
// indexOf() 是查某个指定的字符串在字符串首次出现的位置(索引值)(从左往右)
// lastIndexOf() 是查某个指定的字符串在字符串最后一次出现的位置(索引值)(从左往右) // lastIndexOf() 方法是从后往前搜索,但返回的位置是还是从前开始数的。
//看自己需求用indexOf还是lastIndexOf
let obj = {};
let reg = /([^?&=]+)=([^?&=]*)/g;
search.replace(reg, function(rs, $1, $2) {
let name = decodeURIComponent($1);
let val = decodeURIComponent($2);
val = String(val);
obj[name] = val;
return rs;
});
return obj;
},
首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。
尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。