小程序登錄、支付(小程序、H5)請求加密方法

原文鏈接:https://juejin.im/post/5dad2b816fb9a04e373178c6?utm_source=tuicool&utm_medium=referral
本文檔 當中所用到的:
		const $request = this.request
		const post = $request.call('passport/wxLogin',data)
		post.then(res=>{}).catch()
		是自己封裝的請求方法,如axios,參考時可自行更改
複製代碼

1、js生成接口請求參數簽名加密

定義規則:

對所有發起請求的參數(包括公共參數),按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爲密鑰,後端分配

/** 
 * 定義對象排序方法
 */
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;
	},
複製代碼

微信登錄

這裏採用 button的開放屬性 open-type 觸發@getuserinfo事件 獲取到code 發送給後臺 換取token 存到storge;詳細參考微信官方文檔

<template>
	<button openType="getUserInfo" lang="zh_CN" @getuserinfo="getUserInfo">授權登錄</button>
</template>


methods: {
    getCode(callback) {
    	wx.login({
    		success: res => {
    			console.log(res);
    			if (res.errMsg == 'login:ok') {
    				if (callback) {
    					callback(res.code)
    				}
    				this.code = res.code
    			}
    		}
    	});
    },
    getUserInfo(e) {
    	this.getCode(code => {
    		if (e.detail.errMsg !== 'getPhoneNumber:ok') {
    			return false;
    		}
    		wx.showLoading({
    			title: '正在登錄',
    			mask: true
    		});
    		const data = {
    			code:this.code,
    			iv:e.detail.iv,
    			encryptedData:e.detail.encryptedData
    		}
    		
    		//發起請求登錄
    		const $request = this.request
    		const post = $request.call('passport/wxLogin',data)
    		post.then(res =>{
    			console.log(res)
    			uni.setStorageSync('_user_login_token', res.data.token)
    		}).catch(err => {
    				//常規catch, 一般不用修改
    				$request.callError(err)
    		})
    	});
    }
}
複製代碼

微信小程序支付

首先獲取code{uni.login()} 然後調後臺接口 把code和訂單好傳給後臺,後臺 返回的數據就是小程序調支付的參數

{uni.requestPayment()} 就這麼簡單

const $request = this.request
const resLogin = await uni.login()
if (resLogin[0] !== null || resLogin[1].errMsg !== 'login:ok') {
	return uni.showToast({
		title: 'code獲取失敗',
		icon: 'none'
	})
}
const code = resLogin[1].code

const post = $request.call('order/doPay', {
	order_id: this.order_id,
	pay_type: '無忌微信小程序支付',
	code: code
})
post.then(data => {
	// 返回數據,只返回接口中的data
	const result = JSON.parse(data.data.pay_data)//字符串轉對象
	uni.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))
			this.requestDetail()
		},
		fail: err => {
			console.log('fail:' + JSON.stringify(err))
		}
	})
}).catch(function(e) {
	//常規catch, 一般不用修改
	$request.callError(e)
複製代碼

4、H5支付(微信內瀏覽器/JSPAI)

獲取code

在登錄時就獲取code,後臺得到openId將其存起來,之後後臺在用到openId的地方就不用再獲取了(不會過期)

getCode(){
	let appid = {appid}
	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"
}
複製代碼

封裝H5支付代碼

**
 * 支付
 * 這裏的 $request.call()爲自己封裝的請求方法,使用時請自行更改
 */
var payH5 = {
	onBridgeReady: function(url, $params,success) {
		const post_H5 = $request.call(url, $params)
		post_H5.then(data => {
			// 返回數據,只返回接口中的data
			const result_H5 = JSON.parse(data.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") {
						var msg = '支付成功';
						success(msg)
					} else {
						var msg = '支付失敗';
						success(msg)
					}
				});
		}).catch(function(e) {
			//常規catch, 一般不用修改
			$request.callError(e)
		})
	},

	doPay(url, $params,success) {
		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,success)
		}
	}
}

export default payH5
複製代碼

支付調用

將這個文件引入需要的頁面或者掛載到vue原型上(這裏以uni-app中介紹)

在main.js中 引入: 
				import H5Pay from './api/h5Pay.js'
				Vue.prototype.H5Pay = H5Pay

頁面引用:

			this.H5Pay.doPay(url,params,callback)
參數:	 	  url:接口請求地址
			params:請求參數
			callback:回調方法(回調支付結果)

H5pay(){
	this.H5Pay.doPay('order/doPay', {
					order_id: order_id,//訂單號
					pay_type: '',//支付方式
				}, function(msg) {
					uni.showToast({
						title: msg,
						icon:'none'
					})
					uni.navigateBack()
				})
}
複製代碼

5、H5支付(非微信內置瀏覽器)

相對來說前端簡單很多,沒什麼麻煩要求 後臺會返回一個mwev_url ,window.location.href = mwev_url + redirect_uri (這裏的redirect_uri 是重定向的頁面地址,域名要和支付域名一致 !!!做編譯encodeURIComponent(url))

dopayWeb() { //非微信瀏覽器支付
	const $request = this.request;
	const post = $request.call('order/doPay', {
		order_id: this.order_id,//訂單號
		pay_type: 'nweb'//支付方式
	});
	post.then(res => {
		console.log(res);
		let url = res.mwev_url
		let redirect_uri = encodeURIComponent(url)
		window.location.href = url + "&redirect_uri=" + redirect_uri 
	}).catch(function(e) {
		$request.callError(e)
	});
},
複製代碼

6、 區分是否是微信內置瀏覽器

function isMicroMessenger() {
    let result = false;
    let userAgent = window.navigator.userAgent;    
    if(userAgent.indexOf('MicroMessenger') > -1) {
        result = true;
    }
    return result;
}
複製代碼

原文地址:http://www.wxapp-union.com/portal.php?mod=view&aid=5615

作者:兮丶

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章