Przeglądaj źródła

fix: 修复微信JSAPI支付调用方式,使用WeixinJSBridge.invoke代替wx.chooseWXPay,开启vConsole方便调试

MyFramework User 3 miesięcy temu
rodzic
commit
1637479136

+ 2 - 4
my-uniapp-vue3/src/main.ts

@@ -18,10 +18,8 @@ export function createApp() {
   userStore.initUser();
   userStore.initUser();
 
 
   // #ifdef H5
   // #ifdef H5
-  // vConsole 已禁用,需要时取消下方注释
-  // if (process.env.NODE_ENV !== 'production') {
-  //   new VConsole();
-  // }
+  // vConsole 开启,用于调试微信支付问题
+  new VConsole();
   // #endif
   // #endif
 
 
   return {
   return {

+ 108 - 103
my-uniapp-vue3/src/pages/payment-confirm/index.vue

@@ -323,117 +323,41 @@ async function handleWechatJsapiPay() {
       });
       });
     }
     }
 
 
-    orderInfo.value.orderNo = result.orderNo;
+    // 注意:post 函数返回的是 response.data,即 { code, message, data: {...} }
+    const responseData = result.data || result; // 兼容直接返回 data 的情况
+    orderInfo.value.orderNo = responseData.orderNo;
     uni.hideLoading();
     uni.hideLoading();
 
 
-    // 使用 wx.chooseWXPay 调起支付(微信官方推荐方式)
-    const currentResult = result; // 保存引用,避免闭包问题
+    // 使用 WeixinJSBridge.invoke 调起支付(微信官方推荐方式)
+    const currentResult = responseData; // 保存引用,避免闭包问题
     
     
-    // 检查wx对象是否存在
-    if (typeof (window as any).wx === 'undefined') {
-      console.error('[WeChat Pay] wx对象不存在,可能未引入微信JS-SDK');
-      uni.showToast({ title: '支付环境异常,请刷新页面重试', icon: 'none' });
-      paying.value = false;
-      return;
-    }
-
-    // 1. 先获取JS-SDK签名并配置wx.config
-    const currentUrl = window.location.href.split('#')[0]; // 去掉hash部分
-    console.log('[WeChat Pay] 获取JS-SDK签名,url:', currentUrl);
-    
-    try {
-      const signResult = await get<any>('/payment/wechat/jssdk-sign', { url: currentUrl });
-      
-      if (!signResult || !signResult.appId) {
-        throw new Error('获取JS-SDK签名失败');
-      }
+    console.log('[WeChat Pay] 准备调起 WeixinJSBridge, payParams:', JSON.stringify(currentResult.payParams));
 
 
-      console.log('[WeChat Pay] JS-SDK签名获取成功,准备配置wx.config');
+    // 检查 WeixinJSBridge 是否存在
+    if (typeof (window as any).WeixinJSBridge === 'undefined') {
+      console.error('[WeChat Pay] WeixinJSBridge 不存在,等待注入...');
       
       
-      // 配置wx.config
-      (window as any).wx.config({
-        debug: false, // 调试时可以改为true
-        appId: signResult.appId,
-        timestamp: signResult.timestamp,
-        nonceStr: signResult.nonceStr,
-        signature: signResult.signature,
-        jsApiList: ['chooseWXPay'] // 需要使用的JS接口列表
-      });
-
-      // 等待wx.ready
-      await new Promise<void>((resolve, reject) => {
-        (window as any).wx.ready(() => {
-          console.log('[WeChat Pay] wx.ready 成功');
-          resolve();
+      // 如果 WeixinJSBridge 还未注入,监听注入事件
+      if (document.addEventListener) {
+        document.addEventListener('WeixinJSBridgeReady', () => {
+          console.log('[WeChat Pay] WeixinJSBridge 已注入,开始调起支付');
+          invokeWeixinJSBridge(currentResult);
+        }, false);
+      } else if ((document as any).attachEvent) {
+        (document as any).attachEvent('WeixinJSBridgeReady', () => {
+          console.log('[WeChat Pay] WeixinJSBridge 已注入,开始调起支付');
+          invokeWeixinJSBridge(currentResult);
         });
         });
-        
-        (window as any).wx.error((err: any) => {
-          console.error('[WeChat Pay] wx.error:', err);
-          reject(new Error('wx.config失败: ' + JSON.stringify(err)));
+        (document as any).attachEvent('onWeixinJSBridgeReady', () => {
+          console.log('[WeChat Pay] WeixinJSBridge 已注入,开始调起支付');
+          invokeWeixinJSBridge(currentResult);
         });
         });
-      });
-
-      console.log('[WeChat Pay] 开始调起wx.chooseWXPay');
-      
-      // 2. 使用 wx.chooseWXPay 调起支付
-      (window as any).wx.chooseWXPay({
-        timestamp: currentResult.payParams.timeStamp,
-        nonceStr: currentResult.payParams.nonceStr,
-        package: currentResult.payParams.package,
-        signType: currentResult.payParams.signType || "RSA",
-        paySign: currentResult.payParams.paySign,
-        success: async (res: any) => {
-          console.log('[WeChat Pay] wx.chooseWXPay 成功:', JSON.stringify(res));
-          // 官方要求:必须调用查询订单API确认最终状态
-          const orderStatus = await checkWechatOrderStatus(currentResult.orderNo);
-          paying.value = false;
-
-          if (orderStatus === 'SUCCESS') {
-            uni.showModal({
-              title: '支付成功',
-              content: productType.value === 'token-pack' ? '积分包购买成功!' : '恭喜您订阅成功!',
-              showCancel: false,
-              success: () => uni.switchTab({ url: '/pages/mine/index' })
-            });
-          } else {
-            uni.showToast({ title: '订单确认中,请稍后查看', icon: 'none' });
-          }
-        },
-        fail: async (err: any) => {
-          console.error('[WeChat Pay] wx.chooseWXPay 失败:', JSON.stringify(err));
-          // 官方要求:必须调用查询订单API确认最终状态
-          const orderStatus = await checkWechatOrderStatus(currentResult.orderNo);
-          paying.value = false;
-
-          if (orderStatus === 'SUCCESS') {
-            // 桥回调失败但订单已支付(延迟回调)
-            uni.showModal({
-              title: '支付成功',
-              content: productType.value === 'token-pack' ? '积分包购买成功!' : '恭喜您订阅成功!',
-              showCancel: false,
-              success: () => uni.switchTab({ url: '/pages/mine/index' })
-            });
-          } else {
-            uni.showModal({
-              title: '支付失败',
-              content: `微信支付调起失败 (${err.errMsg || err.err_msg || '未知错误'}),是否使用扫码支付?`,
-              confirmText: '扫码支付',
-              cancelText: '取消',
-              success: (modalRes: any) => {
-                if (modalRes.confirm && currentResult.orderNo) {
-                  inWechat.value = false;
-                  handlePay();
-                }
-              }
-            });
-          }
-        }
-      });
-    } catch (configError: any) {
-      console.error('[WeChat Pay] wx.config 失败:', configError);
-      uni.showToast({ title: '支付配置失败: ' + (configError.message || '未知错误'), icon: 'none' });
-      paying.value = false;
+      }
+      return;
     }
     }
