微信支付
微信支付分为: ① 微信内部支付 ② 外部应用吊起微信支付
场景
① 微信扫描支付
web网页提供了一个订单确认的二维码,用户用手机微信扫码,微信浏览器展示订单确认页,用户点击确认页中的去支付,直接在微信浏览器中调取支付接口,进行支付。
<template>
<div class="container">
<p>缴费信息</p>
<ul class="order">
<li>订单号:{{ order.orderId }}</li>
<li>姓名:{{ order.cstName }}</li>
<li>应缴金额:{{ order.tranAmt }}(元)</li>
</ul>
<section>
<button @click="pay">去缴费</button>
</section>
</div>
</template>
<script>
const APPID = 'wx536e555555555555'
export default {
data () {
return {
order: {
orderId: "", // 订单号
cstName: "", // 姓名
tranAmt: "", // 缴费金额
},
openid: "",
};
},
async created () {
/* 微信浏览器支付 */
if (this.isWeChat()) {
// const wxCode = this.getQueryString('code')
const wxCode = this.getQs('code')
if (!wxCode) {
/*
appid: 公众号唯一标志
redirect_uri: 授权后重定向的回调链接地址, 请使用urlencode对链接处理
response_type: 返回类型, 请填写:code
scope:应用授权作用域,
① snsapi_base: 不弹出授权页,直接跳转,只能获取用户的openid;
② snsapi_userinfo: 弹出授权页,可通过openid获取用户的昵称、性别、所在地,并且即使在未关注的情况下,可以获取用户信息
state(state的值非必输): 重定向后会带上state参数,开发者可以填写a-zA-Z0-9
#wechat_redirect: 必须要带上这个hash
*/
if (process.env.VUE_APP_ENV === "production") {
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx536e555555555555&redirect_uri=https://www.yiyuanlive.com/mall/index.html&response_type=code&scope=snsapi_base&state=#wechat_redirect";
} else {
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx536e555555555559&redirect_uri=http://www.yiyuanlive.com/mall/index.html&response_type=code&scope=snsapi_base&state=#wechat_redirect"
}
} else {
/* 微信授权获取code成功后,重定向到该页面,再次来到beforeCreate生命周期,可以通过location的search来获取code
获取到code值后,就可以向后台发送接口来请求用户的微信号 openid
*/
const response = await this.$http.post('getOpenid', { wxCode: wxCode })
this.openid = response.data.openid
/* 以下是业务逻辑: 获取该openid下的订单信息 */
this.order = (await this.$http.post('getOrderInfo', { openid: this.openid })).data.order
}
} else {
/* 非微信浏览器支付:H5、支付宝 */
}
},
methods: {
/* 判断当前浏览器是不是微信浏览器,非微信浏览器(比如safari或者支付宝)不能直接唤起微信支付 */
isWeChat () {
const userAgent = navigator.userAgent.toLowerCase()
if (userAgent.match(/MicroMessenger/i) === 'micromessenger') {
return true
} else {
return false
}
},
async pay () {
const res = await this.$http.post('pay', { ...this.order, openid: this.openid })
const wxpay = res.data.payInfo
const prepay_data = {
appId: APPID, //公众号名称,由商户传入 ok
timeStamp: wxpay.timeStamp, //时间戳,自1970年以来的秒数 ok
nonceStr: wxpay.nonceStr, //随机串
package: wxpay.package,
signType: wxpay.signType, //微信签名方式
paySign: wxpay.paySign //微信签名
}
window.sessionStorage.set('prepay_data', prepay_data)
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 () {
const _vm = this
const prepay_data = window.sessionStorage.getItem('prepay_data')
WeixinJSBridge.invoke(
"getBrandWCPayRequest",
JSON.parse(prepay_data),
function (res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// this.$router.push({ path: '/order' }) // 这个是不会生效的,this的指向出现问题
// _vm.$router.push({ path: '/order' }) // 也可以使用 window.location.href
window.location.href = 'http://www.yiyuanlive.com/mall/index.html/#/order'
} else if (res.err_msg == "get_brand_wcpay_request:cancel") {
// 支付取消
window.location.href = 'http://www.yiyuanlive.com/mall/index.html/#/order'
} else if (msg == "get_brand_wcpay_request:fail") {
// 支付失败
WeixinJSBridge.call('closeWindow');
}
}
)
},
getQs (name) {
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
const r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
},
getQueryString (name) {
const href = window.location.href
let search = window.location.search
let hash = window.location.hash
/*
https://www.baidu.com/?code=xxxx/#/dsash
search: "?code=xxxx&a=b/"
hash: "#/dsash"
vue中的路由
https://www.baidu.com/#/dsash?code=xxxx
search: ""
hash: "#/dsash?code=xxxx"
*/
const results = {}
if (href.includes('?')) {
if (!search) {
search = hash.split('?')[1]
hash = hash.split('?')[0]
}
search = search.replace(///g, '').replace('?', '')
hash = hash.replace('#/', '')
search.split('&').forEach(d => {
results[d.split('=')[0]] = d.split('=')[1]
});
results.hash = hash
return decodeURI(results[name])
} else {
return false
}
}
}
};
</script>
② H5吊起微信支付
H5页面点击微信支付,直接吊起微信app,进行支付