pay.js 2.7 KB
// src/utils/pay.js
import PayOrderApi from '@/sheep/api/pay/order';

/**
 * 统一全业务收银台支付核心方法(完美适配:团课、私教课、会员卡、余额充值等)
 * @param {Object} options
 * @param {Object} options.createParams - 传给 createOrder 接口的完整参数
 * @param {String} [options.successUrl] - 支付成功后的自定义跳转路径(不传则默认去订单详情页)
 * @param {Function} [options.onFinally] - 无论成功或失败都会触发的回调(用于关闭遮罩、重置Loading等)
 */
export const unifiedOrderAndPay = async ({ createParams, successUrl, onFinally }) => {
  try {
    // 1. 创建订单
    const res1 = await PayOrderApi.createOrder(createParams);

    // 2. 免费/优惠全抵扣导致的 0 元兑换拦截
    if (res1.data?.channelCode === 'FREE') {
      uni.showToast({ title: '兑换成功', icon: 'success' });

      const defaultUrl = `/pages2/pages/order/dingdan-xianqing?id=${res1.data.orderId}&payOrderId=${res1.data.payOrderId}`;
      setTimeout(() => {
        uni.reLaunch({ url: successUrl || defaultUrl });
      }, 500);
      return;
    }

    // 3. 发起支付提交,获取微信预支付凭证

    const openid = uni.getStorageSync('openid');
    const res2 = await PayOrderApi.payOrderSubmit({
      id: res1.data.payOrderId,
      channelCode: res1.data.channelCode,
      channelExtras: { openid },
    });

    // 4. 解析并调起微信原生支付
    const { timeStamp, nonceStr, packageValue, signType, appId, paySign } = JSON.parse(
      res2.data.displayContent,
    );

    await uni.requestPayment({
      provider: 'wxpay',
      timeStamp,
      nonceStr,
      package: packageValue,
      signType,
      paySign,
      appId,
    });

    // 5. 支付成功处理
    uni.showToast({ title: '支付成功', icon: 'success' });

    // 如果没有传入自定义路径,默认订单详情页
    const defaultUrl = `/pages2/pages/order/dingdan-xianqing?id=${res1.data.orderId}&payOrderId=${res1.data.payOrderId}`;
    setTimeout(() => {
      uni.reLaunch({ url: successUrl || defaultUrl });
    }, 500);
  } catch (err) {
    if (err.errMsg === 'requestPayment:fail cancel' || err === 'cancel') {
      uni.showToast({ title: '你已取消支付', icon: 'none' });
      setTimeout(() => {
        uni.reLaunch({ url: `/pages2/pages/order/dingdan-jilu` });
      }, 500);
    } else {
      uni.showToast({
        title: err.message || err.msg || '支付失败,请重试',
        icon: 'none',
      });
    }
    throw err; // 继续抛出让页面可以感知失败
  } finally {
    // 6. 执行宿主页面的清理收尾逻辑(如关闭弹窗)
    if (typeof onFinally === 'function') {
      onFinally();
    }
  }
};