本文檔 當中所用到的: 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
作者:兮丶