• UNI-APP解析支付宝返回FORM表单,唤起支付宝界面

    简要说明

    项目中微信公众号调用支付宝接口被屏蔽的解决方案

    内容

    2.问题描述

    最近在使用uniapp 开发微信公众号使用支付宝支付,ios页面返回的链接没有参数会被微信屏蔽,安卓手机没问题

    3.问题代码

    ali_pay: function(data) {    var that = this;    document.querySelector('body').innerHTML = data;    //调用submit 方法    document.forms[0].submit() },

    4.支付宝官方文档

    链接地址:https://opendocs.alipay.com/open/203/105285 (滑倒最下面有官方的demo)

    5.实现代码图片




    6-1.实现具体代码ap.js

    1.在common里面创建一个组件目录和文件,ap.js文件就是官网的js文件,自己找个文件夹放着
    ap.js:START
      var b = {};
      var a = {};
      a.PADCHAR = "=";
      a.ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      a.makeDOMException = function() {
        var f, d;
        try {
          return new DOMException(DOMException.INVALID_CHARACTER_ERR)
        } catch(d) {
          var c = new Error("DOM Exception 5");
          c.code = c.number = 5;
          c.name = c.description = "INVALID_CHARACTER_ERR";
          c.toString = function() {
            return "Error: " + c.name + ": " + c.message
          };
          return c
        }
      };
      a.getbyte64 = function(e, d) {
        var c = a.ALPHA.indexOf(e.charAt(d));
        if (c === -1) {
          throw a.makeDOMException()
        }
        return c
      };
      a.decode = function(f) {
        f = "" + f;
        var j = a.getbyte64;
        var h, e, g;
        var d = f.length;
        if (d === 0) {
          return f
        }
        if (d % 4 !== 0) {
          throw a.makeDOMException()
        }
        h = 0;
        if (f.charAt(d - 1) === a.PADCHAR) {
          h = 1;
          if (f.charAt(d - 2) === a.PADCHAR) {
            h = 2
          }
          d -= 4
        }
        var c = [];
        for (e = 0; e < d; e += 4) {
          g = (j(f, e) << 18) | (j(f, e + 1) << 12) | (j(f, e + 2) << 6) | j(f, e + 3);
          c.push(String.fromCharCode(g >> 16, (g >> 8) & 255, g & 255))
        }
        switch (h) {
          case 1:
            g = (j(f, e) << 18) | (j(f, e + 1) << 12) | (j(f, e + 2) << 6);
            c.push(String.fromCharCode(g >> 16, (g >> 8) & 255));
            break;
          case 2:
            g = (j(f, e) << 18) | (j(f, e + 1) << 12);
            c.push(String.fromCharCode(g >> 16));
            break
        }
        return c.join("")
      };
      a.getbyte = function(e, d) {
        var c = e.charCodeAt(d);
        if (c > 255) {
          throw a.makeDOMException()
        }
        return c
      };
      a.encode = function(f) {
        if (arguments.length !== 1) {
          throw new SyntaxError("Not enough arguments")
        }
        var g = a.PADCHAR;
        var h = a.ALPHA;
        var k = a.getbyte;
        var e, j;
        var c = [];
        f = "" + f;
        var d = f.length - f.length % 3;
        if (f.length === 0) {
          return f
        }
        for (e = 0; e < d; e += 3) {
          j = (k(f, e) << 16) | (k(f, e + 1) << 8) | k(f, e + 2);
          c.push(h.charAt(j >> 18));
          c.push(h.charAt((j >> 12) & 63));
          c.push(h.charAt((j >> 6) & 63));
          c.push(h.charAt(j & 63))
        }
        switch (f.length - d) {
          case 1:
            j = k(f, e) << 16;
            c.push(h.charAt(j >> 18) + h.charAt((j >> 12) & 63) + g + g);
            break;
          case 2:
            j = (k(f, e) << 16) | (k(f, e + 1) << 8);
            c.push(h.charAt(j >> 18) + h.charAt((j >> 12) & 63) + h.charAt((j >> 6) & 63) + g);
            break
        }
        return c.join("")
      };
      b.pay = function(d) {
        var c = encodeURIComponent(a.encode(d));
          //###################千万注意这个地方#################
          //location.replace (window.location.origin+"#/alipay?goto="+c)
          //####我的'#/alipay'是pay.htm页面改装过来的路由地址,需要自行替换
          //###################千万注意这个地方#################
          //由于微信浏览器 会在你带链接打开其他页面时截取掉 #后面的参数  所以需要一波处理
        //window.location.protocol 获取https
        //window.location.host 获取域名
        ///mobile#/pages/zhongzhuanye/zhongzhuanye 这是展示在浏览器里面展示的页面地址
        //goto=c  是后台接口返回的支付宝支付参数
        location.href = (window.location.protocol + "//" + window.location.host + "/mobile#/pages/zhongzhuanye/zhongzhuanye?goto="+c)
      };
      b.decode = function(c) {
        return a.decode(decodeURIComponent(c))
      };
      export default b
      ap.js:END

    6-2.实现具体代码组件

    注释 : mounted改成onLoad不能在页面里面直接使用,只能使用组件
    2.在components组件里面alipay创建一个组件目录和文件,方便其他页面文件引入 (注释掉的代码是百度上面的,现有的是自己改过的)
    alipay:STAET
     <template>
        <view>
            <!-- <view class="J-weixin-tip weixin-tip" ref="myWeixinTip">
                <view class="weixin-tip-content" ref="myWeixinTipContent">
                    请在菜单中选择在浏览器中打开,
                    以完成支付
                </view>
            </view>
            <view class="J-weixin-tip-img weixin-tip-img"></view> -->
            <image class="img_width" src="../../static/image/fanhui_pay.jpg" mode="widthFix"></image>
        </view>
    </template>
    <script>
        import _AP from '@/common/ap.js'
        //###说明:ap.js文件就是官网的js文件,自己找个文件夹放着,然后在alipay.vue页面中import
        export default {
            data() {
                return {
                }
            },
            mounted() {
                if (location.hash.indexOf('error') != -1) {
                    console.log('参数错误,请检查');
                } else {
                    var ua = navigator.userAgent.toLowerCase();
                    if (ua.match(/MicroMessenger/i) == "micromessenger"){//判断是否是微信内置浏览器
                        //微信内置浏览器无需处理(需要样式调整的话自行处理)
                    } else {
                        var getQueryString = function(url, name) {
                            var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(\\s|&|$)", "i");
                            if (reg.test(url)) return RegExp.$2.replace(/\+/g, " ");
                        };
                        var param = getQueryString(location.href, 'goto') || '';
                        location.href = param != '' ? _AP.decode(param) : 'pay.htm#error';
                    }
                }
            },
        }
    </script>
    <style>
    .img_width{
        width: 100%;
    }
    </style>
    alipay:END

    6-3.实现具体代码 业务逻辑部分,获取到后台传来的form表单

    <template>
        <view class="back">
            <view class="view_but">
                <view class="but" @click="pay()">支付</view>
            </view>
        </view>
    </template>
    <script>
        import _Ap from '@/common/ap.js'
        export default {
            data() {
                return {
                }
            },
            onLoad(e) {
            },
            methods: {
                /**
                 * 支付
                 */
                pay: function() {
                    var that = this
                    var is_check = that.is_check
                    var type_id = that.type_id
                    var order_id = that.order_id
                    var meterreading_id = meterreading_id
                    var is_list = that.is_list
                    that.httppApi('owner/api.owner/payment',{
                    },1,function(res){
                        if(res.code == 1){
                            if(is_check == 1){
                                that.wx_pay(res.info,res.data)
                            }else{
                                that.ali_pay(res.data.result)
                            }
                        }else{
                            that.msg(res.info)
                        }
                    })
                },
                ali_pay: function(data) {
                    var that = this;
                    /* 
                    **最开始的调用方法因为ios返回没有参数链接所以改成了 ali_pay_form这个方法**
                    document.querySelector('body').innerHTML = data;
                    //调用submit 方法
                    document.forms[0].submit() */
                    that.ali_pay_form(data)
                },
                ali_pay_form(data){
                    var that = this
                    //###业务逻辑部分,获取到后台传来的form表单,搞支付宝接口的应该都知道传来form表单是啥吧
                    let htmls = data
                    const div = document.createElement('div');
                    div.innerHTML = htmls;
                    document.body.appendChild(div);
                    document.forms[0].acceptCharset='utf-8';
                    // document.forms[0].submit();
                    var queryParam = '';
                    Array.prototype.slice
                        .call(
                        document
                        .querySelectorAll("input[type=hidden]"))
                        .forEach(
                        function(ele) {
                            queryParam += ele.name
                                + "="
                                + encodeURIComponent(ele.value)
                                + '&';
                        });
                    let url = document.forms[0].action+ '&' + queryParam
                    console.log(url,'urlurlurlurlurl') 
                    _Ap.pay(url)    
                }, 
                wx_pay: function(msg,data) {
                    var that = this
                    console.log(data)
                    console.log(8989)
                    that.log(data,1)
                    WeixinJSBridge.invoke('getBrandWCPayRequest', {
                        "appId": data.appId, //公众号名称,由商户传入
                        "timeStamp": data.timeStamp, //时间戳
                        "nonceStr": data.nonceStr, //随机串
                        "package": data.package, //扩展包
                        "signType": data.signType, //微信签名方式:MD5
                        "paySign": data.paySign //微信签名
                    }, function(respay) {
                        that.log(respay,2)
                        that.respay = respay
                        if (respay.err_msg === "get_brand_wcpay_request:ok") {
                            that.pay_result();
                        } else if (respay.err_msg === "get_brand_wcpay_request:cancel") {
                            that.msg("取消支付")
                            that.is_submit = 0
                        } else if (respay.err_msg === "get_brand_wcpay_request:fail") {
                            that.msg("支付失败")
                        }
                    }, function(err) {
                        that.msg(msg)
                    });
                },
            },
        }
    </script>

    6-6.实现具体代码 展示在浏览器打开支付的页面代码

    <template>
        <view>
        //alipay直接引入之间
            <alipay></alipay>
        </view>
    </template>
    <script>
        export default {
            data() {
                return {
                }
            },
            methods: {
            }
        }
    </script>
    <style>
    </style>