uni-app微信支付、支付宝支付
首先要在微信支付商户平台申请接入对应的平台(APP,H5,小程序);支付宝支付也需要在支付宝开放平台申请对应的平台支付
1. 微信公众号中(H5)调用微信支付: 获取openid,引入微信公众平台API的微信H5支付JSSDK插件 或者 使用微信浏览器内置的onBrideReady(这种方式不需要引入JSSDK,但是只能在微信浏览器中使用)
// 引入微信JSSDK
var jweixin = require('@/js_sdk/[email protected]')
export function toWxPay(res) {
// res为下单后端接口返回的数据,微信支付需要的参数(appId,timeStamp,nonceStr,package,signType,paySign)是后端接口返回的,下单时需要传当前用户的openid
jweixin.config({
// debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.third_data.appId, // 必填,公众号的唯一标识
timestamp: res.third_data.timeStamp, // 必填,生成签名的时间戳
nonceStr: res.third_data.nonceStr, // 必填,生成签名的随机串
signature: res.third_data.authSign, // 必填,签名,见附录1
jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
jweixin.ready(function() {
// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
jweixin.chooseWXPay({
appId: res.third_data.appId, //公众号名称,由商户传入
timestamp: res.third_data.timeStamp, //时间戳,自1970年以来的秒数
nonceStr: res.third_data.nonceStr, //随机串
package: res.third_data.package,
signType: res.third_data.signType, //微信签名方式:
paySign: res.third_data.paySign, //微信签名
success: function(res) {
// console.log('支付成功' + res)
uni.showToast({
title: '支付成功'
})
setTimeout(function() {
uni.navigateBack({
delta: 1
})
}, 1000)
},
cancel: function(res) {
// console.log('取消支付' + res)
uni.showToast({
title: '取消支付',
icon: 'none'
})
},
fail: function(res) {
// console.log('支付失败' + res)
uni.showToast({
title: '支付失败',
icon: 'none'
})
}
})
});
jweixin.error(function(res) {
console.log('身份验证失效' + res)
});
}
// 微信浏览器内置支付方式,appid,timeStamp,nonceStr,package,signType,paySign参数值从接口获取
function onBridgeReady(res) {
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: "wx2421b1c4370ec43b", //公众号名称,由商户传入
timeStamp: "1395712654", //时间戳,自1970年以来的秒数
nonceStr: "e61463f8efa94090b1f366cccfbbb444", //随机串
package: "prepay_id=u802345jgfjsdfgsdg888",
signType: "RSA", //微信签名方式:
paySign: "70EA570631E4BB79628FBCA90534C63FF7FADD89", //微信签名
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 支付成功处理
}
}
);
}
export function wxBridegePay(res){
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady", onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", onBridgeReady);
document.attachEvent("onWeixinJSBridgeReady", onBridgeReady);
}
} else {
onBridgeReady(res);
}
}
2. 支付宝H5支付:通过支付宝扫码调起支付宝支付,后端配合获取用户buyer_id;下载或引入Alipay JSSDK,页面下单后接口返回对应的参数,再调用ap.tradePay唤起支付,有2种唤起方式,根据接口返回的参数类型调用
// 1.交易号唤起支付——tradeNO参数为页面下单后接口返回的交易号
function aliPay(tradeNO){
ap.tradePay({ tradeNO: tradeNO }, function(res){
if(res.resultCode == '9000'){
console.log("支付成功")
}else{
ap.alert('支付失败,'+res.resultCode);
}
});
}
// 2.订单字符串唤起支付——orderStr参数为页面下单后接口返回的交易字符串
function aliPay(orderStr){
ap.tradePay({ orderStr: orderStr}, function(res){
if(res.resultCode == '9000'){
console.log("支付成功")
}else{
ap.alert('支付失败,'+res.resultCode);
}
});
}
3. APP中调用微信支付、支付宝支付
export function appPay(orderInfo, provider) {
// orderInfo包含的key值
// orderInfo = {
// "appid": objData.appid,
// "noncestr": objData.noncestr,
// "package": objData.package,
// "partnerid": objData.partnerid,
// "prepayid": objData.prepayid,
// "timestamp": objData.timestamp,
// "sign": resObj.sign,
// }
// orderInfo为下单后端接口返回的数据,微信支付时provider为wxpay,支付宝支付时provider为alipay
orderInfo = JSON.stringify(orderInfo)
uni.requestPayment({
provider: provider,
orderInfo: orderInfo,
success: function(res) {
uni.showToast({
title: '支付成功'
})
setTimeout(function() {
uni.navigateBack({
delta: 1
})
}, 1000)
},
fail: function(err) {
console.log(err)
showTishi('支付失败')
}
});
}
微信支付调用出现错误 requestPayment:fail [payment微信:-1]General errors",“errCode”:-100,“code”:-100} 时问题排查:
uni-app请求封装
6. H5端跨域处理 —— 在manifest.json中新增跨域处理
"h5" : {
"devServer" : {
"port" : 9000,
"proxy" : {
"/api" : {
"target" : url, // url为接口地址
"secure" : false,
"changeOrigin" : true,
"pathRewrite" : {
"^/api" : "/web-admin" // web-admin是接口前面统一的参数,在这里统一处理下,没有的不用""
}
}
}
}
}
const BASE_URL = url // url是接口地址
export const request = (options) => {
return new Promise((resolve, reject) => {
// #ifdef MP-WEIXIN
options.url= BASE_URL + options.url
// #endif
// #ifdef H5
options.url= '/api' + options.url
// #endif
if(options.url !='/user/login'){
const token = uni.getStorageSync('token')
if(token){
options.header = {
'authorization':token
}
}
}
uni.request({
url: options.url,
method: options.method || 'GET',
data: options.data || {},
header: options.header ,
success: (response) => {
const res = response
// 请求携带authorization的时候就更新authorization的值,没有就不处理
if(res.header.authorization){
uni.setStorageSync('token',res.header.authorization)
}
if(res.statusCode !== 200){
uni.showToast({
title: res.data.message,
})
// 根据实际返回的code处理,我的403和440为需要登录的状态,自动跳转登录页面
if(res.statusCode == 403 || res.statusCode == 440){
uni.removeStorageSync('token')
uni.reLaunch({
url: '../login/login'
})
}
}
resolve(res)
},
fail: (error) => {
uni.showToast({
title: error.message
})
reject(error)
}
})
})
}
H5特殊处理
{
"path": "pages/home/index",
"style": {
"navigationBarTitleText": "首页",
"h5": {
"titleNView": false
}
}
}
padding-top: var(--window-top);
padding-bottom: var(--window-bottom);
uni.navigateTo({
url: '/pages/news/list?item='+encodeURIComponent(JSON.stringify((this.infoData)))
})
// 接收页面:
onLoad(option){
this.info= JSON.parse(decodeURIComponent(option.item))
console.log(this.info,'000')
}
// 有时url参数被转义:decodeURIComponent() 进行反转义
function GetRequest() {
var url = location.search; //获取url中"?"符后的字串
var params= new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for(var i = 0; i < strs.length; i ++) {
params[strs[i].split("=")[0]]=
decodeURIComponent(strs[i].split("=")[1]);
}
}
return params;
}
tabbar菜单使用了不显示title属性,页面顶部使用了fixed,滚动时状态栏能看到滚动上去的内容处理:给状态栏也设置fixed,并添加个背景色。
<template>
<!-- #ifdef APP-PLUS -->
<view class="status-bar"></view>
<!-- #endif -->
<view class="nav">内容</view>
</template>
<style lang="scss" scoped>
.status-bar{
height: var(--status-bar-height);
position: fixed;
width: 100%;
top: 0;
z-index: 9;
background: #ffffff;
}
</style>
其它知识累积
import package from 'packageName'
const package = require('packageName')
// npm安装方式引入
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
// 下载安装方式引入
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
@tab 在小程序不起作用;
navigator需要在同级目录下跳转,不同级的目录需添加 open-type=“switchTab” 属性;
uniapp微信小程序v-show不能和display:flex用在同一个元素上,flex的层级比v-show的display高,导致v-show无效,可以使用v-if