本文以uni-app为例,介绍下: 微信小程序登录、支付(小程序、微信H5、非微信H5)即请求加密方法
微信调整了获取用户信息的API,故不推荐使用button的@getuserinfo方法,使用DOM的点击事调用getUserProfileAPI 获取用户信息。
tips: 解密userInfo的信息 调用getUserProfile可能会刷新session_key,故新的code会解密失败,需要使用之前的code,这里使用了简单粗暴的方式,在页面show的钩子中调用wx.login,每次授权是再调用一次,确保解密信息的解密code和加密时的一致。
html
复制代码
<template> <button @tap="getWxUserinfo">微 信 登 录</button> </template>
javascript
复制代码
export default { data() { return { wxCode: null } }, onShow() { this.getCode() }, methods: { // 获取 wxCode getCode(callback) { wx.login({ success: res => { this.wxCode = res.code callback && callback(res.code) } }); }, // 获取用户信息 getWxUserinfo() { wx.getUserProfile({ desc: '用于完善用户资料', success: res => { console.log(res) wx.showLoading({ title: '正在登录', mask: true }) this.getCode(code => { const data = { code: this.wxCode, iv: res.iv, encryptedData: res.encryptedData } //发起请求登录 wx.request({ url: '/api/login', method: 'POST', success: res => { console.log(res); // 登录成功 wx.hideLoading() } }) }) }, fail: err => { // 获取信息失败 console.log(err) } }) } } }
首先获取code即使用uni.login()然后调后台接口 把code和订单号传给后台,后台返回的数据就是小程序调支付的参数,然后调用uni.requestPayment()就可以了
javascript
复制代码
wx.login({ success: res => { wx.request({ url: '/api/wxpay', method: 'POST', data: { code: res.code, order_id: '订单id', // 后台接口参数 示例 pay_type: 'wxpay', // 后台接口参数 示例 }, success: res => { // 返回数据是json字符串,转为对象 - 具体根据后台返回数据操作 const result = JSON.parse(res.data.pay_data) wx.requestPayment({ provider: 'wxpay', timeStamp: result.timeStamp, nonceStr: result.nonceStr, package: result.package, signType: result.signType, paySign: result.paySign, success: res => { // 支付成功 console.log('success:' + JSON.stringify(res)) }, fail: err => { // 支付失败 console.log('fail:' + JSON.stringify(err)) } }) } }) } })
在登录时就获取code,后台得到openId将其存起来,之后后台在用到openId的地方就不用再获取了(不会过期)
javascript
复制代码
getCode(){ let appid = 'xxxxxxxxxxxx' let url = 'https://xxx.xxxx.xxx' let redirect_uri = encodeURIComponent(url)//回调页面地址 window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + redirect_uri + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect" }
javascript
复制代码
** * 支付 * url 后台下单接口地址 * data 下单参数 * callback 回调函数 */ const payH5 = { onBridgeReady: function(url, data, callback) { wx.request({ url, method: 'POST', data, success(res) { // 后台返回的数据因为是字符串,转换对象 const result_H5 = JSON.parse(res.data.pay_data) WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": result_H5.appId, //公众号名称,由商户传入 "timeStamp": result_H5.timeStamp, //时间戳,自1970年以来的秒数 "nonceStr": result_H5.nonceStr, //随机串 "package": result_H5.package, "signType": result_H5.signType, //微信签名方式: "paySign": result_H5.paySign //微信签名 }, function(res) { if (res.err_msg == "get_brand_wcpay_request:ok") { callback && callback('支付成功') } else { callback && callback('支付失败') } } ); }, fail(err) { console.log('网络错误:', err) } }) }, doPay(url, $params, callback) { if (typeof WeixinJSBridge == "undefined") { if (document.addEventListener) { document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady, false); } else if (document.attachEvent) { document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady); } } else { this.onBridgeReady(url, $params, callback) } } } export default payH5
将这个文件引入需要的页面或者挂载到vue原型上(这里以uni-app中介绍)
javascript
复制代码
// 引入: import H5Pay from './api/h5Pay.js' // H5Pay.doPay(url,params,callback) export default { methods: { H5pay(){ H5Pay.doPay( 'url', { order_id: order_id,//订单号 pay_type: '',//支付方式 }, function(msg) { // 支付结果 console.log(msg) } ) } }
相对来说前端简单很多,没什么麻烦要求 后台会返回一个url,window.location.href = mwev_url + redirect_uri(这里的redirect_uri是重定向的页面地址,域名要和支付域名一致 !!! url 需要encodeURIComponent编码
javascript
复制代码
dopayWeb() { //非微信浏览器支付 wx.request({ url: '/api/h5pay', method: 'POST', data: { order_id: '订单id', // 后台接口参数 示例 pay_type: 'wxpay', // 后台接口参数 示例 }, success(res) { console.log(res); const url = res.pay_url const redirect_uri = encodeURIComponent(url) window.location.href = url + "&redirect_uri=" + redirect_uri }, fail(err) { console.log('网络错误') } }) },
javascript
复制代码
function isMicroMessenger() { let userAgent = window.navigator.userAgent; if(userAgent.indexOf('MicroMessenger') > -1) result = true; return false; }
对所有发起请求的参数(包括公共参数),按key进行升序排序 ,然后组合成key1=value1&key2=value2的形式
如:parames = {b:value-b, c:value-c,a:value-a}排序后应为:string = "a=value-a&b=value-b&c=value-c"排序后对其进行md5: string = md5(string)注意:这里要过滤掉所有为空的参数,空参数,不传 将md5的串与密钥再做一次md5: sign = md5( string + secret ),sceret为密钥,后端分配
javascript
复制代码
/** * 定义对象排序方法 */ objectSort(parames) { var newkeys = Object.keys(parames).sort(); var newObj = {}; for(var i = 0; i < newkeys.length; i++) { newObj[newkeys[i]] = parames[newkeys[i]]; } return newObj; } /** * 计算签名方法 */ makeSign(params) { var sign = ''; var parm = ''; params = objectSort(params); for (let i in params) { var j = params[i]; parm += i + '=' + j + '&'; } parm = parm.slice(0,-1); parm.trim(); sign = Md5.md5(Md5.md5(parm)+$secret);//$secret为密钥,后端分配 return sign; }, /** * 过滤data参数中的空字符 */ filterData(data){ var result = {}; for (let i in data) { var value = data[i]; if (typeof (value) == 'undefined') { value = ''; } if(typeof(value) == 'string'){ value = value.trim(); } if(value) { result[i] = value; } } return result; }, /** * 构建data参数 */ bulidData(data) { if(typeof(data) != 'object'){ data = {}; } //构建参数 data.timestamp = (new Date()).valueOf(); data.app_id = Config.app_info.app_id; //过滤 data = this.filterData(data); //检测用户是否登录 var token = Helper.user.getToken(); if(token) { data.token = token; } data.sign = this.makeSign(data); return data; },
联系我们
友情链接:
小程序开发 小程序定制开发 小程序商店 微信小程序开发文档 分销商城小程序 电商小程序开发 百家号 商城小程序 微信小程序开发API 小程序定制 生鲜小程序 全平台开发 网站建设 外包开发 自主研发产品 sitemap robots热门地区:
松江开发公司 青浦开发公司 崇明开发公司 杨浦开发公司 宝山开发公司 奉贤开发公司 虹口开发公司 闵行开发公司 长宁开发公司 静安开发公司 黄浦开发公司 嘉定开发公司 徐汇开发公司 金山开发公司 上海开发公司 南昌开发公司 杭州开发公司 上饶开发公司COPYRIGHT 2009-2016 www.guanzhiweb.com ALL RIGHTS RESERVED
版权所有 上海观智网络科技有限公司