138 lines
4.0 KiB
TypeScript
138 lines
4.0 KiB
TypeScript
import { resolveLoginPlatform } from '@/api/auth';
|
||
|
||
export interface WxPayParams {
|
||
timeStamp: string;
|
||
nonceStr: string;
|
||
package: string;
|
||
signType: string;
|
||
paySign: string;
|
||
}
|
||
|
||
export const extractWxPayParams = (data: Record<string, any> = {}): WxPayParams => ({
|
||
timeStamp: String(data.timeStamp || data.time_stamp || data.timestamp || ''),
|
||
nonceStr: data.nonceStr || data.nonce_str || '',
|
||
package: data.package || data.pack || '',
|
||
signType: data.signType || data.sign_type || 'RSA',
|
||
paySign: data.paySign || data.pay_sign || ''
|
||
});
|
||
|
||
/** 支付宝小程序 tradeNO,后端 jspay 通常放在 prepay_id 字段 */
|
||
export const extractAlipayTradeNo = (data: Record<string, any> = {}) =>
|
||
String(data.prepay_id || data.tradeNO || '');
|
||
|
||
const ALIPAY_RESULT_MESSAGES: Record<string, string> = {
|
||
'4000': '订单处理失败,请确认 tradeNO 与 buyer_id 是否正确',
|
||
'6001': '已取消支付',
|
||
'6002': '网络连接出错,请稍后重试',
|
||
'6004': '支付结果未知,请在订单页查询',
|
||
'8000': '支付处理中,请在订单页查询'
|
||
};
|
||
|
||
export const formatPaymentError = (error: unknown) => {
|
||
const err = error as any;
|
||
if (err?.message && !/^支付失败$/.test(String(err.message))) {
|
||
return String(err.message);
|
||
}
|
||
|
||
const memo = err?.memo || err?.errMsg || err?.errorMessage || '';
|
||
if (memo && !/^requestPayment:fail/.test(String(memo))) {
|
||
return String(memo);
|
||
}
|
||
|
||
const resultCode = String(err?.resultCode || '');
|
||
if (resultCode && ALIPAY_RESULT_MESSAGES[resultCode]) {
|
||
return ALIPAY_RESULT_MESSAGES[resultCode];
|
||
}
|
||
|
||
if (memo) return String(memo);
|
||
|
||
return '支付失败';
|
||
};
|
||
|
||
export const requestWxPayment = (params: WxPayParams) => {
|
||
return new Promise<void>((resolve, reject) => {
|
||
uni.requestPayment({
|
||
provider: 'wxpay',
|
||
timeStamp: params.timeStamp,
|
||
nonceStr: params.nonceStr,
|
||
package: params.package,
|
||
signType: params.signType,
|
||
paySign: params.paySign,
|
||
success: () => resolve(),
|
||
fail: (error) => reject(error)
|
||
});
|
||
});
|
||
};
|
||
|
||
export const requestAlipayPayment = (tradeNO: string) => {
|
||
console.log('[收银台][支付宝支付] 调起 tradeNO', tradeNO);
|
||
|
||
return new Promise<void>((resolve, reject) => {
|
||
// #ifdef MP-ALIPAY
|
||
if (typeof my !== 'undefined' && typeof my.tradePay === 'function') {
|
||
my.tradePay({
|
||
tradeNO,
|
||
success: (res: any) => {
|
||
console.log('[收银台][支付宝支付] success', res);
|
||
const resultCode = String(res?.resultCode || '');
|
||
if (resultCode === '9000' || resultCode === '8000' || resultCode === '6004') {
|
||
resolve();
|
||
return;
|
||
}
|
||
if (resultCode === '6001') {
|
||
reject({ resultCode, errMsg: 'requestPayment:cancel', memo: '用户取消支付' });
|
||
return;
|
||
}
|
||
reject({
|
||
resultCode,
|
||
memo: res?.memo || ALIPAY_RESULT_MESSAGES[resultCode] || '支付失败'
|
||
});
|
||
},
|
||
fail: (error: any) => {
|
||
console.log('[收银台][支付宝支付] fail', error);
|
||
reject(error);
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
// #endif
|
||
|
||
uni.requestPayment({
|
||
provider: 'alipay',
|
||
orderInfo: tradeNO,
|
||
success: (res) => {
|
||
console.log('[收银台][支付宝支付] uni.requestPayment success', res);
|
||
resolve();
|
||
},
|
||
fail: (error) => {
|
||
console.log('[收银台][支付宝支付] uni.requestPayment fail', error);
|
||
reject(error);
|
||
}
|
||
});
|
||
});
|
||
};
|
||
|
||
/** 按当前端解析 jspay / cash.trade 返回并调起支付 */
|
||
export const requestPlatformPayment = async (data: Record<string, any> = {}) => {
|
||
if (resolveLoginPlatform() === 'mp-alipay') {
|
||
const tradeNO = extractAlipayTradeNo(data);
|
||
if (!tradeNO) {
|
||
throw new Error('支付参数不完整');
|
||
}
|
||
await requestAlipayPayment(tradeNO);
|
||
return;
|
||
}
|
||
|
||
const params = extractWxPayParams(data);
|
||
if (!params.paySign) {
|
||
throw new Error('支付参数不完整');
|
||
}
|
||
await requestWxPayment(params);
|
||
};
|
||
|
||
export const isPaymentCancelled = (error: unknown) => {
|
||
const message = String((error as any)?.errMsg || '');
|
||
const resultCode = String((error as any)?.resultCode || '');
|
||
return message.includes('cancel') || resultCode === '6001';
|
||
};
|