uniapp app端内嵌webview对接支付宝支付
//请求接口需要配置回调地址,回调地址用于跳转回APP指定地址 //app支付 const appRequestPayment = (orderInfo: string) => {
//orderInfo里面返回的是form表单
uni.navigateTo({ url: 'webviewURL?one=' + encodeURIComponent(JSON.stringify(orderInfo)) })
}
<template>
<view class="page">
<web-view :src="state.navUrl"></web-view>
</view>
</template>
<script setup lang="ts">
import {
onLoad,
onReady,
onHide,
onUnload,
onBackPress,
} from '@dcloudio/uni-app';
import {
reactive,
getCurrentInstance,
} from 'vue'
const state : any = reactive({
//需要在src目录下新建html目录以及html页面
navUrl: '../../hybrid/html/xxx.html?data=',
action: '',
isShow: true,
navHeight: 0,
})
onLoad((options : {
one : string,
}) => {
let data = JSON.parse(decodeURIComponent(options.one))
//先把关键布局用特殊符号代替
let htmlSplit = data.replace(/\?/g, "%3F")
let htmlSplit3 = htmlSplit.replace(/\#/g, "%233")
let sult = encodeURIComponent(JSON.stringify(htmlSplit3))
state.navUrl += JSON.parse(decodeURIComponent(sult))
})
onReady(() => {
// #ifdef APP-PLUS
// vue2写法
// const currentWebview = this.$mp.page.$getAppWebview();
// vue3写法
/* 获取屏幕信息 */
let pages = getCurrentPages();
let page : any = pages[pages.length - 1];
setTimeout(() => {
let currentWebview = page.$getAppWebview();
var wv = currentWebview.children()[0];
let url = '此处的地址拦截了跳转H5,并跳转到指定APP的地址'
// wv.overrideUrlLoading({mode: 'allow',match: '.*alipay\.com/.*'},(e)=>{//允许阿里的地址跳转
wv.overrideUrlLoading({
// "reject" 表示满足match属性定义的提交时拦截url跳转并触发callback回调,不满足match属性定义的条件时不拦截url继续加载。
// "allow" 表示满足match属性定义的条件时不拦截url继续加载,不满足match属性定义的条件时拦截url跳转并触发callback回调;
mode: 'reject',
match: `.*${url}\.com/.*`
}, (e) => {
//业务逻辑,可以查询订单状态,然后跳转支付结果页
})
//webview窗口布局
global.$navHeight(res => {
wv.setStyle({
top: 10,
// scalable: true 是否可以双指缩放
})
})
}, 180)
})
onBackPress((e) => {
// 强制不允许返回
return true;
})
</script>
<style scoped lang="scss">
.page {
width: 750rpx;
margin: 0 auto;
}
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<mete http-equiv="contentType" content="textml;charst=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>支付订单</title>
<style>
@keyframes show {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes hide {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
.toast_box {
width: 100%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
justify-content: center;
display: none;
}
.toast_box p {
box-sizing: border-box;
padding: 10px 20px;
max-width: 72%;
width: max-content;
background: #000;
color: #FFF;
font-size: 16px;
text-align: center;
border-radius: 6px;
opacity: 0.8;
}
.zan-dialog-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
background: rgba(0, 0, 0, 0.7);
}
.zan-dialog__container {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background: #f8f8f8;
transition: all 0.4s ease;
z-index: 9999;
border-radius: 20px;
}
.container {
position: relative;
width: 300px;
height: 250px;
border-radius: 20px;
margin: 0 auto;
}
.title {
font-size: 23px;
color: #333;
font-weight: bold;
text-align: center;
padding: 25px 0 0 0;
margin-bottom: 20px;
}
.concent {
font-size: 20px;
color: #333;
font-weight: bold;
text-align: center;
}
.btnFlex {
position: absolute;
bottom: 15px;
width: 100%;
display: flex;
align-items: center;
}
.resetPay {
font-size: 18px;
width: 50%;
height: 50px;
line-height: 50px;
text-align: center;
font-weight: bold;
}
.cancel {
font-size: 18px;
width: 50%;
height: 50px;
line-height: 50px;
text-align: center;
font-weight: bold;
color: #ff2f4e;
}
.hideStyle {
display: none;
}
.showStyle {
display: block;
}
</style>
</head>
<body>
<div style="height:500px"></div>
<div class="toast_box">
<p id="toast"></p>
</div>
<div id='replace'></div>
<div id="zan-dialog-mask" class="hideStyle">
<div class="zan-dialog-mask hideStyle">
<div class="zan-dialog__container">
<div class="container">
<div class="title">提示</div>
<div class="concent">
<div>订单支付未完成,</div>
<div>是否重新支付?</div>
</div>
<div class="btnFlex">
<div class="resetPay" onclick="resetPay()">重新支付</div>
<div class="cancel" onclick="cancel()">取消</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
document.addEventListener('UniAppJSBridgeReady', function() {
let plus=false;
uni.postMessage({
data: {
action: '',
payResult: 0
}
});
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
if(res.plus){
// setTimeout(()=>{
// uni.webView.reLaunch({
// url:'/pages/componentsA/order/paymentResult'
// })
// },500)
}
});
//获取数据进行赋值
getUrlParam()
toast('正在跳转支付页面..', 1200)
//获取元素 其实以下得看自身情况需求来做更改 但大体就是使用 window.location.search.substring(1)截取到凭借的参数 然后使用decodeURIComponent方法进行转译
let replace = document.getElementById('replace')
function getUrlParam() {
// 取得url中?后面的字符
let query = window.location.search.substring(1);
// let pair, pairSplit, id, token,requestUrl,userTerminal;
// 把参数按&拆分成数组3
// let param_arr = query.split("=");
//需要把特殊字符还原,不然webview会报错
let param_arr = query.substring(5);
let htmlSplit = param_arr.replace(/\%3F/g, "?")
let htmlSplitSpace = htmlSplit.replace(/\%20/g, " ")
let htmlSplitSpaceF = htmlSplitSpace.replace(/\%3C/g, "<")
let htmlSplitSpaceFR = htmlSplitSpaceF.replace(/\%3E/g, ">")
let htmlSplitSpaceFf = htmlSplitSpaceFR.replace(/\%22/g, '"')
let htmlSplitSpaceFf3 = htmlSplitSpaceFf.replace(/\%233/g, '#')
// let htmlSplitSpaceFfPay = htmlSplitSpaceFf3.replace(/\%E7%AB%8B%E5%8D%B3%E6%94%AF%E4%BB%98/g, '立即支付')
setTimeout(() => {
let divForm = document.getElementsByTagName('divform')
if (divForm.length) {
document.body.removeChild(divForm[0])
}
const div = document.createElement('divform');
div.innerHTML = htmlSplitSpaceFf3;
document.body.appendChild(div);
document.forms[0].setAttribute('target', '_blank')
document.forms[0].submit();
}, 500)
}
function toast(text, time) {
var toast = document.getElementById('toast');
var toast_box = document.getElementsByClassName('toast_box')[0];
toast.innerHTML = text;
toast_box.style.animation = 'show 1.5s'
toast_box.style.display = 'flex';
setTimeout(() => {
toast_box.style.animation = 'hide 1.5s'
setTimeout(() => {
toast_box.style.display = 'none';
}, 1400)
}, time)
}
});
</script>
</html>
如有疑问,请联系随笔作者,一起进步!!
浙公网安备 33010602011771号