最近公司项目有个充值需求,在微信公众号中添加在线充值,充值页面是用H5完成的,页面中包括微信支付方式和支付宝支付方式。也就是说,要在微信内置浏览器中完成微信支付和支付宝支付。
这个页面,我通过接入Ping++的H5 SDK完成充值功能。附上Ping++的H5 SDK接入指南地址:Ping++ H5 SDK接入指南

开发之前,建议先看一下SDK,有一个大致的了解,然后可以下载demo。附上Github上的demo下载地址:Github上的demo地址。这个链接在文档中也有。
在下载的文件中,有一个demo文件夹,其中的wap.html可以作为开发参考。

下面是ping++支付中前端开发流程的总结(当然需要后端的配合),需要可以做个参考。

微信支付

1.引入pingpp.js文件(文件路径都是我自己项目的文件路径,应该根据自己的项目进行修改)。

<script src="node_modules/pingpp-js/dist/pingpp.js"></script>

2.js中写入支付函数,参照demo中wap.html的wap_pay( )函数。
  刚开始我是将demo中的函数直接复制过来的,但是测试过程中post请求这一块总是有问题,数据发送不过去,我就稍微修改了一下,但是没搞明白为什么demo中的会出错,有清楚的朋友欢迎评论中赐教。示例:

function wap_pay(channel) {
    var YOUR_URL = 后台的充值接口;
    if(YOUR_URL.length == 0 || !YOUR_URL.startsWith('http')){
        alert("请填写正确的URL");
        return;
    }
    var amount = document.getElementById('amount').value * 100; //获取充值金额

    var xhr = new XMLHttpRequest();
    xhr.open("POST", YOUR_URL, true);
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded;application/json;charset=UTF-8");
    xhr.send("channel="+channel+"&amt="+amount+"&id="+id+"&open_id="+open_id);          
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            try{
                var charge = JSON.parse(xhr.responseText)['charge'];
            }catch(err){
                alert('系统错误!');
            }
            pingpp.createPayment(xhr.responseText, function(result, err) {
                console.log(result);
                console.log(err.msg);
                console.log(err.extra);
                if (result == "success") {
                    // 只有微信公众账号 wx_pub 支付成功的结果会在这里返回,其他的支付结果都会跳转到 extra 中对应的 URL(后端处理)。
                    //我的项目中在微信公众号支付成功会跳转到我们的支付成功页面
                    window.location.href = 'success.html';
                } else if (result == "fail") {
                  // charge 不正确或者微信公众账号支付失败时会在此处返回
                  //支付失败会跳转到支付失败页面
                    window.location.href = 'fail.html';
                } else if (result == "cancel") {
                  // 微信公众账号支付取消支付
                  //取消支付同样跳转到支付失败页面
                   window.location.href = 'fail.html';
                }
            });
       }
   }
}

注:请求中需要传给后端的数据,由自己的项目需求而定,比如我的项目中就需要传入用户的id。

关于open_id的获取
微信公众号支付中,需要注意的是,要获取用户的open_id作为用户唯一标识,才能唤起微信支付。同时还需要配置安全域名之类的,我是公司的技术负责人配置的。文档中有链接地址。

ios手机跳转微信支付没反应_支付宝支付

关于open_id的获取方式,我是通过和后端协商以后决定的,大致的前后端交互思路如下:
1. 进入充值页面以后,当用户选好金额,点击微信支付按钮时,跳转至后端给的一个链接,也就是一个后台接口地址,同时将金额和用户id拼接在地址后。
2. 后端在接口中,会默认用户授权登录,获取到授权code,再使用code获取open_id。
3. 后端获取到open_id以后,会将页面跳转到开始的H5充值页面,同时将金额、用户id以及open_id拼接在url地址中。
4. 前端,嗯,也就是我,获取到url中的数据,然后直接执行wap_pay(‘wx_pub’)支付函数,同时将channel、金额、用户id、open_id通过post请求传给后端。
5. 后端返回正确的charge,就可以成功调起支付。(charge中应该是要包含open_id)
6. 在这个过程中,用户的视觉效果就是,点击微信支付以后,页面刷新了一下, 随后就直接调起了微信支付。


