// utils/wxpay.js const API_BASE_URL = 'https://yourdomain.com/api'; class WxPay { constructor() { this.isWeixin = this.checkWeixin(); this.openid = uni.getStorageSync('wx_openid') || ''; } // 检查是否在微信环境 checkWeixin() { const ua = navigator.userAgent.toLowerCase(); return ua.indexOf('micromessenger') !== -1; } // 获取 URL 参数 getQueryParam(name) { const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); const r = window.location.search.substr(1).match(reg); if (r != null) return decodeURIComponent(r[2]); return null; } // 微信授权获取 code async wxAuth() { if (!this.isWeixin) { uni.showToast({ title: '请在微信中打开', icon: 'none' }); return null; } const code = this.getQueryParam('code'); if (!code) { // 跳转微信授权 const currentUrl = encodeURIComponent(window.location.href.split('#')[0]); const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appId}&redirect_uri=${currentUrl}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`; window.location.href = authUrl; return null; } return code; } // 通过 code 获取 openid async getOpenId(code) { try { const response = await uni.request({ url: `${API_BASE_URL}/wx/auth`, method: 'GET', data: { code } }); if (response[1].data.code === 0) { const { openid } = response[1].data.data; this.openid = openid; uni.setStorageSync('wx_openid', openid); return openid; } return null; } catch (error) { console.error('获取openid失败:', error); return null; } } // 初始化微信 JS-SDK async initWxJsSDK() { if (!this.isWeixin) return false; try { // 获取当前页面 URL(去掉 # 后面的部分) const currentUrl = window.location.href.split('#')[0]; const response = await uni.request({ url: `${API_BASE_URL}/jssdk/config`, method: 'GET', data: { url: encodeURIComponent(currentUrl) } }); if (response[1].data.code === 0) { const config = response[1].data.data; // 引入微信 JS-SDK await this.loadWxJsSDK(); // 配置微信 JS-SDK wx.config({ debug: false, // 开启调试模式 appId: config.appId, timestamp: config.timestamp, nonceStr: config.nonceStr, signature: config.signature, jsApiList: [ 'chooseWXPay', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'scanQRCode' ] }); return new Promise((resolve) => { wx.ready(() => { console.log('微信 JS-SDK 初始化成功'); resolve(true); }); wx.error((err) => { console.error('微信 JS-SDK 初始化失败:', err); uni.showToast({ title: '微信初始化失败', icon: 'none' }); resolve(false); }); }); } return false; } catch (error) { console.error('初始化JS-SDK失败:', error); return false; } } // 动态加载微信 JS-SDK loadWxJsSDK() { return new Promise((resolve, reject) => { if (typeof wx !== 'undefined') { resolve(); return; } const script = document.createElement('script'); script.src = 'https://res.wx.qq.com/open/js/jweixin-1.6.0.js'; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } // 创建支付订单 async createPayment(orderData) { try { // 确保有 openid if (!this.openid) { const code = await this.wxAuth(); if (code) { await this.getOpenId(code); } } if (!this.openid) { throw new Error('获取用户信息失败'); } const response = await uni.request({ url: `${API_BASE_URL}/wxpay/unifiedorder`, method: 'POST', header: { 'Content-Type': 'application/json' }, data: { openid: this.openid, body: orderData.body || '账户充值', total_fee: orderData.amount, out_trade_no: orderData.orderNo, attach: orderData.attach || '' } }); if (response[1].data.code === 0) { return response[1].data.data; } else { throw new Error(response[1].data.msg || '创建订单失败'); } } catch (error) { console.error('创建支付订单失败:', error); throw error; } } // 发起微信支付 async launchPayment(payData) { return new Promise((resolve, reject) => { wx.chooseWXPay({ timestamp: payData.timeStamp, nonceStr: payData.nonceStr, package: payData.package, signType: payData.signType, paySign: payData.paySign, success: (res) => { if (res.errMsg === 'chooseWXPay:ok') { resolve({ success: true, message: '支付成功' }); } else { reject(new Error('支付失败: ' + res.errMsg)); } }, fail: (err) => { reject(new Error('支付失败: ' + JSON.stringify(err))); }, cancel: () => { reject(new Error('用户取消支付')); } }); }); } // 完整的支付流程 async pay(amount, orderNo, attach = '') { try { // 1. 检查环境 if (!this.isWeixin) { uni.showToast({ title: '请在微信中打开', icon: 'none' }); return { success: false, message: '非微信环境' }; } // 2. 初始化 JS-SDK const initSuccess = await this.initWxJsSDK(); if (!initSuccess) { return { success: false, message: '微信初始化失败' }; } // 3. 创建支付订单 const payData = await this.createPayment({ amount: amount, orderNo: orderNo, attach: attach }); // 4. 发起支付 const result = await this.launchPayment(payData); // 5. 验证支付结果 if (result.success) { // 支付成功,可以查询订单确认 await this.verifyPayment(orderNo); return { success: true, message: '支付成功' }; } return result; } catch (error) { console.error('支付流程错误:', error); return { success: false, message: error.message || '支付失败' }; } } // 验证支付结果 async verifyPayment(orderNo) { try { const response = await uni.request({ url: `${API_BASE_URL}/wxpay/query`, method: 'GET', data: { out_trade_no: orderNo } }); if (response[1].data.code === 0) { const orderData = response[1].data.data; if (orderData.trade_state === 'SUCCESS') { return true; } } return false; } catch (error) { console.error('验证支付结果失败:', error); return false; } } } export default new WxPay();