微信小程序> 微信小程序webview公众号与小程序支付的切换使用

微信小程序webview公众号与小程序支付的切换使用

浏览量:571 时间: 来源:相信自己Justin

微信小程序web-view公众号与小程序支付间的切换使用

        最近小程序开放了新功能,支持内嵌网页。html写的网页,官网,网站,运行在浏览器上的,有域名的那种,可以内嵌到小程序里了!

那么这意味着什么呢?你还需要开发独立开发官网小程序吗?之前的微信公众号功能大部分也可以直接通过小程序webview实现了。
这几天刚好公司也有这方面的需求,怀着激动心情的我开始了踩坑之旅。

     开发之前我们需要把需要的环境配置好,这里就引用官方的介绍了————

1. 开发者登录小程序后台,选择设置-开发设置-业务域名,新增配置域名模块。目前小程序内嵌网页能力暂不开放给个人类型帐号和海外类型帐号。
 2.配置的业务域名必须时https

那么配置好后,马上可以进入开发啦!
     小程序

  页面中引入公众号的首页,小程序端的代码不是很多,主要的是后台进行结合。1.在后端添加一个小程序的入口方法,

/** * 小程序第一次入口 * @return */public String wxIndex(){//返回首页    sessions=request.getSession().getId();    return "home";}

这里我没有做任何的处理,这个项目首页是不用登陆的,直接返回首页;来到这一步时我们发现之前公众号后台保存在session中的信息获取不到,使用后发现小程序每次请求sessionId都会发生改变,这样后台无法使用session储存数据。

解决方案:

小程序第一次请求后台返回一个sessionId,之后小程序在参数或header中带入这个sessionId,后台使用这个session来处理。注意session销毁以及过期设置。


wx.login({  success: function (res) {        wx.getSetting({      success(setRes) {        // 判断是否已授权          if (!setRes.authSetting['scope.userInfo']) {          // 授权访问            wx.authorize({            scope: 'scope.userInfo',            success() {              //获取用户信息                wx.getUserInfo({                lang: "zh_CN",                success: function (userRes) {                  // var session_id= wx.getStorageSync('JSESSIONID');                  //发起网络请求                    wx.request({                    url: 'https://www.ulin5.com/vip/buser-bind-mobile_wxXiaoChengXuLogin.html',                    data: {                      code: res.code,                      encryptedData: userRes.encryptedData,                      iv: userRes.iv                    },                    header: {                      "Content-Type": "application/x-www-form-urlencoded"                    },                    method: 'POST',                    //服务端的回掉                      success: function (result) {                      console.log(result)                      // var session_id = wx.getStorageSync('JSESSIONID');//本地取存储的sessionID                        // if (session_id == null || session_id == "") {                        wx.setStorageSync('JSESSIONID', result.data.sessionId) //如果本地没有就说明第一次请求 把返回的session id 存入本地                        // }                      console.log(result.data.openId)                      getApp().openid = result.data.openId                      // var data = result.data.result;                      // data.expireTime = nowDate + EXPIRETIME;                      // wx.setStorageSync("userInfo", data);                      // userInfo = data;                    }                  })                }              })            }          })          })

 把小程序所需要的openid和unionid拿到,由于公众号的openid   和小程序的openid不同,所以这需要用到unionid。换句话说,同一用户,对同一个微信开放平台帐号下的不同应用,UnionID是相同的。此前的OpenID机制,每个微信号对应每个公众号只有唯一的OpenID,所以不同微信公众号之间是不能共享用户的,现在有了UnionID就可以了。   前面说到小程序每次请求的sessionId不同,所以通过sessionId可以获取到我们存储的数据信息。   注意Servlet2.1之后不支持SessionContext里面getSession(String id)方法。   我这里通过HttpSessionListener监听器和全局静态map自己实现一个SessionContext。

public class MySessionContext { private static HashMap mymap = new HashMap();    public static synchronized void AddSession(HttpSession session) {        if (session != null) {            mymap.put(session.getId(), session);        }    }    public static synchronized void DelSession(HttpSession session) {        if (session != null) {            mymap.remove(session.getId());        }    }    public static synchronized HttpSession getSession(String session_id) {        if (session_id == null)        return null;        return (HttpSession) mymap.get(session_id);    }    }

        public class SessionListener implements HttpSessionListener {/*public static Map userMap = new HashMap();  *//*private   MySessionContext myc=MySessionContext.getInstance();  */@Overridepublic void sessionCreated(HttpSessionEvent arg0) {    /*myc.AddSession(arg0.getSession()); */    MySessionContext.AddSession(arg0.getSession());}@Overridepublic void sessionDestroyed(HttpSessionEvent arg0) {    HttpSession session = arg0.getSession();      /*myc.DelSession(session);*/     MySessionContext.DelSession(session);}}

web.xml添加一个监听器:

<listener>  <listenerclass>com.common.util.SessionListener</istener-class>  </listener>  

根据sessionId获取Session对象:

String sessionId = request.getParameter("sessionId");

HttpSession session = MySessionContext.getSession(sessionId);

写到这里已经算是完成一半了,只要在后台加一个处理小程序进来的方法,把所需要的用户信息保存到数据库中。我们不需要改变以前写好处理公众号的任何代码(根据项目进行整合),

public String wxLogin(){//java后端String Code = request.getParameter("code");// 登陆状态码    String typeDate = request.getParameter("encryptedData");// 用户加密信息,用于解密获取unionid    String iv = request.getParameter("iv");// 解密密钥    String OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret"            + "=SECRET&js_code=JSCODE&grant_type=authorization_code";// 获取openid的地址    UserInfo userInfo = null;    String url = OPENID_URL.replace("APPID", Pkcs7Encoder.APPID)            .replace("SECRET", Pkcs7Encoder.APPSECRET)            .replace("JSCODE", Code);    JSONObject jsonObject = null;    jsonObject = Pkcs7Encoder.doGetStr(url);// 调取Get提交方法    String OpenId = jsonObject.getString("openid"); // 获取openid    /*     * ResourceBundle resource = ResourceBundle.getBundle("weixin");     * //读取属性文件     */String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; // 请求地址    /* String wxUserInfo=Pkcs7Encoder.sendPost(requestUrl, requestUrlParam); */    // 获取会话密钥(session_key)    String session_key = jsonObject.getString("session_key");       ....     //通过逻辑代码保存我们需要的信息}

  接下来到最重要的环节了,到了我们最期待的支付环节了。由于web-view目前还不支持支付接口。  我们需要判断是否运行在小程序环境中进行支付的互换,从而实现支付功能。

<script type="text/javascript"src="https://res.wx.qq.com/open/js/jweixin-1.3.0.js"></script>

在网页内可通过window.__wxjs_environment变量判断是否在小程序环境。


// web-view下的页面内
wx.ready(function() {
   console.log(window.__wxjs_environment === 'miniprogram') // true
})

例如:

  var isWxMini = window.__wxjs_environment ===       'miniprogram';    if (isWxMini) {//判断是否在微信小程序环境中调用支付接口    $("#wxloading").hide();    var jumpUrl = encodeURIComponent(window.location)    //把要用到的参数传到小程序中进行支付    var path = '/pages/pay/pay?jhNum='+jhNum+'&cproType='+cproType+'&zcProId='+zcProId+'&url='+url+'&cproId='+cproId+'&esOrderc='+esOrderc;    wx.miniProgram.navigateTo({        url: path    })}else{//公众号支付window.location.href="/vip/buy-group_saveJoinPt.html?cproId="+cproId+"&jhNum="+jhNum+"&cproType="+cproType+"&zcProId="+zcProId+"&esOrderc="+esOrderc;}

小程序pay文件夹下新建pay.js和pay.wxml

 pay.js          Page({  onLoad: function (options) {  console.log(options)    // 获取网页传过来的值 // TODO 用es6解构来获取值TODOvar jhNum = options.jhNumvar cproType = options.cproTypevar zcProId = options.zcProIdvar cproId = options.cproIdvar esOrderc = options.esOrderc// var jumpUrl = decodeURIComponent(options.jumpUrl)var tourl=options.url// console.log(tourl)var openid = getApp().openidconsole.log(openid)var session_id = wx.getStorageSync('JSESSIONID')//本地取存储的sessionID// console.log('----------sessionid' + session_id+'-----------------')wx.request({  url: tourl,  data: {    openid: openid,    jhNum: jhNum,    cproType: cproType,    zcProId: zcProId,    cproId: cproId,    esOrderc: esOrderc  },  header: {    "Content-Type": "application/x-www-form-urlencoded",    'Cookie': 'JSESSIONID=' + session_id  },  method: 'POST',  success: function (res){    console.log(res)    wx.requestPayment({      'timeStamp': res.data.timeStamp,      'nonceStr': res.data.nonceStr,      'package': res.data.package,      'signType': 'MD5',      'paySign': res.data.sign,      'success': function (res) {        console.log('支付成功')         wx.navigateBack() //返回会上个页面      },      'fail': function (res) {        console.log('支付失败')          wx.navigateBack() //返回会上个页面      }    })  }})}})

到这基本上已经完成,个人感觉这种实现方式在用户体验度上并不是很友好,但是基本的功能都可以实现。相信官方也会对webview更进一步的优化。能在webview中直接调用支付的接口。如果大家有更好的实现思路,千万别忘了告诉我哦。由于作者还是个工作不到一年的小菜。在代码编写上还有很多的不足,欢迎大家指正。这也是我的第一篇博客,嗯嗯嗯还是有点小激动。^_^
微信小程序

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