支付宝兼容
This commit is contained in:
+183
-51
@@ -78,6 +78,10 @@
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
queryById,
|
||||
createWxPayment,
|
||||
getWxPaymentStatus,
|
||||
createAliPayment,
|
||||
getAliPaymentStatus,
|
||||
createAntomPayment,
|
||||
getAntomPaymentMethods,
|
||||
getAntomPaymentStatus
|
||||
@@ -107,9 +111,9 @@
|
||||
const countdown = ref(15 * 60) // 15分钟 = 900秒
|
||||
let countdownTimer = null
|
||||
|
||||
// 支付方式相关
|
||||
// 支付方式相关(微信/支付宝/H5-Antom 多平台)
|
||||
const paymentMethods = ref([])
|
||||
const selectedPaymentMethod = ref('ALIPAY') // 默认选择支付宝
|
||||
const selectedPaymentMethod = ref('WECHAT') // 默认微信
|
||||
|
||||
// 地点名称(可以从设备信息中获取,这里先用默认值)
|
||||
const locationName = ref('澎创办公室')
|
||||
@@ -197,11 +201,11 @@
|
||||
deviceNo.value = orderData.deviceNo;
|
||||
await loadDeviceInfo();
|
||||
await loadPaymentMethods();
|
||||
// #ifdef H5
|
||||
// 如果订单状态是等待支付,启动相应的支付状态轮询
|
||||
if(orderInfo.value.orderStatus=='waiting_for_payment'){
|
||||
// 使用当前选中的支付方式类型进行轮询
|
||||
startPaymentStatusPolling();
|
||||
}
|
||||
// #endif
|
||||
} else {
|
||||
throw new Error(t('order.getOrderFailed'))
|
||||
}
|
||||
@@ -253,35 +257,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 加载支付方式列表
|
||||
// 加载支付方式列表(根据平台决定可选项)
|
||||
const loadPaymentMethods = async () => {
|
||||
if (!orderInfo.value.orderNo) return;
|
||||
const methods = []
|
||||
|
||||
try {
|
||||
const osType = getOsType();
|
||||
console.log('当前系统类型:', osType);
|
||||
// 小程序环境下:微信 / 支付宝
|
||||
// #ifdef MP-WEIXIN
|
||||
methods.push({ paymentMethodType: 'WECHAT', paymentMethodName: '微信支付' })
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
methods.push({ paymentMethodType: 'ALIPAY', paymentMethodName: '支付宝支付' })
|
||||
// #endif
|
||||
|
||||
const res = await getAntomPaymentMethods(orderInfo.value.orderNo, osType);
|
||||
if (res.code === 200 && res.data && res.data.paymentOptions) {
|
||||
paymentMethods.value = res.data.paymentOptions;
|
||||
console.log('支付方式列表:', paymentMethods.value);
|
||||
// 如果有支付方式,默认选择第一个
|
||||
if (paymentMethods.value.length > 0) {
|
||||
selectedPaymentMethod.value = paymentMethods.value[0].paymentMethodType;
|
||||
// H5 环境:使用 Antom 聚合支付(多通道)
|
||||
// #ifdef H5
|
||||
if (orderInfo.value.orderNo) {
|
||||
try {
|
||||
const osType = getOsType();
|
||||
const res = await getAntomPaymentMethods(orderInfo.value.orderNo, osType);
|
||||
if (res.code === 200 && res.data && res.data.paymentOptions) {
|
||||
res.data.paymentOptions.forEach(item => {
|
||||
methods.push({
|
||||
paymentMethodType: item.paymentMethodType,
|
||||
paymentMethodName: item.paymentMethodName || item.paymentMethodType
|
||||
});
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取 Antom 支付方式失败:', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取支付方式失败:', error);
|
||||
// 如果获取失败,使用默认支付方式
|
||||
paymentMethods.value = [{
|
||||
paymentMethodType: 'ALIPAY',
|
||||
paymentMethodName: '支付宝'
|
||||
},
|
||||
{
|
||||
paymentMethodType: 'WECHATPAY',
|
||||
paymentMethodName: '微信支付'
|
||||
}
|
||||
];
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 兜底:至少保留一个微信
|
||||
if (!methods.length) {
|
||||
methods.push({ paymentMethodType: 'WECHAT', paymentMethodName: '微信支付' })
|
||||
}
|
||||
|
||||
paymentMethods.value = methods
|
||||
if (paymentMethods.value.length > 0) {
|
||||
selectedPaymentMethod.value = paymentMethods.value[0].paymentMethodType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,8 +330,85 @@
|
||||
title: t('common.processing')
|
||||
})
|
||||
|
||||
const method = selectedPaymentMethod.value
|
||||
|
||||
// 微信小程序支付押金
|
||||
// #ifdef MP-WEIXIN
|
||||
if (method === 'WECHAT') {
|
||||
const wxRes = await createWxPayment(orderInfo.value.orderNo)
|
||||
if (wxRes.code === 200 && wxRes.data) {
|
||||
const payData = wxRes.data
|
||||
await new Promise((resolve, reject) => {
|
||||
wx.requestPayment({
|
||||
...payData,
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
// 支付成功后轮询微信支付状态
|
||||
startPaymentStatusPolling('WECHAT')
|
||||
return
|
||||
} else {
|
||||
throw new Error(wxRes.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// 支付宝小程序支付押金
|
||||
// #ifdef MP-ALIPAY
|
||||
if (method === 'ALIPAY') {
|
||||
const aliRes = await createAliPayment(orderInfo.value.orderNo)
|
||||
if (aliRes.code === 200 && aliRes.data) {
|
||||
// 后端当前实际返回结构示例:
|
||||
// { code:200, msg:'操作成功', data:{ tradeNo:'xxx', outTradeNo:'yyy' } }
|
||||
const tradeNO = aliRes.data.tradeNo || aliRes.data.outTradeNo
|
||||
const payForm = aliRes.data.payForm || aliRes.data.orderStr
|
||||
|
||||
if (!tradeNO && !payForm) {
|
||||
throw new Error('未获取到支付宝支付参数')
|
||||
}
|
||||
|
||||
// 优先使用 tradeNO 方式,其次兼容老的 orderStr 方式
|
||||
if (tradeNO) {
|
||||
my.tradePay({
|
||||
tradeNO,
|
||||
success: (res) => {
|
||||
if (res.resultCode === '9000') {
|
||||
startPaymentStatusPolling('ALIPAY')
|
||||
} else {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
})
|
||||
} else {
|
||||
my.tradePay({
|
||||
orderStr: payForm,
|
||||
success: (res) => {
|
||||
if (res.resultCode === '9000') {
|
||||
startPaymentStatusPolling('ALIPAY')
|
||||
} else {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: t('payment.paymentFailed'), icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
} else {
|
||||
throw new Error(aliRes.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// H5 + Antom 聚合支付
|
||||
// #ifdef H5
|
||||
const osType = getOsType();
|
||||
const res = await createAntomPayment(orderInfo.value.orderNo, selectedPaymentMethod.value, osType)
|
||||
const res = await createAntomPayment(orderInfo.value.orderNo, method, osType)
|
||||
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const paymentUrl = res.data.h5Url;
|
||||
@@ -326,21 +418,16 @@
|
||||
}
|
||||
|
||||
uni.hideLoading();
|
||||
// #ifdef H5
|
||||
uni.setStorageSync('pendingPaymentNo', orderId.value);
|
||||
// 跳转到支付页面
|
||||
// uni.navigateTo({
|
||||
// url: `/pages/webview/index?url=${encodeURIComponent(paymentUrl)}&title=支付`
|
||||
// });
|
||||
window.open(paymentUrl);
|
||||
// #endif
|
||||
|
||||
// 开始轮询支付状态
|
||||
startPaymentStatusPolling();
|
||||
|
||||
// 开始轮询支付状态(传入当前选中的支付方式类型)
|
||||
startPaymentStatusPolling(method);
|
||||
return
|
||||
} else {
|
||||
throw new Error(res?.msg || t('payment.createPayOrderFailed'))
|
||||
}
|
||||
// #endif
|
||||
} catch (error) {
|
||||
console.error('支付失败:', error)
|
||||
uni.showToast({
|
||||
@@ -352,14 +439,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 轮询支付状态
|
||||
// 轮询定时器
|
||||
let pollingTimer = null;
|
||||
const startPaymentStatusPolling = () => {
|
||||
|
||||
/**
|
||||
* 统一的支付状态轮询方法
|
||||
* @param {string} paymentMethodType - 支付方式类型,如 'WECHAT' | 'ALIPAY' | 'WECHATPAY' 等,与 selectedPaymentMethod 保持一致
|
||||
*/
|
||||
const startPaymentStatusPolling = (paymentMethodType = null) => {
|
||||
// 清除之前的定时器
|
||||
if (pollingTimer) {
|
||||
clearInterval(pollingTimer);
|
||||
}
|
||||
|
||||
// 如果没有传入支付方式类型,使用当前选中的支付方式
|
||||
const methodType = paymentMethodType || selectedPaymentMethod.value;
|
||||
|
||||
let pollCount = 0;
|
||||
const maxPollCount = 60; // 最多轮询60次(5分钟)
|
||||
|
||||
@@ -376,32 +471,64 @@
|
||||
}
|
||||
|
||||
try {
|
||||
let res;
|
||||
let status, successStatus, failStatuses;
|
||||
|
||||
// #ifdef H5
|
||||
// H5 环境统一使用 Antom 聚合支付 API
|
||||
const osType = getOsType();
|
||||
const res = await getAntomPaymentStatus(orderInfo.value.orderNo, osType);
|
||||
res = await getAntomPaymentStatus(orderInfo.value.orderNo, osType);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const paymentStatus = res.data.paymentStatus;
|
||||
status = res.data.paymentStatus;
|
||||
successStatus = 'SUCCESS';
|
||||
failStatuses = ['FAIL', 'CANCELLED'];
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序:根据支付方式类型判断
|
||||
if (methodType === 'WECHAT' || methodType === 'WECHATPAY') {
|
||||
res = await getWxPaymentStatus(orderInfo.value.orderNo);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
status = res.data.tradeStatus;
|
||||
successStatus = 'SUCCESS';
|
||||
failStatuses = ['FAIL', 'CANCELLED'];
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
// 支付宝小程序
|
||||
if (methodType === 'ALIPAY') {
|
||||
res = await getAliPaymentStatus(orderInfo.value.orderNo);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
status = res.data.tradeStatus;
|
||||
successStatus = 'TRADE_SUCCESS';
|
||||
failStatuses = ['TRADE_FAIL', 'TRADE_CANCELLED'];
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (paymentStatus === 'SUCCESS') {
|
||||
// 处理支付状态结果
|
||||
if (res && res.code === 200 && res.data && status) {
|
||||
// 支付成功
|
||||
if (status === successStatus) {
|
||||
clearInterval(pollingTimer);
|
||||
|
||||
// uni.showToast({
|
||||
// title: t('payment.paymentSuccess'),
|
||||
// icon: 'success'
|
||||
// });
|
||||
|
||||
try {
|
||||
await updateUserBalance(orderId.value);
|
||||
} catch (error) {
|
||||
console.warn('更新用户余额失败:', error);
|
||||
}
|
||||
console.log(orderInfo);
|
||||
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({
|
||||
url: `/pages/order/success?orderId=${orderId.value}&deviceId=${orderInfo.value.deviceNo}`
|
||||
});
|
||||
}, 1500);
|
||||
} else if (paymentStatus === 'FAIL' || paymentStatus === 'CANCELLED') {
|
||||
}
|
||||
// 支付失败
|
||||
else if (failStatuses && failStatuses.includes(status)) {
|
||||
clearInterval(pollingTimer);
|
||||
uni.showToast({
|
||||
title: '支付失败,请重新支付',
|
||||
@@ -410,11 +537,16 @@
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询支付状态失败:', error);
|
||||
const errorMsg = methodType === 'ALIPAY' ? '支付宝' : (methodType === 'WECHAT' || methodType === 'WECHATPAY') ? '微信' : '支付';
|
||||
console.error(`查询${errorMsg}支付状态失败:`, error);
|
||||
}
|
||||
}, 5000); // 每5秒查询一次
|
||||
}
|
||||
|
||||
// 兼容性方法:保持原有函数名,内部调用统一方法
|
||||
const startWxPaymentStatusPolling = () => startPaymentStatusPolling('WECHAT');
|
||||
const startAliPaymentStatusPolling = () => startPaymentStatusPolling('ALIPAY');
|
||||
|
||||
// 更新导航栏倒计时
|
||||
const updateNavBarCountdown = () => {
|
||||
const minutes = Math.floor(countdown.value / 60).toString().padStart(2, '0')
|
||||
|
||||
Reference in New Issue
Block a user