微信支付点金计划从试错到成功

最近开发的公众号中,接入了微信的点金计划,就是在支付完成后,点击完成按钮会跳转到微信的一个页面,页面上可以展示订单和商户的基本信息,下部还有自带的广告信息,详细的可以了解下微信的官方文档:微信点金计划,文档里介绍了产品信息、接入方法等内容。

但是,众所周知某些开发文档对于初次开发的人员来说并不友好,甚至文档都快背下来了,依旧不知道怎么去开发,并且中途遇到问题在文档里也找不到合理的解决办法,这时候还得是靠广大的网友的聪明智慧了......

这里先上一下全部代码,然后再说明遇到的问题和解决问题思路。对于点金计划页面,可以使用路由做一个页面,也可以单独写个html页面,这里我使用的是html+万能的jquery

xml 复制代码
<!DOCTYPE html>
<html lang="en" data-design-width="750" data-design-font="100" >
<head>
  <meta charset="UTF-8">
  <link rel="icon" href="../favicon.png" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover" />
  <title>支付完成页</title>
  <!-- 点金计划必须接入的js -->
  <script type="text/javascript" charset="UTF-8" src="https://wx.gtimg.com/pay_h5/goldplan/js/jgoldplan-1.0.0.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
  <script>
    // 字号转换rem
    (function (window, undefined) { 
      var html_dom = document.getElementsByTagName('html')[0]; 
      var design_width = parseInt(html_dom.dataset.designWidth, 10); 
      var design_font = parseInt(html_dom.dataset.designFont, 10); 
      var isMobile = /Mobile/.test(window.navigator.userAgent); 
      window.onresize = function () { 
        resizeRoot(); 
      } 
      function resizeRoot() { 
        var client_width = document.documentElement.clientWidth; 
        if (client_width >= 750) { 
          client_width = 750; 
        } 
        var fs = client_width / design_width * design_font; 
        html_dom.style.fontSize = fs + "px"; 
      }; 
      resizeRoot(); 
    })(window)
  </script>
  <script th:inline="javascript">
  //获取url中返回参数
  function  getQueryString(name) {
    var query = window.location.search.substring(1);
    var vars = query.split("&");
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == name) {
            return pair[1];
        }
    }
    return null;
  }
  
  // 获取cookie
  function getck(sname) {  //获取单个cookies
    if(document.cookie){
      var acookie = document.cookie.split("; ");
      for (var i = 0; i < acookie.length; i++) {
        var arr = acookie[i].split("=");
        if (sname == arr[0]) {
          if (arr.length > 1) {
            console.log('arr', arr[1])
            return unescape(arr[1]);
          } else {
            return "";
          }
        }
      }
      return "";
    }
  }
  
  window.onload = function(){
    var out_trade_no = getQueryString("out_trade_no");   //商户订单号
    $.ajax({
      type: "POST",
      url: window.location.origin + '/payResult',
      data: JSON.stringify({
        orgId: out_trade_no
      }),
      contentType: "application/json; charset=utf-8",
      dataType: "json",
      headers: {
        'token': getck('token')
      },
      success: function (res) {
        console.log('请求成功',res)
        if (res && res.code == 200 && res.data) {
            // 根据页面需要展示的内容进行修改
            $('.merTitle').html(res.data.merName)
            $('.name').html(res.data.nickName)
            $('.amt strong').html(res.data.amt)
            $('.headImg').attr('src', res.data.picUrl)
  
            var mchData = { action: 'onIframeReady', displayStyle: 'SHOW_CUSTOM_PAGE', height: 404 };
            let postData = JSON.stringify(mchData);
            // window.parent.postMessage(postData, 'https://payapp.weixin.qq.com');
            top.postMessage(postData, '*');
  
            // 注册点击事件,即点击页面上按钮跳转出去
            document.querySelector('#goOrder').onclick = function () {
              let pathname = window.location.pathname
              let pathnameArr = pathname.split('/')
              var mchData = {
                  action: 'jumpOut',
                  jumpOutUrl: window.location.origin + '/' + pathnameArr[1] + '/#/bbb?id=' + res.data.id   //跳转的页面
              }
              console.log('调用成功',mchData);
              var postData = JSON.stringify(mchData)
              // parent.postMessage(postData, "https://payapp.weixin.qq.com")
              top.postMessage(postData, "*")
            }
        }
      },
      error: function(err){
        console.log('请求出错',err)
      }
    });
  }
  </script>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    .pay_over .content {
      text-align: center;
      background-color: rgba(246, 246, 246, 1);
      width: 99%;
      margin: .5rem auto 0;
      position: relative;
    }

    .pay_over .content .headImg {
      width: 1.5rem;
      height: 1.5rem;
      border-radius: 50%;
      position: absolute;
      left: 50%;
      top: -.25rem;
      margin-left: -.75rem;
    }

    .pay_over .content .merTitle {
      font-size: .42rem;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #333333;
      margin: 0 0 .56rem;
      padding-top: 1.5rem;
    }

    .pay_over .content .name {
      font-size: .42rem;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #333333;
      margin: 0 0 .16rem;
    }

    .pay_over .content .amt {
      font-size: .8rem;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #333333;
      margin: 0 0 .4rem;
    }

    .pay_over .content .amt span {
      font-size: .36rem;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      padding-left: .1rem;
    }

    .pay_over .content .link {
      font-size: .32rem;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #1677FF;
      padding-bottom: .42rem;
    }

    .pay_over .content .link a {
      text-decoration: underline;
      font-family: PingFangSC-Regular, PingFang SC;
    }
  </style>
