Uniapp小程序处理微信支付的异步方法

包含以下主要步骤:

  1. 检查并设置商品ID
  2. 调用购买接口获取支付参数
  3. 检查网络状态
  4. 发起微信支付
  5. 处理支付结果
async handleBuyVip() {
    
    
  let that = this;
  try {
    
    
    // Step1: 调用购买接口获取支付的参数
    const res = await buyVip({
    
    
      goods_id: this.goods_id
    });

    if (res && res.data) {
    
    
      // 缓存订单信息(用于可能的重新支付场景)
      that.orderInfo = res.data;

      // Step2: 网络状态检查
      await uni.getNetworkType({
    
    
        success: (networkRes) => {
    
    
          if (networkRes.networkType === 'none') {
    
    
            uni.showToast({
    
    
              title: '网络未连接,请检查网络',
              icon: 'none'
            });
            return Promise.reject('network unavailable') // 主动中断流程
          }

          // Step3: 发起支付请求
          return new Promise((resolve, reject) => {
    
    
            // 添加loading状态防止重复点击
            uni.showLoading({
    
     title: '发起支付中' })

            uni.requestPayment({
    
    
              ...that.orderInfo, // 需要包含以下参数:
              // timeStamp: 时间戳(单位秒)
              // nonceStr: 随机字符串
              // package: 统一下单接口返回的 prepay_id 格式如:prepay_id=***
              // signType: 签名算法
              // paySign: 签名
              // 注意:不同小程序平台参数可能不同
              success: res => {
    
    
                uni.hideLoading()
                // 支付成功后续处理
                console.log("支付成功", res);
                setTimeout(() => {
    
    
                  uni.navigateBack(); 
                }, 1000);
                resolve()
              },
              fail: err => {
    
    
                uni.hideLoading()
                console.error('支付失败', err)
                // 区分用户取消支付和真正支付失败的情况
                if (err.errCode === 6001) {
    
    
                  uni.showToast({
    
     title: '您取消了支付', icon: 'none' })
                } else {
    
    
                  uni.showToast({
    
     title: '支付失败', icon: 'none' })
                }
                setTimeout(() => {
    
    
                  uni.navigateBack(); 
                }, 1000);
                reject(err)
              }
            });
          });
        }
      });
    } else {
    
    
      // 处理接口异常情况
      console.error('接口返回数据异常', res);
      uni.showToast({
    
    
        title: res?.msg || '获取支付信息失败',
        icon: 'none'
      });
    }
  } catch (error) {
    
    
    // 统一错误处理
    console.error('流程异常:', error);
    uni.showToast({
    
    
      title: error.message || '购买会员失败',
      icon: 'none'
    });
  }
},

注意事项说明

1. 支付参数验证

时间戳单位:微信小程序要求timeStamp为秒级时间戳(10位数字),需注意与毫秒级时间戳的区分。

参数完整性:确保orderInfo包含以下必需参数:

{
    
    
  timeStamp: '',  // 支付签名时间戳
  nonceStr: '',   // 随机字符串
  package: '',    // 统一下单接口返回的 prepay_id
  signType: '',   // 签名算法 MD5/HMAC-SHA256/RSA等
  paySign: '',    // 签名
}

2. 网络状态处理

必要性检查:在发起支付前检查网络状态,避免在弱网环境下出现支付中断

异常处理:当检测到无网络时,建议:

  • 显示明确的错误提示
  • 记录失败日志
  • 提供重试按钮

3. 支付结果处理

成功处理建议

  • 立即更新本地用户VIP状态
  • 发送支付成功通知
  • 跳转前建议先获取最新用户信息

失败处理建议

  • 区分用户主动取消(errCode 6001)和系统错误
  • 保留在当前页面允许重新支付
  • 记录失败日志用于后续分析

4. 用户体验优化

防止重复点击

// 在方法开始处添加
if (this.isPaying) return
this.isPaying = true

// 在finally中添加
.finally(() => {
    
    
  this.isPaying = false
})

加载状态提示:使用uni.showLoading()防止用户误操作

跳转延迟:支付结果提示至少保持1秒后再跳转

5. 跨平台兼容

参数差异:不同小程序平台(微信/支付宝/百度)的支付参数可能不同

平台检测

 #ifdef MP-WEIXIN
// 微信专用参数
 #endif

 #ifdef MP-ALIPAY
// 支付宝专用参数
 #endif

6. 安全注意事项

敏感信息处理:不要在客户端存储或传输支付密钥

签名验证:确保签名在服务端生成,客户端仅做参数传递

防重复支付:服务端需要校验订单状态

7. 错误监控

异常捕获:使用try-catch包裹异步操作

日志记录:关键节点添加日志记录(建议使用唯一订单号跟踪)

错误上报:使用uni.report()或第三方监控服务

猜你喜欢

转载自blog.csdn.net/weixin_61529967/article/details/145822759
今日推荐