WeChat payment (about h5 payment and JSAPI payment)
Requirement: If you use the built-in browser of WeChat, you can directly call the payment (JSAPI payment), if you use the non-WeChat browser (qq browser, safari...) to pull the WeChat client and then pay.
Set the order.vue page:
goToPay() {
// 点击确认付款
let {
tradeno,amount } = this.$route.query;
if(this.$utils.isWeixin()) {
// 如果是微信自带浏览器中,获取openid,由后端重定向到/person/wallet/pay页面
let url = encodeURIComponent(`${
window.location.origin}/wxopenid/?tradeno=${
tradeno}&amount=${
amount}`)
this.$http.post(this.$api.APPID03).then((res) => {
// 从后端获取appid
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${
res}&redirect_uri=${
url
}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`;
});
} else {
// 再浏览器中自我跳转
this.$router.push({
path: '/person/wallet/pay',
query: {
tradeno,
amount
}
})
}
},
pay.view:
<template>
<div class="pay">
<div class="item-wrap">
<img src="@/assets/image/wxpay.png" alt="" />
<div>微信支付: ¥ {
{
$route.query.amount }}元</div>
<div>收保费</div>
</div>
<div class="item-btn">
<van-button
color="#ff721f"
v-if="isWeixin"
type="primary"
@click="goToPay"
>确认支付</van-button
>
<van-button color="#ff721f" v-else type="primary" @click="goToPage"
>确认支付</van-button
>
</div>
</div>
</template>
If it is an external browser, the backend will generate h5_url by calling the H5 order interface, and directly window.location.href in h5, which means that the following click to confirm payment in a non-WeChat browser calls the goToPage method
mounted() {
this.initData();
},
async initData() {
let {
amount, tradeno, openid } = this.$route.query;
this.amount = amount;
let obj = {
tradeno,
paytype: this.isWeixin ? 1 : 0,
};
if (openid) {
obj.openid = openid;
}
let res = await this.$http.post(this.$api.WXPAYPARAM, obj);
this.url = res.url;
this.timestamp = res.timeStamp || res.timestamp;
this.nonceStr = res.nonceStr;
this.package1 = res.package;
this.signType = res.signType;
this.paySign = res.paySign;
this.appId = res.appId;
},
goToPage() {
window.location.href = this.url;
},
Pay in WeChat browser, use JSAPI to pay :
goToPay() {
// 点击确认支付调用goToPay
this.bridgePay();
},
bridgePay() {
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();
}
},
onBridgeReady() {
let {
timestamp, nonceStr, package1, signType, paySign, appId, notifyurl } =
this;
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: appId, //公众号ID,由商户传入
timeStamp: timestamp, //时间戳,自1970年以来的秒数
nonceStr, //随机串
package: package1,
signType, //微信签名方式:
paySign, //微信签名
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
}
);
},
Through the above brief introduction, draw a simple picture
Paste the complete code of pay.vue
<template>
<div class="pay">
<div class="item-wrap">
<img src="@/assets/image/wxpay.png" alt="" />
<div>微信支付: ¥ {
{
$route.query.amount }}元</div>
<div>收保费</div>
</div>
<div class="item-btn">
<van-button
color="#ff721f"
v-if="isWeixin"
type="primary"
@click="goToPay"
>确认支付</van-button
>
<van-button color="#ff721f" v-else type="primary" @click="goToPage"
>确认支付</van-button
>
</div>
</div>
</template>
<script>
import wx from "weixin-js-sdk";
import {
Dialog } from "vant";
export default {
data() {
return {
timestamp: "",
nonceStr: "",
package1: "",
signType: "",
paySign: "",
appId: "",
amount: "",
orderid: "",
pcode: "",
username: "",
deeplink: "",
isWeixin: false,
notifyurl: "", // 支付成功跳转
};
},
mounted() {
if (this.$utils.isWeixin()) {
this.isWeixin = true;
} else {
this.isWeixin = false;
}
this.$nextTick(() => {
this.initData();
});
},
methods: {
async initData() {
let {
amount, tradeno, openid } = this.$route.query;
this.amount = amount;
let obj = {
tradeno,
paytype: this.isWeixin ? 1 : 0,
};
if (openid) {
obj.openid = openid;
}
let res = await this.$http.post(this.$api.WXPAYPARAM, obj);
this.url = res.url;
this.timestamp = res.timeStamp || res.timestamp;
this.nonceStr = res.nonceStr;
this.package1 = res.package;
this.signType = res.signType;
this.paySign = res.paySign;
this.appId = res.appId;
this.notifyurl = notifyurl;
},
goToPay() {
this.bridgePay();
},
goToPage() {
window.location.href = this.url;
},
bridgePay() {
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();
}
},
onBridgeReady() {
let {
timestamp, nonceStr, package1, signType, paySign, appId, notifyurl } =
this;
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
{
appId: appId, //公众号ID,由商户传入
timeStamp: timestamp, //时间戳,自1970年以来的秒数
nonceStr, //随机串
package: package1,
signType, //微信签名方式:
paySign, //微信签名
},
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
}
);
},
},
};
</script>
<style lang="scss" scoped>
.pay {
padding-top: 200px;
.item-wrap {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
& div {
margin-top: 20px;
font-size: 28px;
}
}
.item-btn {
display: flex;
align-items: center;
justify-content: center;
margin-top: 120px;
}
}