import { useToast } from './useToast' import { ref, reactive } from 'vue'; export function usePayment() { const { Toast } = useToast() // 支付状态 const paymentLoading = ref(false); const paymentResult = ref(null); // 支付配置 const paymentConfig = reactive({ // 支付类型 PAYMENT_TYPES: { ALIPAY: "alipay", WECHAT: "weixin", BALANCE: "balance", }, // 支付状态 PAYMENT_STATUS: { SUCCESS: "支付成功", FAIL: "支付失败", CANCEL: "用户取消支付", }, }); /** * 获取可用的支付渠道 */ const getAvailableChannels = () => { return new Promise((resolve, reject) => { // #ifdef APP uni.getProvider({ service: "payment", success: (res) => { console.log("可用支付渠道:", res.provider); resolve(res.provider); }, fail: (err) => { console.error("获取支付渠道失败:", err); reject(err); }, }); // #endif // #ifndef APP // H5端默认返回所有渠道(实际支付需要调用后端接口) // resolve(["alipay", "wxpay", "balance"]); resolve(["balance"]); // #endif }); }; /** * 支付宝支付 * @param {String} orderInfo - 服务器返回的支付宝订单信息字符串 */ const alipayPayment = (orderInfo) => { return new Promise((resolve, reject) => { // #ifdef APP uni.requestPayment({ provider: "alipay", orderInfo: orderInfo, success: (res) => { console.log("支付宝支付成功:", res); try { const rawdata = JSON.parse(res.rawdata); resolve({ status: paymentConfig.PAYMENT_STATUS.SUCCESS, data: rawdata, message: "支付成功", }); } catch (e) { resolve({ status: paymentConfig.PAYMENT_STATUS.SUCCESS, data: res, message: "支付成功", }); } }, fail: (err) => { console.error("支付宝支付失败:", err); const errorMsg = err.errMsg || "支付失败"; // 判断是否为用户取消 if (errorMsg.includes("cancel") || errorMsg.includes("取消")) { resolve({ status: paymentConfig.PAYMENT_STATUS.CANCEL, data: err, message: "用户取消支付", }); } else { reject({ status: paymentConfig.PAYMENT_STATUS.FAIL, data: err, message: errorMsg, }); } }, }); // #endif // #ifndef APP // H5端需要调用后端接口进行支付 console.warn("H5端支付宝支付需要后端配合实现"); reject({ status: paymentConfig.PAYMENT_STATUS.FAIL, message: "H5端暂不支持支付宝支付", }); // #endif }); }; /** * 微信支付 * @param {Object} orderInfo - 服务器返回的微信支付订单对象 */ const wechatPayment = (orderInfo) => { return new Promise((resolve, reject) => { // 验证订单信息 if (!orderInfo || !orderInfo.appid || !orderInfo.partnerid) { reject({ status: paymentConfig.PAYMENT_STATUS.FAIL, message: "微信支付订单信息不完整", }); return; } // #ifdef APP-PLUS uni.requestPayment({ provider: "wxpay", orderInfo: orderInfo, success: (res) => { console.log("微信支付成功:", res); try { const rawdata = JSON.parse(res.rawdata || "{}"); resolve({ status: paymentConfig.PAYMENT_STATUS.SUCCESS, data: rawdata, message: "支付成功", }); } catch (e) { resolve({ status: paymentConfig.PAYMENT_STATUS.SUCCESS, data: res, message: "支付成功", }); } }, fail: (err) => { console.error("微信支付失败:", err); const errorMsg = err.errMsg || "支付失败"; // 判断是否为用户取消 if (errorMsg.includes("cancel") || errorMsg.includes("取消")) { resolve({ status: paymentConfig.PAYMENT_STATUS.CANCEL, data: err, message: "用户取消支付", }); } else { reject({ status: paymentConfig.PAYMENT_STATUS.FAIL, data: err, message: errorMsg, }); } }, }); // #endif // #ifndef APP // H5端需要调用后端接口进行支付 console.warn("H5端微信支付需要后端配合实现"); reject({ status: paymentConfig.PAYMENT_STATUS.FAIL, message: "H5端暂不支持微信支付", }); // #endif }); }; /** * 统一支付方法 * @param {Object} options - 支付配置 * @param {String} options.type - 支付类型 ('alipay' | 'wxpay' | 'balance') * @param {Object|String} options.orderInfo - 订单信息 * @param {Object} options.params - 其他参数 */ const submitPayment = async (options) => { const { type, orderInfo, params = {} } = options; if (paymentLoading.value) { throw new Error("支付正在进行中,请勿重复提交"); } paymentLoading.value = true; paymentResult.value = null; try { // 检查支付渠道是否可用 const channels = await getAvailableChannels(); console.log("channels:", channels); let result = null; switch (type) { case paymentConfig.PAYMENT_TYPES.ALIPAY: if (channels.indexOf('alipay') === -1) { Toast({title: "设备不支持支付宝支付"}) throw new Error("设备不支持支付宝支付"); } result = await alipayPayment(orderInfo); break; case paymentConfig.PAYMENT_TYPES.WECHAT: if (channels.indexOf('wxpay') === -1) { Toast({title: "设备不支持微信支付"}) throw new Error("设备不支持微信支付"); } result = await wechatPayment(orderInfo); break; case paymentConfig.PAYMENT_TYPES.BALANCE: result = await balancePayment({ ...params, orderInfo }); break; default: throw new Error("不支持的支付类型"); } paymentResult.value = result; return result; } catch (error) { paymentResult.value = error; throw error; } finally { paymentLoading.value = false; } }; return { paymentLoading, paymentResult, paymentConfig, getAvailableChannels, alipayPayment, wechatPayment, submitPayment, } }