1 登录篇
1.1 微信登录
1.1.1 微信小程序
登录流程时序
说明
1.调用wx.login()获取 临时登录凭证code ,并回传到开发者服务器 2.调用auth.code2Session接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key 之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
注意
1.会话密钥 session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
2.临时登录凭证 code 只能使用一次
const request = require('/api/index.js');
login() {
const that = this;
return new Promise((resolve, reject) => {
wx.checkSession({
success() {
resolve();
},
fail() {
wx.login({
success: res => {
request.post('/user/login', {
code: res.code
}).then(res => {
let token = res.data.token;
wx.setStorageSync('token', token);
resolve();
})
}
})
}
})
})
}
code:用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用auth.code2session,使用code换取openid和sessionkey等信息。
1.1.2 微信公众号
微信公众号采用的是oauth2的登录授权方式; 简单来讲,就是
1.1 用户用过微信确认登录之后,微信方会返回一个授权码code给回第三方(接入方),这个授权码 >是一次性的,且有效期时间比较短; 1.2 第三方通过此code去调用微信接口获取token,token的有效期也比较短; 1.3 通过token再去调用微信平台接口,获取微信个人信息(昵称,头像地址,openid,unionid,地区……)
2.1 通过重新赋值location.href,并传入服务号的appId以及redirect_uri跳转微信授权链接
2.2 经过用户同意获取code;这里redirect_uri授权的页面地址,里面的location.host必须要经过授权才行,否则官方不会承认这个地址,也就不会返回code。 示例如下(具体配置参考官方文档)
export const requestWxCode = () => {
const REDIRECT_URI = [location.protocol, "//", location.host, location.pathname].join('')
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_userinfo&state=ok#wechat_redirect`
}
3.授权回调域名过程: ①拿服务号的账号和密码登录微信管理后台,找到网页授权 ② 填写授权回调域 ③ 将MP_verify_NWxYqcEY0l6bdRam.txt下载下来上传至填写域名或路径指向的web服务器(或者虚拟主机)的目录;校验确保可以访问; ④注意第三步,对于首次使用的域名,服务器根目录下是没有的,所以即便你在本地放置了,依旧是访问不到的;所以要么自己放置后部署,要么找运维手动放置;当可以点击“保存”时,就说明回调域名授权成功
具体登录逻辑
- 4.1 先判断是否在微信应用内打开,只有在应用内打开,才能调用微信的授权链接;
- 4.2 判断缓存中是否有有效token(token存在并且未过期),如果有则可直接去接口请求;
- 4.3 如果token不存在或者存在但已过期,则需要重新判断code,看链接上是否存在code或者code是不是重复的(重复的意味着一定不可用了,因为code是一次性的)
- 4.4 如果code不存在,则手动重定向路由,以调用微信的授权链接如下:
location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${APP_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=snsapi_userinfo&state=ok#wechat_redirect`
用户同意授权后,就会发现路由地址变成了https://h5.xxxx.com/lvy-pay?code=0014sGyh2lXvIC05NYvh2B3qyh24sGyY&state=ok,上面含有code,取到code,向服务器换取token,并将此token及过期时间存到缓存中,方便下次打开时直接调用;这时就可以放开去发接口请求了
具体可参考 微信公众平台开发——微信授权登录(OAuth2.0) 微信开放平台
1.2 支付宝登录
1.2.1 支付宝小程序
let self = this;
uni.getProvider({
service: 'oauth',
success: function(res) {
self.provider = res.provider[0];
uni.login({
provider: self.provider,
success: loginRes => {
console.log('01----authCode获取成功', loginRes.authCode)
uni.getUserInfo({
provider: self.provider,
success(infoRes) {
mypublicing(
"/auth/applet/login", {
code: loginRes.authCode,
client: 'zfb'
})
.then(res => {
if (res.data.code == 200) {
self.zfb.openId =res.data.data.openid;
console.log("02----openid获取成功",self.zfb)
if (res.data.data.access_token) {
uni.setStorageSync('token',red.data.data.access_token);
}
} else {
uni.showLoading({
title: "code换openid失败",
});
}
})
}
});
}
});
}
});
2 支付篇
2.1 微信支付
2.1.1 H5支付
H5支付是指,前端在浏览器唤起微信app,支付成功后再回到浏览器。
前端发起请求,需要后台server 支持,请求微信支付服务,返回前端微信支付的链接。我们的回调地址,会以redirect_url 的形式拼的返回的链接后面,前端打开这个链接,就可以唤起微信支付。完成微信支付后,会回到回调地址。
常见链接形如下面:
MWEB_URL= wx.tenpay.com/cgi-bin/mmp…
任务流程图
主要页面跳转: 泳道图
注意点
1.当我们把h5页面嵌入到app内使用时,问题:ios 端在微信支付成功或者取消支付后,停留到了微信,无法回到app.会打开safari 我们做了一个中转页面,专门供iOS 使用,在浏览器打开时,我们会以url schema 的形式唤起app,打开支付结果页面。
2.注意微信xyRedirectUrl 编码后长度不可超过 800 微信支付会报错
2.1.2 微信小程序支付
小程序需要通过微信认证,开通微信支付能力。需要商户号资质,一般个人开发比较难搞 调用方式比较JSAPI 较为简单,因为是在微信环境内,兼容性问题较少。
appId: "wx5*5f7119*de*513"
nonceStr: "JGIGiEuHY*nhyVvWpJcmeJ4W*Sa0VsdY"
package: "prepay_id=wx2011*407469034*38132bda7cdc6690000"
paySign: "A9A3AF*8197CF11A077*DD226566AAFB"
signType: "MD5"
timeStamp: "1658287447"
wx.config({
debug: true,
appId: '',
timestamp: ,
nonceStr: '',
signature: '',
jsApiList: [
'updateAppMessageShareData',
'updateTimelineShareData',
'onMenuShareWeibo',
'onMenuShareQZone',
'startRecord',
'stopRecord',
'onVoiceRecordEnd',
'playVoice',
'pauseVoice',
'stopVoice',
'onVoicePlayEnd',
'uploadVoice',
'downloadVoice',
'chooseImage',
'previewImage',
'uploadImage',
'downloadImage',
'translateVoice',
'getNetworkType',
'openLocation',
'getLocation',
'hideOptionMenu',
'showOptionMenu',
'hideMenuItems',
'showMenuItems',
'hideAllNonBaseMenuItem',
'showAllNonBaseMenuItem',
'closeWindow',
'scanQRCode',
'chooseWXPay',
'openProductSpecificView',
'addCard',
'chooseCard',
]
},
wx.error(function(res){
});
);
wx.requestPayment({
"timeStamp":"",
"nonceStr": "",
"package": "",
"signType": ,
"MD5",
"paySign": "",
"success":function(res){},
"fail":function(res){},
"complete":function(res){}
})
2.2 支付宝支付
支付宝支付
2.2.1 H5支付
任务流程图 主要页面跳转:
代码:
// 后台接口返回来的是form标签字符串
let _str = `
<form id='alipaysubmit' name='alipaysubmit' action='https://openapi.alipay.com/gateway.do' method='POST'>
<input type='hidden' name='app_id' value='201805106……'/>
<input type='hidden' name='method' value='alipay.trade.page.pay'/>
<input type='hidden' name='format' value='JSON'/>
<input type='submit' value='ok' style='display:none;''>
</form> <script>document.forms['alipaysubmit'].submit();</script>`;
_str = _str.replace(/form/, 'form target="_blank"');
div.innerHTML=_str; document.body.appendChild(div); document.forms.alipaysubmit.submit();
或
1.直接调用后台的支付接口
const params = {}
alipay(params).then(res => {
const { data } = res
if (!data.alipay_trade_wap_pay_response) {
document.querySelector('body').innerHtml = res.data;
document.forms[0].submit()
} else {
console.log('支付宝支付失败');
Toast(data.alipay_trade_wap_pay_response.msg)
}
})
2.2.2 APP支付
2.2.3 支付宝小程序支付
trade_no: "2022072022001495141459520641"
uni.requestPayment({
provider: 'alipay',
orderInfo: trade_no,
success: function(res) {},
fail: function(err) {},
complete:function(res){}
})
|