本文檔 當中所用到的:
const $request = this.request
const post = $request.call('url',data)
post.then(res=>{}).catch()
是本身封裝的請求方法,如axios,參考時可自行更改
複製代碼
對全部發起請求的參數(包括公共參數),按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";vue
排序後對其進行md5: string = md5(string);//注意:這裏要過濾掉全部爲空的參數,空參數,不傳ios
將md5的串與密鑰再作一次md5: sign = md5( string + secret ); //sceret爲密鑰,後端分配web
/**
* 定義對象排序方法
*/
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;詳細參考微信官方文檔axios
<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('url',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('url', {
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)
複製代碼
在登陸時就獲取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"
}
複製代碼
**
* 支付
* 這裏的 $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中介紹)api
在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('url', {
order_id: order_id,//訂單號
pay_type: '',//支付方式
}, function(msg) {
uni.showToast({
title: msg,
icon:'none'
})
uni.navigateBack()
})
}
複製代碼
相對來講前端簡單不少,沒什麼麻煩要求 後臺會返回一個mwev_url ,window.location.href = mwev_url + redirect_uri (這裏的redirect_uri 是重定向的頁面地址,域名要和支付域名一致 !!!作編譯encodeURIComponent(url))瀏覽器
dopayWeb() { //非微信瀏覽器支付
const $request = this.request;
const post = $request.call('url', {
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)
});
},
複製代碼
function isMicroMessenger() {
let result = false;
let userAgent = window.navigator.userAgent;
if(userAgent.indexOf('MicroMessenger') > -1) {
result = true;
}
return result;
}
複製代碼