payment: 统一支付逻辑,移除冗余文件。移除 payUtils.js、huaweiPay.js 、payCore.js冗余依赖,重构 payment.vue 支付逻辑:统一调用/api/pay/pay,新增华为支付支持。
This commit is contained in:
@@ -1,152 +0,0 @@
|
|||||||
/**
|
|
||||||
* 华为支付核心工具类
|
|
||||||
* 适配端:华为快应用(原生支付)、微信小程序(H5支付)、H5端(H5支付)
|
|
||||||
* 核心:统一封装支付调用逻辑,返回H5支付链接适配web-view组件
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 华为支付调用封装
|
|
||||||
* @param {String} outTradeNo 前端生成的唯一订单号
|
|
||||||
* @param {Number} amount 支付金额(单位:元,保留2位小数)
|
|
||||||
* @param {String} subject 订单标题
|
|
||||||
* @param {String} payType 支付类型(默认huaweipay)
|
|
||||||
* @returns {Promise} 支付结果(含H5支付链接)
|
|
||||||
*/
|
|
||||||
export function invokeHuaweiPay(outTradeNo, amount, subject, payType = 'huaweipay') {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
try {
|
|
||||||
// 1. 显示加载中提示
|
|
||||||
uni.showLoading({
|
|
||||||
title: '发起支付...'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. 调用后端生成订单
|
|
||||||
const orderRes = await uni.request({
|
|
||||||
url: getApiUrl() + '/api/huawei/pay/createOrder',
|
|
||||||
method: 'POST',
|
|
||||||
data: {
|
|
||||||
out_trade_no: outTradeNo,
|
|
||||||
total_amount: amount,
|
|
||||||
subject: subject,
|
|
||||||
pay_type: payType
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 3. 校验后端返回结果
|
|
||||||
if (orderRes.data.code !== 0) {
|
|
||||||
uni.hideLoading();
|
|
||||||
reject(new Error(orderRes.data.msg || '生成支付订单失败'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 区分运行端处理
|
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
|
||||||
const accountInfo = uni.getAccountInfoSync();
|
|
||||||
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
|
|
||||||
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
|
|
||||||
const isH5 = systemInfo.platform === 'web' || !accountInfo?.miniProgram; // H5端
|
|
||||||
|
|
||||||
if (isHuaweiQuickApp) {
|
|
||||||
// 4.1 华为快应用:原生唤起支付控件
|
|
||||||
// 注意:这里需要根据实际的华为快应用支付SDK调用
|
|
||||||
try {
|
|
||||||
// 示例代码,实际需要根据华为快应用文档调整
|
|
||||||
const huaweiPay = require('@service.pay.huawei');
|
|
||||||
huaweiPay.pay({
|
|
||||||
orderInfo: orderRes.data.data.orderInfo,
|
|
||||||
success: (payRes) => {
|
|
||||||
uni.hideLoading();
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '华为支付控件唤起成功',
|
|
||||||
data: payRes
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
uni.hideLoading();
|
|
||||||
const errMsg = err.message || err.code || '未知错误';
|
|
||||||
reject(new Error(`支付失败:${errMsg}`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (sdkError) {
|
|
||||||
// SDK不存在,降级到H5支付
|
|
||||||
if (orderRes.data.data.payUrl) {
|
|
||||||
uni.hideLoading();
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '跳转华为支付H5页面',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
uni.hideLoading();
|
|
||||||
reject(new Error('华为支付SDK不可用且无H5支付链接'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (isWechatMini || isH5) {
|
|
||||||
// 4.2 微信小程序/H5端:返回H5支付链接(适配web-view)
|
|
||||||
if (!orderRes.data.data.payUrl) {
|
|
||||||
uni.hideLoading();
|
|
||||||
reject(new Error('未获取到华为支付H5跳转链接'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uni.hideLoading();
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '跳转华为支付H5页面',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 4.3 其他端:提示不支持
|
|
||||||
uni.hideLoading();
|
|
||||||
reject(new Error('当前环境暂不支持华为支付'));
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
uni.hideLoading();
|
|
||||||
reject(new Error(`支付异常:${err.message || '网络请求失败'}`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验支付最终状态(统一适配所有支付方式)
|
|
||||||
* @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',
|
|
||||||
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 '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* 全支付方式统一调用入口
|
|
||||||
* 整合微信/支付宝/华为支付的所有方法,简化页面引入逻辑
|
|
||||||
* 依赖:payUtils.js、huaweiPay.js(无需修改原文件)
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 1. 引入原工具类的所有方法(修正方法名)
|
|
||||||
import {
|
|
||||||
invokeWechatPay, // 微信支付(完整方法名)
|
|
||||||
invokeAlipay, // 支付宝支付(完整方法名)
|
|
||||||
checkPayStatus as payUtilsCheck // 微信/支付宝支付状态校验(完整方法名)
|
|
||||||
} from './payUtils.js';
|
|
||||||
|
|
||||||
import {
|
|
||||||
invokeHuaweiPay, // 华为支付(完整方法名)
|
|
||||||
checkPayStatus as huaweiCheck // 华为支付状态校验(完整方法名)
|
|
||||||
} from './huaweiPay.js';
|
|
||||||
|
|
||||||
// 2. 导出所有支付调用方法(修正方法名,和原方法一致)
|
|
||||||
export {
|
|
||||||
invokeWechatPay,
|
|
||||||
invokeAlipay,
|
|
||||||
invokeHuaweiPay
|
|
||||||
};
|
|
||||||
|
|
||||||
// 3. 导出统一的支付状态校验方法(两个工具类逻辑完全一致,任选其一即可)
|
|
||||||
export const checkPayStatus = payUtilsCheck;
|
|
||||||
// 若需使用华为支付工具类的校验逻辑,可替换为:export const checkPayStatus = huaweiCheck;
|
|
||||||
@@ -1,354 +0,0 @@
|
|||||||
/**
|
|
||||||
* 微信/支付宝支付工具类
|
|
||||||
* 适配端:微信小程序(全支付方式)、华为快应用(全支付方式)、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 || '网络请求失败'}`));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 华为支付调用封装(适配全端:微信小程序/H5/华为快应用)
|
|
||||||
* @param {String} outTradeNo 前端生成的唯一订单号
|
|
||||||
* @param {Number} amount 支付金额(单位:元,保留2位小数)
|
|
||||||
* @param {String} subject 订单标题
|
|
||||||
* @returns {Promise} 支付结果(含H5支付链接/原生支付状态)
|
|
||||||
*/
|
|
||||||
export function invokeHuaweiPay(outTradeNo, amount, subject) {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
try {
|
|
||||||
// ===== 1. 模拟后端返回合法凭证(跳过真实接口调用)=====
|
|
||||||
// 注释掉真实请求后端的代码,直接模拟返回正确格式的凭证
|
|
||||||
// const orderRes = await uni.request({
|
|
||||||
// url: getApiUrl() + '/api/pay/huawei/createOrder',
|
|
||||||
// method: 'POST',
|
|
||||||
// data: {
|
|
||||||
// out_trade_no: outTradeNo,
|
|
||||||
// total_amount: amount,
|
|
||||||
// subject: subject,
|
|
||||||
// pay_type: 'huaweipay'
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// 模拟后端返回的合法数据(重点:code=0,有orderInfo和payUrl)
|
|
||||||
const orderRes = {
|
|
||||||
data: {
|
|
||||||
code: 0,
|
|
||||||
msg: '生成华为支付订单成功',
|
|
||||||
data: {
|
|
||||||
orderInfo: 'test_order_info_123456', // 模拟华为原生SDK需要的参数
|
|
||||||
payUrl: 'https://pay.huawei.com/cashier/test' // 模拟H5支付链接
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// =====================================================
|
|
||||||
|
|
||||||
// ===== 2. 加日志:打印模拟的凭证,看是否拿到数据 =====
|
|
||||||
console.log('【华为支付测试】模拟后端返回的凭证:', orderRes.data);
|
|
||||||
|
|
||||||
// 3. 校验后端返回结果
|
|
||||||
if (orderRes.data.code !== 0) {
|
|
||||||
reject(new Error(orderRes.data.msg || '生成华为支付订单失败'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 区分运行端处理
|
|
||||||
const accountInfo = uni.getAccountInfoSync();
|
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
|
||||||
const isWechatMini = accountInfo?.miniProgram?.appId?.includes('wx'); // 微信小程序
|
|
||||||
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei'; // 华为快应用
|
|
||||||
|
|
||||||
if (isHuaweiQuickApp) {
|
|
||||||
// ===== 3. 加日志:标记进入华为快应用逻辑 =====
|
|
||||||
console.log('【华为支付测试】进入华为快应用逻辑,尝试调起原生SDK');
|
|
||||||
|
|
||||||
// 3.1 华为快应用:优先原生SDK调起,失败则降级H5
|
|
||||||
if (orderRes.data.data.orderInfo) { // 后端返回华为支付SDK所需的orderInfo
|
|
||||||
try {
|
|
||||||
const huaweiPay = require('@service.pay.huawei'); // 华为快应用支付SDK
|
|
||||||
console.log('【华为支付测试】开始调用华为原生支付SDK');
|
|
||||||
huaweiPay.pay({
|
|
||||||
orderInfo: orderRes.data.data.orderInfo, // 后端返回的原生支付参数
|
|
||||||
success: (res) => {
|
|
||||||
console.log('【华为支付测试】原生SDK调起成功', res);
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '华为支付原生控件唤起成功',
|
|
||||||
data: {}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.log('【华为支付测试】原生SDK调起失败,降级到H5', err);
|
|
||||||
// 原生唤起失败,降级返回H5链接
|
|
||||||
if (orderRes.data.data.payUrl) {
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '原生支付失败,跳转H5支付',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
reject(new Error(`华为支付失败:${err.message || '无H5支付链接'}`));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (sdkErr) {
|
|
||||||
console.log('【华为支付测试】SDK加载失败,降级到H5', sdkErr);
|
|
||||||
// SDK加载失败,直接返回H5链接
|
|
||||||
if (orderRes.data.data.payUrl) {
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: 'SDK加载失败,跳转H5支付',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
reject(new Error('华为支付SDK异常且无H5链接'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (orderRes.data.data.payUrl) {
|
|
||||||
console.log('【华为支付测试】无原生参数,直接返回H5链接');
|
|
||||||
// 无原生参数,直接返回H5链接
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '跳转华为支付H5页面',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
reject(new Error('缺少华为支付参数(原生/H5)'));
|
|
||||||
}
|
|
||||||
} else if (isWechatMini) {
|
|
||||||
// ===== 4. 加日志:标记进入微信小程序逻辑 =====
|
|
||||||
console.log('【华为支付测试】进入微信小程序逻辑,返回H5链接');
|
|
||||||
|
|
||||||
// 3.2 微信小程序:返回H5链接(适配web-view)
|
|
||||||
if (!orderRes.data.data.payUrl) {
|
|
||||||
reject(new Error('未获取到华为支付H5跳转链接'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve({
|
|
||||||
code: 0,
|
|
||||||
msg: '跳转华为支付H5页面',
|
|
||||||
data: { payUrl: orderRes.data.data.payUrl }
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// ===== 5. 加日志:标记进入H5端逻辑 =====
|
|
||||||
console.log('【华为支付测试】进入H5端逻辑,直接跳转');
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
console.error('【华为支付测试】整体异常:', 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 '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -56,9 +56,6 @@ import {
|
|||||||
} from 'common/js/wx-jssdk.js';
|
} from 'common/js/wx-jssdk.js';
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// 引入统一支付工具类(真实调用)
|
|
||||||
import { invokeWechatPay, invokeAlipay, invokeHuaweiPay } from '../../common/js/payCore.js';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'payment',
|
name: 'payment',
|
||||||
components: {
|
components: {
|
||||||
@@ -119,6 +116,7 @@ export default {
|
|||||||
//重置是否已完成,没有完成不能调用api/pay/pay
|
//重置是否已完成,没有完成不能调用api/pay/pay
|
||||||
resetPayComplete: true,
|
resetPayComplete: true,
|
||||||
repeatFlag: false,
|
repeatFlag: false,
|
||||||
|
flag: false // 保留文件1的flag变量,用于支付失败处理
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created(e) {
|
created(e) {
|
||||||
@@ -268,92 +266,208 @@ export default {
|
|||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
pay() {
|
pay() {
|
||||||
var payType = this.payTypeList[this.payIndex];
|
var payType = this.payTypeList[this.payIndex];
|
||||||
|
// 保留文件2的线下支付逻辑
|
||||||
if (!payType || payType.type === 'offlinepay') {
|
if (!payType || payType.type === 'offlinepay') {
|
||||||
// 线下支付仍使用原有逻辑
|
|
||||||
this.payOffline();
|
this.payOffline();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用统一支付工具类进行真实支付调用
|
// 保留文件2的流程控制
|
||||||
this.invokeUnifiedPay(payType.type);
|
if (!this.resetPayComplete) {
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统一支付调用方法(恢复真实后端调用)
|
|
||||||
*/
|
|
||||||
async invokeUnifiedPay(payType) {
|
|
||||||
try {
|
|
||||||
let payResult;
|
|
||||||
const amount = this.payMoney;
|
|
||||||
const outTradeNo = this.payInfo.out_trade_no;
|
|
||||||
const subject = '订单支付';
|
|
||||||
|
|
||||||
// 恢复真实支付方法调用(对接后端)
|
|
||||||
switch (payType) {
|
|
||||||
case 'wechatpay':
|
|
||||||
payResult = await invokeWechatPay(outTradeNo, amount, subject);
|
|
||||||
break;
|
|
||||||
case 'alipay':
|
|
||||||
payResult = await invokeAlipay(outTradeNo, amount, subject);
|
|
||||||
break;
|
|
||||||
case 'huaweipay':
|
|
||||||
payResult = await invokeHuaweiPay(outTradeNo, amount, subject);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error('不支持的支付方式');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 验证支付结果
|
|
||||||
if (!payResult) {
|
|
||||||
throw new Error('支付结果为空');
|
|
||||||
}
|
|
||||||
if (typeof payResult.code === 'undefined') {
|
|
||||||
throw new Error('缺少code属性');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 真实调起逻辑
|
|
||||||
if (payResult.code === 0 && payResult.data?.payUrl) {
|
|
||||||
// 关闭支付中弹窗
|
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
this.$util.showToast({
|
||||||
// H5端直接跳转
|
title: '支付取消中,请稍后再试!'
|
||||||
if (systemInfo.platform === 'web') {
|
});
|
||||||
window.location.href = payResult.data.payUrl;
|
this.repeatFlag = false;
|
||||||
this.checkPayStatus();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复用文件1的核心逻辑:调用后端/api/pay/pay接口
|
||||||
|
var return_url = '';
|
||||||
|
if (this.payInfo.event == 'BlindboxGoodsOrderPayNotify') {
|
||||||
|
return_url = '/pages_promotion/blindbox/index?outTradeNo=';
|
||||||
} else {
|
} else {
|
||||||
// 小程序/快应用跳WebView
|
return_url = '/pages_tool/pay/result?code=';
|
||||||
this.showPayWebView(payResult.data.payUrl);
|
|
||||||
}
|
}
|
||||||
} else if (payResult.code === 0) {
|
|
||||||
// 关闭支付中弹窗
|
this.$api.sendRequest({
|
||||||
|
url: '/api/pay/pay',
|
||||||
|
data: {
|
||||||
|
out_trade_no: this.payInfo.out_trade_no,
|
||||||
|
pay_type: payType.type,
|
||||||
|
return_url: encodeURIComponent(this.$config.h5Domain + return_url + this.payInfo.out_trade_no),
|
||||||
|
is_balance: this.isBalance
|
||||||
|
},
|
||||||
|
success: res => {
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
|
this.repeatFlag = false; // 重置文件2的防重复标记
|
||||||
|
if (res.code >= 0) {
|
||||||
|
if (res.data.pay_success) {
|
||||||
|
this.paySuccess();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (payType.type) {
|
||||||
|
// 保留文件1的微信支付逻辑(新增空值判断)
|
||||||
|
case 'wechatpay':
|
||||||
|
if (this.$util.isWeiXin()) {
|
||||||
|
if (uni.getSystemInfoSync().platform == 'ios') {
|
||||||
|
var url = uni.getStorageSync('initUrl');
|
||||||
|
} else {
|
||||||
|
var url = location.href;
|
||||||
|
}
|
||||||
|
// 获取jssdk配置
|
||||||
|
this.$api.sendRequest({
|
||||||
|
url: '/wechat/api/wechat/jssdkconfig',
|
||||||
|
data: {
|
||||||
|
url: url
|
||||||
|
},
|
||||||
|
success: jssdkRes => {
|
||||||
|
var wxJS = new Weixin(),
|
||||||
|
payData = res.data.data;
|
||||||
|
// 新增:空值判断,避免读取undefined属性
|
||||||
|
if (!payData) {
|
||||||
|
this.$util.showToast({ title: '微信支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wxJS.init(jssdkRes.data);
|
||||||
|
wxJS.pay({
|
||||||
|
timestamp: payData.timestamp ? payData.timestamp : payData.timeStamp,
|
||||||
|
nonceStr: payData.nonceStr,
|
||||||
|
package: payData.package,
|
||||||
|
signType: payData.signType,
|
||||||
|
paySign: payData.paySign
|
||||||
|
},
|
||||||
|
res => {
|
||||||
|
if (res.errMsg == 'chooseWXPay:ok') {
|
||||||
this.paySuccess();
|
this.paySuccess();
|
||||||
} else {
|
} else {
|
||||||
throw new Error(payResult.msg || '支付失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
// 关闭支付中弹窗
|
|
||||||
uni.hideLoading();
|
|
||||||
this.repeatFlag = false;
|
|
||||||
this.$util.showToast({
|
this.$util.showToast({
|
||||||
title: error.message || '支付失败'
|
title: res.errMsg
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
this.close();
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
res => {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '您已取消支付'
|
||||||
|
});
|
||||||
|
this.resetpay();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 新增:判断res.data.url是否存在
|
||||||
|
if (!res.data.url) {
|
||||||
|
this.$util.showToast({ title: '微信支付链接获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
location.href = res.data.url;
|
||||||
|
this.checkPayStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 保留文件1的支付宝支付逻辑
|
||||||
|
case 'alipay':
|
||||||
|
if (this.$util.isWeiXin()) {
|
||||||
|
// 新增:判断res.data.data是否存在
|
||||||
|
if (!res.data.data) {
|
||||||
|
this.$util.showToast({ title: '支付宝支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var wx_alipay = encodeURIComponent(res.data.data);
|
||||||
|
this.$util.redirectTo('/pages_tool/pay/wx_pay', {
|
||||||
|
wx_alipay: wx_alipay,
|
||||||
|
out_trade_no: this.payInfo.out_trade_no
|
||||||
|
}, '', 'redirectTo');
|
||||||
|
} else {
|
||||||
|
// 新增:判断res.data.data是否存在
|
||||||
|
if (!res.data.data) {
|
||||||
|
this.$util.showToast({ title: '支付宝支付链接获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
location.href = res.data.data;
|
||||||
|
this.checkPayStatus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// 新增华为支付分支处理(沿用文件1范式,补充空值判断)
|
||||||
|
case 'huaweipay':
|
||||||
|
// 新增:先判断res.data.data是否存在
|
||||||
|
if (!res.data.data) {
|
||||||
|
this.$util.showToast({ title: '华为支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
const isHuaweiQuickApp = systemInfo.platform === 'quickapp-huawei';
|
||||||
|
// 华为快应用:尝试原生SDK唤起
|
||||||
|
if (isHuaweiQuickApp && res.data.data.orderInfo) {
|
||||||
|
try {
|
||||||
|
const huaweiPay = require('@service.pay.huawei');
|
||||||
|
huaweiPay.pay({
|
||||||
|
orderInfo: res.data.data.orderInfo,
|
||||||
|
success: () => {
|
||||||
|
this.paySuccess();
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
// 原生失败跳H5链接
|
||||||
|
if (res.data.data.payUrl) {
|
||||||
|
location.href = res.data.data.payUrl;
|
||||||
|
this.checkPayStatus();
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: `华为支付失败:${err.message}`
|
||||||
|
});
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (sdkErr) {
|
||||||
|
// SDK加载失败跳H5
|
||||||
|
if (res.data.data.payUrl) {
|
||||||
|
location.href = res.data.data.payUrl;
|
||||||
|
this.checkPayStatus();
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '华为支付SDK加载失败'
|
||||||
|
});
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (res.data.data.payUrl) {
|
||||||
|
// 非华为快应用:直接跳H5链接
|
||||||
|
location.href = res.data.data.payUrl;
|
||||||
|
this.checkPayStatus();
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '未获取到华为支付链接'
|
||||||
|
});
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: res.message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
fail: res => {
|
||||||
/**
|
uni.hideLoading();
|
||||||
* 显示支付WebView(真实跳转逻辑)
|
this.repeatFlag = false; // 重置文件2的防重复标记
|
||||||
*/
|
this.$util.showToast({
|
||||||
showPayWebView(payUrl) {
|
title: 'request:fail'
|
||||||
this.$util.redirectTo('/pages/Pay/Pay', {
|
});
|
||||||
payUrl: payUrl,
|
}
|
||||||
outTradeNo: this.payInfo.out_trade_no
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 线下支付处理(保留原有逻辑)
|
* 线下支付处理(保留文件2原有逻辑)
|
||||||
*/
|
*/
|
||||||
payOffline() {
|
payOffline() {
|
||||||
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
|
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
|
||||||
@@ -385,8 +499,8 @@ export default {
|
|||||||
// #ifdef MP
|
// #ifdef MP
|
||||||
pay() {
|
pay() {
|
||||||
var payType = this.payTypeList[this.payIndex];
|
var payType = this.payTypeList[this.payIndex];
|
||||||
|
// 保留文件2的线下支付逻辑
|
||||||
if (!payType || payType.type === 'offlinepay') {
|
if (!payType || payType.type === 'offlinepay') {
|
||||||
// 线下支付仍使用原有逻辑
|
|
||||||
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
|
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
|
||||||
outTradeNo: this.payInfo.out_trade_no
|
outTradeNo: this.payInfo.out_trade_no
|
||||||
});
|
});
|
||||||
@@ -394,8 +508,147 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 小程序端真实调用统一支付工具类
|
// 保留文件2的流程控制
|
||||||
this.invokeUnifiedPay(payType.type);
|
if (!this.resetPayComplete) {
|
||||||
|
uni.hideLoading();
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '支付取消中,请稍后再试!'
|
||||||
|
});
|
||||||
|
this.repeatFlag = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复用文件1的小程序端核心逻辑:调用/api/pay/pay
|
||||||
|
this.$api.sendRequest({
|
||||||
|
url: '/api/pay/pay',
|
||||||
|
data: {
|
||||||
|
out_trade_no: this.payInfo.out_trade_no,
|
||||||
|
pay_type: payType.type,
|
||||||
|
scene: uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene,
|
||||||
|
is_balance: this.isBalance
|
||||||
|
},
|
||||||
|
success: res => {
|
||||||
|
uni.hideLoading();
|
||||||
|
this.repeatFlag = false; // 重置文件2的防重复标记
|
||||||
|
if (res.code >= 0) {
|
||||||
|
if (res.data.pay_success) {
|
||||||
|
this.paySuccess();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var payData = res.data.data;
|
||||||
|
|
||||||
|
switch (payType.type) {
|
||||||
|
// 保留文件1的微信支付逻辑(新增空值判断)
|
||||||
|
case 'wechatpay':
|
||||||
|
// 新增:空值判断
|
||||||
|
if (!payData) {
|
||||||
|
this.$util.showToast({ title: '微信支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var scene = uni.getStorageSync('is_test') ? 1175 : wx.getLaunchOptionsSync().scene;
|
||||||
|
if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) {
|
||||||
|
uni.requestOrderPayment({
|
||||||
|
timeStamp: payData.timeStamp,
|
||||||
|
nonceStr: payData.nonceStr,
|
||||||
|
package: payData.package,
|
||||||
|
signType: payData.signType,
|
||||||
|
paySign: payData.paySign,
|
||||||
|
success: res => {
|
||||||
|
this.paySuccess();
|
||||||
|
},
|
||||||
|
fail: res => {
|
||||||
|
this.handlePayFail(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.requestPayment({
|
||||||
|
provider: 'wxpay',
|
||||||
|
...payData,
|
||||||
|
success: res => {
|
||||||
|
this.paySuccess();
|
||||||
|
},
|
||||||
|
fail: res => {
|
||||||
|
this.handlePayFail(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
// 保留文件1的支付宝支付逻辑(新增空值判断)
|
||||||
|
case 'alipay':
|
||||||
|
// 新增:空值判断
|
||||||
|
if (!payData) {
|
||||||
|
this.$util.showToast({ title: '支付宝支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.requestPayment({
|
||||||
|
provider: 'alipay',
|
||||||
|
...payData,
|
||||||
|
success: res => {
|
||||||
|
this.paySuccess();
|
||||||
|
},
|
||||||
|
fail: res => {
|
||||||
|
this.handlePayFail(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
// 新增华为支付小程序端逻辑(补充空值判断)
|
||||||
|
case 'huaweipay':
|
||||||
|
// 新增:空值判断
|
||||||
|
if (!payData) {
|
||||||
|
this.$util.showToast({ title: '华为支付参数获取失败' });
|
||||||
|
this.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (payData.payUrl) {
|
||||||
|
// 小程序端跳WebView页面
|
||||||
|
this.$util.redirectTo('/pages/Pay/Pay', {
|
||||||
|
payUrl: payData.payUrl,
|
||||||
|
outTradeNo: this.payInfo.out_trade_no
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '未获取到华为支付链接'
|
||||||
|
});
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: res.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: res => {
|
||||||
|
uni.hideLoading();
|
||||||
|
this.repeatFlag = false; // 重置文件2的防重复标记
|
||||||
|
this.$util.showToast({
|
||||||
|
title: 'request:fail'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 统一处理支付失败(复用文件1逻辑)
|
||||||
|
*/
|
||||||
|
handlePayFail(res) {
|
||||||
|
this.flag = false;
|
||||||
|
if (res.errMsg.includes('cancel')) {
|
||||||
|
this.$util.showToast({
|
||||||
|
title: '您已取消支付'
|
||||||
|
});
|
||||||
|
this.resetpay();
|
||||||
|
} else {
|
||||||
|
uni.showModal({
|
||||||
|
content: '支付失败,失败原因: ' + res.errMsg,
|
||||||
|
showCancel: false
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
this.close();
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
// #endif
|
// #endif
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user