情景
H5网站webview的形式嵌入小程序,接微信支付。H5和小程序都是用uniapp开发的,以uniapp为例,使用原生开发的自动切换。
踩坑 - JSAPI支付
最开始想到的是接微信JSAPI支付,跳转支付页面的时候,加上公众号授权,获取code,换取openId,调起JSAPI支付。
成功 - 跳转到小程序支付
1.小程序承载H5的页面
- 通过login获取用户code,换取openId
<template>
<view class="content">
<web-view :src="completePath"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
pagePath:'/pages/index/index',//默认的页面地址
webPath:'https://xxxxxx.com/h5/#' //授权的域名地址
}
},
onLoad(options) {
if(options?.pagePath){
this.pagePath = options.pagePath
}
this.loginGetCode()
},
methods: {
loginGetCode(){
uni.login({
provider: 'weixin',
success:(loginRes)=>{
let code = loginRes.code
this.pagePath = `${this.pagePath}?code=${code}`
}
})
}
},
computed:{
completePath(){
return this.webPath + this.pagePath
}
}
}
2.H5首页
- 通过wind.location属性获取小程序传过来的code
onShow() {
if(uni.getStorageSync('isweixin')){ //在APP.vue文件就判断了是不是微信浏览器环境
let code = this.getUrlParam("code")
uni.setStorageSync('user_wx_code',code)
}
},
methods: {
/**
* @param {Object} name
* 获取小程序传入的参数:用户code
*/
getUrlParam(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var rrr = window.location.href.split('?')[1]; //因为用的hash模式,没办法用search属性,
// var rrr = window.location.search; //history模式(路由没有#),可以用search属性
var r = rrr.match(reg);
if (r != null) return unescape(r[2]);
return null;
},
}
3.H5收银台页面
- 下单后拿code以及下单参数,请求后端Api,拿到支付需要的参数,跳转到小程序的支付页。(具体和后端商量看怎么配合)
注意参数package和paySign!!!
weixinPay(){
//微信环境,微信小程序支付
let params = {
xxx:xxxx, //其他下单参数
code:this.code
}
api.orderPay(params).then((orderRes)=>{
let {data} = orderRes
this.weixinMiniProgramPay(data)
})
},
/**
* 跳转到微信小程序支付
*/
weixinMiniProgramPay(payDataStr){
let payParams = `?nonceStr=${payDataStr.nonceStr}&package=${encodeURIComponent(payDataStr.package)}&paySign=${encodeURIComponent(payDataStr.paySign)}&signType=${payDataStr.signType}&timeStamp=${payDataStr.timeStamp}`
jWeixin.miniProgram.navigateTo({
appId:'wx126ae2069f831xxx',
url:`/pages/pay/index${payParams}`,
envVersion:'develop',
success(res) {
console.log(res,'跳转成功')
},
fail(res){
console.log(res,'跳转失败')
}
})
},
4.小程序支付页面
onLoad(options) {
this.toMiniPay(options)
},
methods:{
toMiniPay(data){
uni.requestPayment({
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: decodeURIComponent(data.package),
signType: data.signType,
paySign: decodeURIComponent(data.paySign),
success:(res)=>{
let pagePath="/pages/order/index" //H5指定的页面
uni.navigateTo({
url:`/pages/index/index?pagePath=${pagePath}`
})
//支付成功,回去嵌入h5的页面,url指向H5支付成功对应的页面
},
fail: (res) => {
//支付失败,回去嵌入h5的页面,url指向H5支付失败对应的页面
console.log('fail:' + JSON.stringify(res));
}
})
}
}
6.H5引入微信JS SDK
- 在html文件中引入JS文件,这里需要新建模板。参考uniapp官网做法:uniapp.dcloud.io/collocation…
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
</title>
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<!-- 微信JS SDK -->
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js"></script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong></strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
7.H5跳小程序传参数踩坑记录
- package和paySign参数
package: "prepay_id=wx09160546182232dea6c853cfxxxxxxxxxx"
paySign: "NYBvV2dk//xxxxxxxxxxxxxxxxx+m80d35A=="
//都有特殊符号'=',需要encodeURIComponent编码一下,不编码在小程序支付页面拿到的参数就是:
package: "prepay_id"
paySign: "NYBvV2dk//xxxxxxxxxxxxxxxxx+m80d35A"