lex-xin 3 months ago
parent
commit
8e79dd76ae

+ 8 - 0
src/router/router-root.ts

@@ -96,6 +96,14 @@ export default [
     }
   },
   {
+    path: '/payResultWechat',
+    name: 'payResult',
+    component: () => import('@/views/adapay/pay-result-wechat'),
+    meta: {
+      title: '支付'
+    }
+  },
+  {
     path: '/preview-protocol',
     name: 'preview-protocol',
     component: () => import('@/views/preview-protocol/index'),

+ 55 - 0
src/views/adapay/pay-result-wechat/index.module.less

@@ -0,0 +1,55 @@
+.paywxresult {
+  overflow: hidden;
+  // background: #fff;
+  min-height: 100vh;
+
+  :gloabl {
+    .van-cell {
+      padding: 12px 16px;
+    }
+    .van-cell__title,
+    .van-cell__value {
+      flex: auto;
+      font-size: 16px;
+      color: #4f4f4f;
+    }
+    .van-button {
+      font-size: 16px;
+      width: 86%;
+      margin: 20px auto;
+    }
+    .van-loading__spinner {
+      width: 50px;
+      height: 50px;
+    }
+  }
+}
+.container {
+  background: #fff;
+  padding: 15px 0;
+}
+
+.order-loading {
+  padding: 15px 0;
+  margin-top: 15px;
+  background-color: #ffffff;
+  text-align: center;
+  font-size: 15px;
+  & > p {
+    margin-bottom: 15px;
+  }
+}
+.error-text {
+  font-size: 15px;
+  width: 100%;
+  text-align: center;
+  color: #3f3f3f;
+  margin-top: 100px;
+}
+
+.error-icon {
+  display: block;
+  color: #ffb07b;
+  font-size: 22px;
+  margin-bottom: 20px;
+}

+ 286 - 0
src/views/adapay/pay-result-wechat/index.tsx

@@ -0,0 +1,286 @@
+import request from '@/helpers/request';
+import { browser, getUrlCode, moneyFormat } from '@/helpers/utils';
+import { goAliAuth, goWechatAuth } from '@/state';
+import {
+  Cell,
+  CellGroup,
+  Icon,
+  Loading,
+  showConfirmDialog,
+  showToast
+} from 'vant';
+import { defineComponent, onMounted, reactive } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'pay-result',
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const state = reactive({
+      errorText: '',
+      browserStatus: false,
+      code: null as any,
+      pay_channel: route.query.pay_channel as any,
+      wxAppId: route.query.wxAppId as any,
+      paymentType: route.query.paymentType as any,
+      alipayAppId: route.query.alipayAppId as any,
+      body: route.query.body as any,
+      price: route.query.price as any,
+      orderNo: route.query.orderNo as any,
+      userId: route.query.userId as any,
+      payInfo: {} as any,
+      isYeePay: false // 是否为易宝支付
+    });
+
+    const init = () => {
+      const query = route.query;
+      const isYeePay = state.paymentType.indexOf('yeepay') !== -1;
+      // 判断是否有支付对象
+      if (!query.orderNo || !query.pay_channel) {
+        showConfirmDialog({
+          message: '支付订单信息错误请重新支付',
+          showCancelButton: false
+        }).then(() => {
+          router.back();
+        });
+      } else {
+        // 判断当前浏览器
+        if (browser().weixin) {
+          state.browserStatus = true;
+          getWxPay();
+        } else if (browser().alipay) {
+          if (isYeePay) {
+            let code = getUrlCode('auth_code');
+            if (code) {
+              state.code = code; // 赋值code码
+              state.browserStatus = true;
+              getPayment();
+            } else {
+              goAliAuth(state.alipayAppId);
+            }
+          } else {
+            state.browserStatus = true;
+            getPayment();
+          }
+        } else {
+          state.errorText = '请在微信或支付宝客户端打开';
+          document.title = 'ERROR';
+        }
+      }
+    };
+
+    const getPayment = async () => {
+      try {
+        if (parseFloat(state.price) <= 0) {
+          showToast('支付金额异常');
+          return;
+        }
+        const payMap: any = {
+          merOrderNo: state.orderNo,
+          paymentChannel: state.pay_channel, // 支付渠道
+          userId: state.userId,
+          code: state.code
+        };
+        //     // 判断是否是微信公众号支付
+        // if (state.pay_channel == 'wx_pub') {
+        // payMap.code = state.code;
+        // }
+
+        const { data } = await request.post(
+          '/edu-app/open/userOrder/executePayment',
+          {
+            data: {
+              ...payMap
+            }
+          }
+        );
+        state.isYeePay = data.paymentVender?.indexOf('yeepay') !== -1;
+        console.log(data, 'data');
+        scanCodePay(data.reqParams);
+      } catch (e) {
+        //
+        console.log(e);
+        // 接口报错也跳转到支付回调页
+        // window.location.replace(
+        //   location.origin +
+        //     '/classroom-app/#/payment-result?orderNo=' +
+        //     state.orderNo
+        // );
+      }
+    };
+
+    // 由于js的载入是异步的,所以可以通过该方法,当AlipayJSBridgeReady事件发生后,再执行callback方法
+    const ready = (callback: any) => {
+      if ((window as any).AlipayJSBridge) {
+        callback && callback();
+      } else {
+        document.addEventListener('AlipayJSBridgeReady', callback, false);
+      }
+    };
+    const tradePay = (tradeNO: any) => {
+      ready(function () {
+        // 通过传入交易号唤起快捷调用方式(注意tradeNO大小写严格)
+        (window as any).AlipayJSBridge.call(
+          'tradePay',
+          {
+            tradeNO: tradeNO
+          },
+          function (data: any) {
+            // if ('9000' == data.resultCode) {
+            //   window.location.replace(
+            //     location.origin +
+            //       '/classroom-app/#/payment-result?orderNo=' +
+            //       state.orderNo
+            //   );
+            // } else {
+            //   window.location.replace(
+            //     location.origin +
+            //       '/classroom-app/#/payment-result?orderNo=' +
+            //       state.orderNo
+            //   );
+            // }
+            //使用的支付宝内置api实现关闭H5
+            (window as any).AlipayJSBridge.call('closeWebview');
+          }
+        );
+      });
+    };
+    const scanCodePay = (data: any) => {
+      // 判断支付方式 如果是 test 模式 支付用测试url 否则用生产url
+      if (state.pay_channel == 'alipay_qr') {
+        if (state.isYeePay) {
+          tradePay(data.tradeNO);
+        } else {
+          const url =
+            data.prod_mode === 'false'
+              ? data?.expend?.qrcode_url +
+                '?payment_id=' +
+                data.id +
+                '&pay_channel=' +
+                data.pay_channel
+              : data?.expend?.qrcode_url;
+          window.location.href = url;
+        }
+      } else if (state.pay_channel == 'alipay_wap') {
+        window.location.href = data?.expend?.pay_info;
+      } else if (state.pay_channel == 'wx_pub') {
+        const tempPayInfo = state.isYeePay
+          ? JSON.parse(data.prePayTn)
+          : data?.expend
+          ? JSON.parse(data?.expend?.pay_info)
+          : data;
+        state.payInfo = tempPayInfo;
+        if (typeof (window as any).WeixinJSBridge == 'undefined') {
+          if (document.addEventListener) {
+            document.addEventListener(
+              'WeixinJSBridgeReady',
+              onBridgeReady,
+              false
+            );
+          } else if ((document as any).attachEvent) {
+            (document as any)
+              .attachEvent(
+                'WeixinJSBridgeReady',
+                onBridgeReady
+              )(document as any)
+              .attachEvent('onWeixinJSBridgeReady', onBridgeReady);
+          }
+        } else {
+          onBridgeReady();
+        }
+      }
+    };
+
+    const onBridgeReady = () => {
+      const payInfo = state.payInfo;
+      // let orderNo = state.orderNo
+      (window as any).WeixinJSBridge.invoke(
+        'getBrandWCPayRequest',
+        {
+          appId: payInfo.appId, //公众号名称,由商户传入
+          timeStamp: payInfo.timeStamp, //时间戳,自1970年以来的秒数
+          nonceStr: payInfo.nonceStr, //随机串
+          package: payInfo.package || payInfo.packageValue,
+          signType: payInfo.signType, //微信签名方式:
+          paySign: payInfo.paySign //微信签名
+        },
+        (res: any) => {
+          // if(res.err_msg == "get_brand_wcpay_request:ok" ){
+          // 使用以上方式判断前端返回,微信团队郑重提示:
+          //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+          // } else
+
+          console.log(res, 'res')
+          if (
+            res.err_msg == 'get_brand_wcpay_request:cancel' ||
+            res.err_msg == 'get_brand_wcpay_request:fail'
+          ) {
+            // window.location.replace(
+            //   location.origin +
+            //     '/classroom-app/#/payment-result?orderNo=' +
+            //     state.orderNo
+            // );
+          } else {
+            // 使用以上方式判断前端返回,微信团队郑重提示:
+            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+            // alert('支付成功')
+            // window.location.replace(
+            //   location.origin +
+            //     '/classroom-app/#/payment-result?orderNo=' +
+            //     state.orderNo
+            // );
+          }
+        }
+      );
+    };
+
+    const getWxPay = () => {
+      // 微信公众号支付
+      //授权
+      const code = getUrlCode();
+      if (!code) {
+        goWechatAuth(state.wxAppId);
+      } else {
+        state.code = code;
+        getPayment();
+      }
+    };
+
+    onMounted(() => {
+      init();
+    });
+
+    return () => (
+      <div class={styles.paywxresult}>
+        {state.browserStatus && (
+          <>
+            <div class={styles.container}>
+              <CellGroup border={false}>
+                <Cell
+                  title={'订单金额'}
+                  value={'¥ ' + moneyFormat(state.price)}></Cell>
+                <Cell title={'订单信息'} value={state.body}></Cell>
+              </CellGroup>
+            </div>
+
+            <div class={styles['order-loading']}>
+              <p>{state.pay_channel == 'wx_pub' ? '微信支付' : '支付宝支付'}</p>
+              <Loading type="spinner" color="#01C1B5" />
+            </div>
+          </>
+        )}
+
+        {!state.browserStatus && (
+          <div class={styles['error-text']}>
+            {state.errorText && (
+              <Icon class={styles['error-icon']} name="warning-o" />
+            )}
+            {state.errorText}
+          </div>
+        )}
+      </div>
+    );
+  }
+});