From 353bc5084a28952e360c4e7a5dc22d552b4fe16d Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Thu, 13 May 2021 21:10:01 +0800
Subject: [PATCH] 抽离公众号 H5 支付为独立模块

---
 common/WxH5Pay.js |  176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 176 insertions(+), 0 deletions(-)

diff --git a/common/WxH5Pay.js b/common/WxH5Pay.js
new file mode 100644
index 0000000..07022b9
--- /dev/null
+++ b/common/WxH5Pay.js
@@ -0,0 +1,176 @@
+/**
+ * WxH5Pay
+ * @author Tevin
+ */
+
+import Taro from '@tarojs/taro';
+import { $ } from '@tarojs/extend';
+import { Tools } from '@components/common/Tools';
+
+const askModal = {
+    $modal: null,
+    show(type, callback) {
+        const that = this;
+        Taro.showModal({
+            title: type === 'ask' ? '微信支付未响应?' : '微信支付仍未响应?',
+            confirmColor: '#4a8aff',
+            confirmText: type === 'ask' ? '点击重试' : '重载页面',
+            success: res => {
+                // 点击重试,执行回调
+                if (res.confirm) {
+                    callback(true);
+                } else if (res.cancel) {
+                    callback(false);
+                }
+                this.$modal = null;
+            },
+        });
+        setTimeout(() => {
+            this.$modal = $('.taro__modal');
+        }, 10);
+    },
+    cancel() {
+        if (this.$modal) {
+            this.$modal.find('.taro-modal__foot > .taro-model__btn:eq(0)').trigger('click');
+            this.$modal = null;
+        }
+    },
+};
+
+export class WxH5Pay {
+
+    constructor() {
+        this._data = {
+            alreadyCall: false,
+        };
+    }
+
+    callWxPay(payParam, callback, type = 'webview') {
+        // 默认 webview 支付
+        if (type === 'webview') {
+            Tools.toast('正在微信支付...');
+            this._data.alreadyCall = false;
+            // 0.1 秒后发起正常支付
+            setTimeout(() => {
+                this._wvChooseWXPay(payParam, callback);
+            }, 100);
+            // 2.2 秒后,如果 alreadyCall 未变为 true,跳出询问弹窗
+            setTimeout(() => {
+                if (!this._data.alreadyCall) {
+                    askModal.show('ask', next => {
+                        if (next) {
+                            this.callWxPay(payParam, callback, 'webview2');
+                        } else {
+                            callback('cancel', '支付已取消!(微信未响应)');
+                            window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-noResponse', 0]);
+                        }
+                    });
+                }
+            }, 2200);
+        }
+        // 第二次 webview 支付
+        else if (type === 'webview2') {
+            // 重新发起支付
+            Tools.toast('正在微信支付...');
+            this._data.alreadyCall = false;
+            // 0.1 秒后发起二次支付
+            setTimeout(() => {
+                this._wvBrandWCPay(payParam, callback);
+            }, 100);
+            // 2.2 秒后,如果 alreadyCall 未变为 true,跳出询问弹窗
+            setTimeout(() => {
+                if (!this._data.alreadyCall) {
+                    askModal.show('reload', next => {
+                        if (next) {
+                            callback('fail', '页面重载中...');
+                            window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-pageReload', 0]);
+                            setTimeout(() => {
+                                if (window.location.href.split('#')[0].indexOf('?') < 0) {
+                                    window.location.href =
+                                        window.location.href.split(/[#?]/)[0] + '?' + window.location.hash;
+                                }
+                                window.location.reload();
+                            }, 1000);
+                        } else {
+                            callback('cancel', '支付已取消!(微信未响应)');
+                            window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-noResponse', 0]);
+                        }
+                    });
+                }
+            }, 2200);
+        }
+    }
+
+    _wvChooseWXPay(payParam, callback) {
+        wx.ready(() => {
+            window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-chooseWXPay:start', 0]);
+            // 发起支付
+            const sign = JSON.parse(payParam);
+            wx.chooseWXPay({
+                ...sign,
+                timestamp: sign.timeStamp,
+                complete: complete => {
+                    // 关闭询问弹窗
+                    askModal.cancel();
+                    this._data.alreadyCall = true;
+                    // 支付结果
+                    if (complete.errMsg === 'chooseWXPay:ok') {
+                        callback && callback('ok', '支付成功!');
+                        window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-chooseWXPay:ok', 0]);
+                    } else if (complete.errMsg === 'chooseWXPay:cancel') {
+                        callback && callback('cancel', '支付已取消!');
+                        window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-chooseWXPay:cancel', 0]);
+                    } else {
+                        let msg = '支付失败!';
+                        // 例如 "chooseWXPay:没有此SDK或暂不支持此SDK模拟"
+                        msg += complete.errMsg ? '(' + complete.errMsg + ')' : '';
+                        callback && callback('fail', msg);
+                        window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-chooseWXPay:fail', 0]);
+                    }
+                },
+            });
+        });
+    }
+
+    _wvBrandWCPay(payParam, callback) {
+        const jsApiCall = () => {
+            window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-BrandWCPay:start', 0]);
+            // 发起支付
+            const sign = JSON.parse(payParam);
+            WeixinJSBridge.invoke('getBrandWCPayRequest', sign, res => {
+                // 关闭询问弹窗
+                askModal.cancel();
+                this._data.alreadyCall = true;
+                // 支付结果
+                if (res.err_msg === 'get_brand_wcpay_request:ok') {
+                    callback && callback('ok', '支付成功!');
+                    window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-brandWCPay:ok', 0]);
+                } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
+                    callback && callback('cancel', '支付已取消!');
+                    window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-brandWCPay:cancel', 0]);
+                } else {
+                    let msg = '支付失败!';
+                    const errMsg = res.err_msg || res.errMsg || '';
+                    // 例如 "chooseWXPay:没有此SDK或暂不支持此SDK模拟"
+                    msg += errMsg ? '(' + errMsg + ')' : '';
+                    callback && callback('fail', msg);
+                    window._hmt.push(['_trackEvent', 'wx', 'wx-wxPay', 'wx-wxPay-brandWCPay:fail', 0]);
+                }
+            });
+        };
+        if (typeof WeixinJSBridge == 'undefined') {
+            if (document.addEventListener) {
+                document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
+            } else if (document.attachEvent) {
+                document.attachEvent('WeixinJSBridgeReady', jsApiCall);
+                document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
+            }
+        } else {
+            jsApiCall();
+        }
+    }
+
+}
+
+// 全局服务实例
+export const $wxH5Pay = new WxH5Pay();
\ No newline at end of file

--
Gitblit v1.9.1