上述是一个前后端交互的思路,结合到前端代码的编写,我是按照如下思路编写的: 1. 用户进入充值页面以后,先判断url地址中是否拼接了open_id字段,如果没有拼接,则跳转至后端接口地址。
2. 如果获取到了url地址中open_id字段,则直接执行wap_pay(‘wx_pub’)。

注:获取到open_id重新返回充值页面以后,之前页面中的金额被选中状态已经没有了,所以这里需要根据url中返回的金额,通过JS逻辑将页面重现跳转之前的状态。

这里附上我关于这部分的代码作为参考,不同的项目要根据自己的页面以及需求去修改JS逻辑。

//获取url中的open_id
var Request = new Object();
Request = GetRequest();
open_id = Request['open_id'];
if(open_id == undefined){
    $('.wx').unbind('click').click(function(){
        if(jingyu_id == '' || jingyu_id == null){
              alert('请登录后再充值!');
         }else{
              if($('#amount').length > 0){
                        window.location.href = 'http://a.whale.ikanlive.com/web/wx_pub_pay?money='+amount+'&id='+jingyu_id;
               }else{
                    alert('请选择充值金额!');
               }
         }
    })
}else{
    //这部分代码是为了复现页面跳转之前的状态,也就是页面跳转回来以后,页面仍然是选中金额的状态
    amount = parseInt(Request['money']);
    var money = amount + '元';
    $('.content').find('.content_li').each(function(){
        if($(this).find('.zs_price').text() == money){
            $(this).css('background-image','url(img/images_xz_@2x.png)');
            $(this).attr('id','amount');
        }
    });
    //执行支付函数
    wap_pay('wx_pub');
}

支付宝支付

支付宝支付相比微信支付,要简单一些。只需要在点击按钮时,直接执行wap_pay(‘alipay_wap’);
但是存在的一个问题是,在微信内置浏览器中,是无法直接调起支付宝网页版支付控件的。

针对这一问题,Ping++给出的解决方案是这样的:

ios手机跳转微信支付没反应_H5_02

这上面的两种解决方案都是让充值页面跳转至一个中间页,中间页会提示用户用手机浏览器打开当前页面。
第一种是将pay.htm文件放在和H5充值页面同级目录下。
第二种方式,在充值页面html文件中添加代码:

ios手机跳转微信支付没反应_H5_03

然后修改pay.htm最下面的代码:

ios手机跳转微信支付没反应_微信支付_04

  上面两种方式我都尝试过了,但是都不起作用,点击支付宝支付还是出现了一长串链接。这个问题搞了很久都没有解决,中间页就是无法唤起。后来无奈换了需求,自己做了一个中间跳转页面,然后点击支付宝支付时,跳转至自己的中间页面,提示用户在手机浏览器中打开。这一块有清楚的也欢迎评论留言哦~

支付宝支付思路
所以点击支付宝支付时,先判断当前浏览器,如果是微信浏览器,则跳转中间页,如果是手机浏览器,则执行支付函数。代码示例如下:

//点击支付宝支付判断浏览器
$('.zfb').unbind('click').click(function(){
  var ua = navigator.userAgent.toLowerCase();
  if(ua.match(/MicroMessenger/i)=="micromessenger") {
        // 微信 JS逻辑根据自己需要进行修改
        $('.prompt').slideDown('slow');
   } else {
       if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
         //苹果手机浏览器
         wap_pay('alipay_wap');
       } else if (/(Android)/i.test(navigator.userAgent)) {
        //安卓手机浏览器
          wap_pay('alipay_wap');
       } else {
         confirm('请通过手机浏览器查看此页面!');
       }
    }
 })

  一个大概的微信内置浏览器中微信支付和支付宝支付的总结,前端方面的任务其实很简单,只需要将页面搭建好,然后在点击支付按钮时,执行demo中的wap_pay()函数,向后台发送正确的ajax请求就可以了,主要是后端要返回正确的charge。
  文章中有描述不清楚的地方或者错误的地方还希望能及时指出。后续再有关于H5支付或者PC支付的项目,也会进行补充。