/** * 微信/支付宝支付工具类 * 适配端:微信小程序(全支付方式)、华为快应用(全支付方式)、H5(全支付方式) * 核心:统一封装支付调用逻辑,返回H5支付链接适配web-view组件 */ /** * 微信支付调用封装 * @param {String} outTradeNo 前端生成的唯一订单号 * @param {Number} amount 支付金额(单位:元,保留2位小数) * @param {String} subject 订单标题 * @returns {Promise} 支付结果(含H5支付链接) */ export function invokeWechatPay(outTradeNo, amount, subject) { return new Promise(async (resolve, reject) => { try { // 1. 调用后端接口生成微信支付订单 const orderRes = await uni.request({ url: getApiUrl() + '/api/pay/wechat/createOrder', method: 'POST', data: { out_trade_no: outTradeNo, total_amount: amount, subject: subject, pay_type: 'wechatpay' } }); // 2. 校验后端返回结果 if (orderRes.data.code !== 0) { reject(new Error(orderRes.data.msg || '生成微信支付订单失败')); return; } // 3. 区分运行端处理 const systemInfo = uni.getSystemInfoSync(); const accountInfo = uni.getAccountInfoSync(); const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序 const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用 if (isWechatMini) { // 3.1 微信小程序:优先原生唤起,失败则返回H5链接 if (orderRes.data.data.timeStamp && orderRes.data.data.paySign) { uni.requestPayment({ timeStamp: orderRes.data.data.timeStamp, nonceStr: orderRes.data.data.nonceStr, package: orderRes.data.data.package, signType: 'MD5', paySign: orderRes.data.data.paySign, success: () => { resolve({ code: 0, msg: '微信支付控件唤起成功', data: {} }); }, fail: (err) => { // 原生唤起失败,返回H5链接适配web-view if (orderRes.data.data.payUrl) { resolve({ code: 0, msg: '原生支付失败,跳转H5支付', data: { payUrl: orderRes.data.data.payUrl } }); } else { reject(new Error(`微信支付失败:${err.errMsg || '无H5支付链接'}`)); } } }); } else if (orderRes.data.data.payUrl) { // 无原生支付参数,直接返回H5链接 resolve({ code: 0, msg: '跳转微信支付H5页面', data: { payUrl: orderRes.data.data.payUrl } }); } else { reject(new Error('缺少微信支付参数(原生/H5)')); } } else if (isHuaweiQuickApp) { // 3.2 华为快应用:返回H5支付链接 if (!orderRes.data.data.payUrl) { reject(new Error('未获取到微信支付H5跳转链接')); return; } resolve({ code: 0, msg: '跳转微信支付H5页面', data: { payUrl: orderRes.data.data.payUrl } }); } else { // 3.3 H5端:直接跳转 if (!orderRes.data.data.payUrl) { reject(new Error('未获取到微信支付跳转链接')); return; } window.location.href = orderRes.data.data.payUrl; resolve({ code: 0, msg: '跳转微信支付页面成功', data: {} }); } } catch (err) { reject(new Error(`微信支付异常:${err.message || '网络请求失败'}`)); } }); } /** * 支付宝支付调用封装(全端支持,返回H5链接适配web-view) * @param {String} outTradeNo 前端生成的唯一订单号 * @param {Number} amount 支付金额(单位:元) * @param {String} subject 订单标题 * @returns {Promise} 支付结果(含H5支付链接) */ export function invokeAlipay(outTradeNo, amount, subject) { return new Promise(async (resolve, reject) => { try { // 1. 调用后端接口生成支付宝支付订单 const orderRes = await uni.request({ url: getApiUrl() + '/api/pay/alipay/createOrder', method: 'POST', data: { out_trade_no: outTradeNo, total_amount: amount, subject: subject, pay_type: 'alipay' } }); // 2. 校验后端返回结果 if (orderRes.data.code !== 0) { reject(new Error(orderRes.data.msg || '生成支付宝支付订单失败')); return; } // 3. 区分运行端处理(全端返回H5链接) const accountInfo = uni.getAccountInfoSync(); const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); const isHuaweiQuickApp = uni.getSystemInfoSync().platform === 'quickapp-huawei'; if (!orderRes.data.data.payUrl) { reject(new Error('未获取到支付宝支付H5跳转链接')); return; } if (isWechatMini || isHuaweiQuickApp) { // 3.1 微信小程序/华为快应用:返回H5链接(适配web-view) resolve({ code: 0, msg: '跳转支付宝支付H5页面', data: { payUrl: orderRes.data.data.payUrl } }); } else { // 3.2 H5端:直接跳转 window.location.href = orderRes.data.data.payUrl; resolve({ code: 0, msg: '跳转支付宝支付页面成功', data: {} }); } } catch (err) { reject(new Error(`支付宝支付异常:${err.message || '网络请求失败'}`)); } }); } /** * 统一支付状态校验(和huaweiPay.js的checkPayStatus对齐) * @param {String} outTradeNo 前端生成的订单号 * @returns {Promise} 校验结果(包含订单实际支付状态) */ export function checkPayStatus(outTradeNo) { return new Promise(async (resolve, reject) => { try { // 统一调用后端状态校验接口(适配所有支付类型) const checkRes = await uni.request({ url: getApiUrl() + '/api/pay/checkStatus', // 和huaweiPay.js使用同一接口 method: 'POST', data: { out_trade_no: outTradeNo } }); resolve(checkRes.data); } catch (err) { reject(new Error(`校验支付状态失败:${err.message || '网络请求失败'}`)); } }); } /** * 获取API基础URL */ function getApiUrl() { // 尝试获取配置的API地址 try { // #ifdef H5 const config = require('@/common/js/config.js').default; return config.baseUrl || ''; // #endif // #ifndef H5 const config = require('@/common/js/config.js').default; return config.baseUrl || ''; // #endif } catch (e) { console.warn('获取API配置失败,使用空字符串'); return ''; } }