+
+    // WeixinJSBridge 已存在,直接调起
+    invokeWeixinJSBridge(currentResult);
   } catch (error: any) {
   } catch (error: any) {
     paying.value = false;
     paying.value = false;
     uni.hideLoading();
     uni.hideLoading();
@@ -448,6 +372,87 @@ async function handleWechatJsapiPay() {
   }
   }
 }
 }
 
 
+// 调用 WeixinJSBridge.invoke
+function invokeWeixinJSBridge(payResult: any) {
+  const payParams = payResult.payParams;
+  
+  if (!payParams || !payParams.package) {
+    console.error('[WeChat Pay] payParams 异常:', payParams);
+    uni.showToast({ title: '支付参数异常', icon: 'none' });
+    paying.value = false;
+    return;
+  }
+
+  console.log('[WeChat Pay] 调用 WeixinJSBridge.invoke, params:', JSON.stringify(payParams));
+
+  (window as any).WeixinJSBridge.invoke(
+    'getBrandWCPayRequest',
+    {
+      appId: payParams.appId,
+      timeStamp: payParams.timeStamp,
+      nonceStr: payParams.nonceStr,
+      package: payParams.package,
+      signType: payParams.signType || 'RSA',
+      paySign: payParams.paySign,
+    },
+    async (res: any) => {
+      console.log('[WeChat Pay] WeixinJSBridge 回调:', JSON.stringify(res));
+      paying.value = false;
+
+      if (res.err_msg === 'get_brand_wcpay_request:ok') {
+        // 支付成功(前端返回,需调用查询API确认)
+        console.log('[WeChat Pay] 前端返回支付成功,查询订单状态...');
+        const orderStatus = await checkWechatOrderStatus(payResult.orderNo);
+
+        if (orderStatus === 'SUCCESS') {
+          uni.showModal({
+            title: '支付成功',
+            content: productType.value === 'token-pack' ? '积分包购买成功!' : '恭喜您订阅成功!',
+            showCancel: false,
+            success: () => uni.switchTab({ url: '/pages/mine/index' })
+          });
+        } else {
+          // 前端返回成功但订单未成功(延迟回调)
+          uni.showToast({ title: '订单确认中,请稍后查看', icon: 'none' });
+        }
+      } else {
+        // 支付失败或取消
+        console.log('[WeChat Pay] 支付失败或取消:', res.err_msg);
+        
+        // 官方要求:必须调用查询订单API确认最终状态
+        const orderStatus = await checkWechatOrderStatus(payResult.orderNo);
+
+        if (orderStatus === 'SUCCESS') {
+          // 桥回调失败但订单已支付(延迟回调)
+          uni.showModal({
+            title: '支付成功',
+            content: productType.value === 'token-pack' ? '积分包购买成功!' : '恭喜您订阅成功!',
+            showCancel: false,
+            success: () => uni.switchTab({ url: '/pages/mine/index' })
+          });
+        } else {
+          // 用户取消或真正失败
+          const isCancel = res.err_msg === 'get_brand_wcpay_request:cancel';
+          uni.showModal({
+            title: isCancel ? '支付取消' : '支付失败',
+            content: isCancel ? '您已取消支付' : `支付失败 (${res.err_msg || '未知错误'})`,
+            showCancel: !isCancel,
+            confirmText: '重新支付',
+            cancelText: '取消',
+            success: (modalRes: any) => {
+              if (modalRes.confirm) {
+                // 重新调起支付
+                paying.value = false;
+                handleWechatJsapiPay();
+              }
+            }
+          });
+        }
+      }
+    }
+  );
+}
+
 async function handlePay() {
 async function handlePay() {
   // 防重处理:2秒内禁止重复点击(官方要求按钮防抖)
   // 防重处理:2秒内禁止重复点击(官方要求按钮防抖)
   const now = Date.now();
   const now = Date.now();