</head>
<body>
  <div class="pay_over">
    <div class="content">
      <img class="headImg" src="" alt="">
      <div class="merTitle"></div>
      <div class="name"></div>
      <div class="amt"><strong></strong><span>元</span></div>
      <div class="link" id="goOrder"><a href="javascript:void 0">查看订单详情</a></div>
    </div>
  </div>
</body>
</html>

上面就是出版的点金计划页面代码,在本地调试接口是没问题的,但是如果真的需要模拟点金计划完整页面的效果,需要把这个页面放到服务器上,并把路径配到微信商家配置里,才可以进行调试,这部分文档有相关方法,不再赘述。

重点说一下开发中遇到的问题,就是能够支付完成,也能够跳转到点金页面,但是部分(基本就是IOS)手机会显示无法获取订单信息,这也是小伙伴们遇到的最多的问题。

针对这个问题,官方也给出了几条建议:

1、已打开特约商户的商家小票及点金计划开关

2、商家小票页面需调用父页面"onIframeReady事件"的jsapi,具体请查看商家小票开发指引

3、从加载商家小票到调用JSAPI之间的用时不可超过3s

4、调试时,扫描二维码的微信号和支付该笔测试订单的微信号需为同一个

5、商家小票页面可正常访问

6、检查商家小票请求的Response Headers中X-Frame-Options是否允许payapp.weixin.qq.com访问

7、如果是使用VUE,onIframeReady不能放在created里执行

8、如果上述方法都不行,请先编写一个最简单的demo页面,看看demo页面是否成功

9、商家URL是否有进行重定向,是否重定向到http的链接

不过这些建议有的可以验证,有的真的无从下手...所以针对上面的问题楼主联合了后端一起排查,通过日志发现,在请求的时候实际上已经报错了,问题就出在通过cookie获取token上面,此时cookie为空了,自然接口的登录信息校验就过不去了。

这里也是楼主的疏忽,本来觉得点金页面和实际业务页都在一个域名下,cookie是可以共享的,能够完美获取;但是实际上,到真实环境中上面开发的页面是通过iframe被嵌入到微信官方页面中的;大部分安卓和一部分IOS 能够正常显示页面,只有部分IOS无法正常显示,借用网上其他小伙伴的说法,这就是系统的差异,能够正常显示的在跳转时没有清除登录信息,但是IOS把登录信息都清掉了。所以如果涉及缓存存取,还是要慎重!!!

到这里问题原因就很明确了,后端做了相应的修改,给这个接口加白名单,不去校验token(当然是在业务允许的情况下),前端代码获取不获取token就无所谓了。

最后,在上边官方给出的九条建议上再加一条:

10、检查业务逻辑请求是否涉及到登录信息存取,如无业务需求,尽量避免登录相关校验

相关推荐
papapa键盘侠5 小时前
Coze 实战教程 | 10 分钟打造你的AI 助手
人工智能·微信·信息可视化
若水无华19 小时前
fiddler 配置ios手机代理调试
ios·智能手机·fiddler
Aress"20 小时前
【ios越狱包安装失败?uniapp导出ipa文件如何安装到苹果手机】苹果IOS直接安装IPA文件
ios·uni-app·ipa安装
Jouzzy1 天前
【iOS安全】Dopamine越狱 iPhone X iOS 16.6 (20G75) | 解决Jailbreak failed with error
安全·ios·iphone
瓜子三百克1 天前
采用sherpa-onnx 实现 ios语音唤起的调研
macos·ios·cocoa
左钦杨1 天前
IOS CSS3 right transformX 动画卡顿 回弹
前端·ios·css3
努力成为包租婆1 天前
SDK does not contain ‘libarclite‘ at the path
ios
安和昂2 天前
【iOS】Tagged Pointer
macos·ios·cocoa
I烟雨云渊T2 天前
iOS 阅后即焚功能的实现
macos·ios·cocoa
struggle20252 天前
适用于 iOS 的 开源Ultralytics YOLO:应用程序和 Swift 软件包,用于在您自己的 iOS 应用程序中运行 YOLO
yolo·ios·开源·app·swift