cashier/utils/wxpay.ts

138 lines
4.0 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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';
};