Files
2026-08-18 09:22:32 +08:00

80 lines
2.7 KiB
JavaScript

// xuchao: 支付层 —— 支付逻辑全部隔离在这里
// 一期为模拟支付(开发模式),后端微信预下单接口就绪后只改本文件:
// - devMode=true 模拟支付成功(订单在测试环境真实生成为"待支付"状态)
// - devMode=false 调后端微信预下单接口,再用微信内置桥接唤起微信支付
import config from '@/common/config.js'
// xuchao: 判断是否在微信浏览器内(正式支付只能在微信里唤起)
const isWechatBrowser = () => {
// #ifdef H5
return /micromessenger/i.test(navigator.userAgent)
// #endif
}
// xuchao: 发起支付
// vm: 页面的 this(用于调接口)
// orderId: 订单号(createTicketsOrder 返回值)
// onSuccess / onFail: 支付结果回调
const pay = (vm, { orderId, onSuccess, onFail }) => {
if (config.devMode) {
// 开发模式:模拟支付成功
uni.showLoading({ title: '支付中...' })
setTimeout(() => {
uni.hideLoading()
onSuccess && onSuccess({ mock: true })
}, 800)
return
}
// 正式流程:微信 JSAPI 支付
const openId = uni.getStorageSync('openId')
if (!openId) {
uni.showToast({ icon: 'none', title: '缺少登录身份,请重新进入' })
onFail && onFail({ errMsg: 'no openId' })
return
}
console.log('[pay] prepay orderId=' + orderId + ' openId=' + openId)
vm.$u.api.prepayWx({ orderId, openId, type: 1 }).then(res => {
if (!res) return
const p = res.data || {}
console.log('[pay] prepay resp', p)
// 后端返回微信支付所需参数后,用此桥接唤起支付(微信浏览器内置,无需额外引入)
// appId 优先取后端返回值,为空时用 config.wxAppid 兜底
const invokePay = () => {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId: p.appId || config.wxAppid,
timeStamp: String(p.timeStamp),
nonceStr: p.nonceStr || p.nonce,
package: p.packageValue || p.pack || p['package'],
signType: p.signType || 'RSA',
paySign: p.paySign
}, bridgeRes => {
if (bridgeRes.err_msg === 'get_brand_wcpay_request:ok') {
onSuccess && onSuccess(bridgeRes)
} else {
onFail && onFail(bridgeRes)
}
})
}
// 非微信环境 prepay 已拿到参数,唤起桥接这一步才提示需在微信中完成
if (!isWechatBrowser()) {
uni.showToast({ icon: 'none', title: '请在微信中打开完成支付' })
onFail && onFail({ errMsg: 'not wechat browser' })
return
}
// 桥接可能未就绪(冷启动进页立刻支付),挂 WeixinJSBridgeReady 事件等它就绪
if (typeof WeixinJSBridge === 'undefined') {
document.addEventListener('WeixinJSBridgeReady', invokePay, false)
} else {
invokePay()
}
}).catch(() => {
onFail && onFail({ errMsg: 'prepay error' })
})
}
export default {
pay,
isWechatBrowser
}