微信小程序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中直接调用支付的接口。如果大家有更好的实现思路,千万别忘了告诉我哦。由于作者还是个工作不到一年的小菜。在代码编写上还有很多的不足,欢迎大家指正。这也是我的第一篇博客,嗯嗯嗯还是有点小激动。^_^微信小程序
最新评论
优秀的团队,万商直播管理系统
不错的小程序案例
优秀的团队,不错的服务!
讲的很好
主播长的帅气
好系统好服务
优秀的团队
好服务,值得信赖