uni-app微信支付宝支付,requestPayment:fail [payment微信:-1],H5遮挡内容、APP状态栏透明、url参数转义、 uview-ui引入、APP公众号小程序兼容性

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} 时问题排查:

  1. orderInfo 参数的key值全部为小写,并且为json格式
  2. provider值为wxpay
  3. 模拟器环境有时候调起成功后再多次调用也会出现这种情况,打包后就是正常的了
  4. 以上几种情况都确认无误只能是后端的问题的,可能是配置的appid、签名等信息、申请时填写的app信息等不正确导致

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是接口前面统一的参数,在这里统一处理下,没有的不用""
                 }
             }
         }
     }
 }
  1. 运行小程序模式时,需配置完整的url,在统一的request中处理。根目录下创建 utils/request.js 文件,在这里统一处理请求头、错误情况,文件代码如下
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特殊处理

  1. uni-app兼容APP、H5、小程序时,在H5中标题重复,在page.json中配置页面路径时,在page.json中设置H5的titleNView为false:
{
	"path": "pages/home/index",
	"style": {
		"navigationBarTitleText": "首页",
		"h5": {
			"titleNView": false
		}
	}
}
  1. H5页面底部tabbar遮挡内容,设置元素style : padding-top、padding-bottom
padding-top: var(--window-top);
padding-bottom: var(--window-bottom);
  1. 页面与页面直接传递对象参数:
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>

其它知识累积

  1. 使用Hbuilder X创建的项目没有package.json文件,执行命令 npm init -y 创建,创建了后就可以通过 npm 安装依赖了。安装的插件引入方法:
import package from 'packageName'
const package = require('packageName')
  1. uview-ui在pages.json中配置时npm安装和下载安装2种引入方式不一样:npm安装的方式不需要前面的"@/“,下载安装的方式需要”@/"。
// npm安装方式引入
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
// 下载安装方式引入
 "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
  1. @tab 在小程序不起作用;

  2. navigator需要在同级目录下跳转,不同级的目录需添加 open-type=“switchTab” 属性;

  3. uniapp微信小程序v-show不能和display:flex用在同一个元素上,flex的层级比v-show的display高,导致v-show无效,可以使用v-if

你可能感兴趣的:(uni-app,小程序,公众号,uni-app,前端)