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