176 lines
4.8 KiB
TypeScript
176 lines
4.8 KiB
TypeScript
/**
|
|
* 支付工具类 - uni-app 版本
|
|
*/
|
|
import { paymentApi } from '@/api';
|
|
import type { CreateOrderParams } from '@/api/types';
|
|
import { showToast } from './uni-compat';
|
|
import { quickWechatPay, secureWechatPay, handlePaymentResult, type PaymentResult } from './wechat-payment';
|
|
|
|
declare const uni: any;
|
|
|
|
/**
|
|
* 发起微信支付(推荐使用新的微信支付方法)
|
|
* @param params 订单参数
|
|
* @param secure 是否使用安全模式(启用支付状态验证)
|
|
* @returns Promise<支付结果>
|
|
*/
|
|
export const wxPay = async (
|
|
params: CreateOrderParams,
|
|
secure: boolean = false
|
|
): Promise<{
|
|
success: boolean;
|
|
outTradeNo?: string;
|
|
msg?: string;
|
|
}> => {
|
|
try {
|
|
// 使用新的微信支付集成
|
|
const result: PaymentResult = secure
|
|
? await secureWechatPay(params)
|
|
: await quickWechatPay(params);
|
|
|
|
return {
|
|
success: result.success,
|
|
outTradeNo: result.outTradeNo,
|
|
msg: result.msg
|
|
};
|
|
} catch (error: any) {
|
|
console.error('支付流程失败:', error);
|
|
const errorMsg = error.msg || error.message || '支付失败,请重试';
|
|
showToast({ title: errorMsg, icon: 'none' });
|
|
|
|
return {
|
|
success: false,
|
|
msg: errorMsg
|
|
};
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 发起快速微信支付(不验证支付状态)
|
|
* @param params 订单参数
|
|
* @returns Promise<支付结果>
|
|
*/
|
|
export const quickPay = async (params: CreateOrderParams) => {
|
|
return wxPay(params, false);
|
|
};
|
|
|
|
/**
|
|
* 发起安全微信支付(验证支付状态)
|
|
* @param params 订单参数
|
|
* @returns Promise<支付结果>
|
|
*/
|
|
export const securePay = async (params: CreateOrderParams) => {
|
|
return wxPay(params, true);
|
|
};
|
|
|
|
/**
|
|
* 通用支付方法(带回调处理)
|
|
* @param params 订单参数
|
|
* @param callbacks 支付结果回调
|
|
* @param secure 是否使用安全模式
|
|
*/
|
|
export const payWithCallbacks = async (
|
|
params: CreateOrderParams,
|
|
callbacks: {
|
|
onSuccess?: (result: any) => void;
|
|
onFail?: (result: any) => void;
|
|
onCancel?: (result: any) => void;
|
|
},
|
|
secure: boolean = false
|
|
) => {
|
|
try {
|
|
const result: PaymentResult = secure
|
|
? await secureWechatPay(params)
|
|
: await quickWechatPay(params);
|
|
|
|
handlePaymentResult(result, {
|
|
onSuccess: callbacks.onSuccess,
|
|
onFail: callbacks.onFail,
|
|
onCancel: callbacks.onCancel
|
|
});
|
|
|
|
return result;
|
|
} catch (error: any) {
|
|
console.error('支付流程失败:', error);
|
|
const errorMsg = error.msg || error.message || '支付失败,请重试';
|
|
|
|
const failResult = {
|
|
success: false,
|
|
msg: errorMsg
|
|
};
|
|
|
|
callbacks.onFail?.(failResult);
|
|
return failResult;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 查询订单状态
|
|
* @param outTradeNo 商户订单号
|
|
* @returns Promise<订单信息>
|
|
*/
|
|
export const queryOrderStatus = async (outTradeNo: string) => {
|
|
try {
|
|
const res = await paymentApi.queryOrder(outTradeNo);
|
|
return res;
|
|
} catch (error: any) {
|
|
console.error('查询订单失败:', error);
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 轮询查询订单状态(用于支付后确认)
|
|
* @param outTradeNo 商户订单号
|
|
* @param maxAttempts 最大尝试次数
|
|
* @param interval 查询间隔(毫秒)
|
|
* @returns Promise<是否支付成功>
|
|
*/
|
|
export const pollOrderStatus = async (
|
|
outTradeNo: string,
|
|
maxAttempts: number = 10,
|
|
interval: number = 2000
|
|
): Promise<boolean> => {
|
|
for (let i = 0; i < maxAttempts; i++) {
|
|
try {
|
|
const res = await queryOrderStatus(outTradeNo);
|
|
|
|
if (res.status === 'paid') {
|
|
return true;
|
|
} else if (res.status === 'cancelled' || res.status === 'refunded') {
|
|
return false;
|
|
}
|
|
|
|
// 等待后继续查询
|
|
await new Promise(resolve => setTimeout(resolve, interval));
|
|
} catch (error) {
|
|
console.error(`第${i + 1}次查询订单失败:`, error);
|
|
|
|
if (i === maxAttempts - 1) {
|
|
throw error;
|
|
}
|
|
|
|
await new Promise(resolve => setTimeout(resolve, interval));
|
|
}
|
|
}
|
|
|
|
return false;
|
|
};
|
|
|
|
/**
|
|
* 关闭订单
|
|
* @param outTradeNo 商户订单号
|
|
* @returns Promise<是否成功>
|
|
*/
|
|
export const closeOrder = async (outTradeNo: string): Promise<boolean> => {
|
|
try {
|
|
await paymentApi.closeOrder(outTradeNo);
|
|
showToast({ title: '订单已关闭', icon: 'success' });
|
|
return true;
|
|
} catch (error: any) {
|
|
console.error('关闭订单失败:', error);
|
|
showToast({ title: error.msg || '关闭订单失败', icon: 'none' });
|
|
return false;
|
|
}
|
|
};
|