上一篇:一个90后员工猝死的全过程

如下介绍一个可运行的微信小程序登录+支付的demo。接触了小程序简易教程的,想必都知道我们必然有自己的后台应用服务器,来处理我们自己的业务逻辑、请求微信服务完成一定的功能。在此,我们的后台采用java环境,本文将首先介绍环境搭建的过程,随后介绍登录+支付的流程及代码。

一、后台web服务环境搭建

1.安装jdk、tomcat,ICP备案的域名准备。

Linux安装jdk:https://blog.csdn.net/zhang918784312/article/details/79751283 Linux 安装tomcat:https://www.cnblogs.com/EasonJim/p/7202844.html 经过icp备案的域名,请自行准备。

2.配置https

由于小程序请求url必须是https,故而必须配置支持https请求。本人采用的是在阿里云购买的域名,故而采用的证书也是阿里云生成的ssl证书,可参考如下两篇博文进行配置。当然,你也可以通过别的方式生成证书,更或者通过nginx作反向代理到你的服务器。

https://blog.csdn.net/qq_28189091/article/details/75078164 https://blog.csdn.net/z_xuewen/article/details/78176509同时,务必将您的小程序域名绑定在小程序后端。登入小程序后台,【设置】-【开发设置】-【服务器域名】

3.部署web服务

如上两步完成后,请务必确认通过你的域名(https://...)可以展示tomcat的默认页之后,开始部署我们的web服务。在此,就简单粗暴的在webapps下建立小程序的根目录,我命名为wechatserver,在此目录下,创建WEB-INFO,下面的目录结构如下:

classes存放自己写的类的classes文件,lib存放我们项目依赖的jar包,logs用于存放我们的日志输出,web.xml是我们这个项目的配置。demo中,我们只有一个servlet接收小程序前端请求,web.xml中增加配置如下:

<servlet><servlet-name>WechatServlet</servlet-name><servlet-class>com.icbc.servlet.WechatServlet</servlet-class></servlet><servlet-mapping><servlet-name>WechatServlet</servlet-name><url-pattern>/servlet/WechatServlet</url-pattern></servlet-mapping>

4. log4j 应用

在开发调试中,我们免不了需要通过打印日志进行调试,因此在此增加了日志的使用。web.xml中增加配置:

<context-param>  <param-name>log4jConfigLocation</param-name>  <param-value>classes/log4j.properties</param-value>
</context-param>

在classes增加文件,log4j.properties,内容如下:

log4j.rootLogger = INFO,toConsole,D,Elog4j.appender.toConsole=org.apache.log4j.ConsoleAppender
log4j.appender.toConsole.Target=System.out
log4j.appender.toConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.toConsole.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] [%p] %m%n log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.file = 你的目录/common.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = info
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.appender.D.DatePattern='.'yyyy-MM-dd'.log'log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.file = 你的目录/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.appender.D.DatePattern='.'yyyy-MM-dd'.log'

二、微信小程序登录+支付

1. 小程序前端目录准备

基于微信小程序工具生成的默认hello world程序,pages下先建立目录order,随后在order目录生成一个新的page,命名为order,结构如下图:

在index中增加按钮,进入order。index.wxml

 <view><navigator class="index-intro__btn btn btn-danger btn-md" url="/pages/order/order">进入商城</navigator></view>

order.xml中描述商品信息,增加支付按钮 order.js 支付事件处理。

2. 登录+支付 code

流程大概分为几步:1)登录,获取code(一个code只能用一次) 2)通过code获取openid(通过请求服务器,由服务器请求微信获取并返回小程序)。微信登录+获取openid接口

3)小程序请求服务器进行预下单,上送商品详情、金额、openid。4)服务器端接收请求,根据请求订单数据、生成第三方订单号,调用微信的统一下单接口。5)服务器收到预下单信息后,签名并组装支付数据,返回给小程序。所需数据见:小程序支付接口 6)小程序前端发起支付,并支付完成 7)服务器收到回调。

2.1 登录,获取code

  onLoad: function (options) {// 登录wx.login({success: function (res) {// 发送 res.code 到后台换取 openId, sessionKey, unionIdvar that = this;if (res.code) {console.log('获取用户登录态success!' + res.code)app.globalData.code = res.code} else {console.log('获取用户登录态失败!' + res.errMsg)}}})  },

2.2 通过code 获取openid(前端)

getOpenId:function(that, code){console.log(code);let operFlag = "getOpenid";console.log(operFlag);wx.request({url: 'https://xxx/wechatserver/servlet/WechatServlet',data: {code:code,operFlag:operFlag},header: { 'content-type': 'application/json' },success: function (res) {console.log(res); var openid = res.data.openid;console.log(openid);that.paypay(that, openid); //预下单并支付},fail: function (res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete:function(res){}})},

2.3 服务器端servlet(复写HttpServlet的doGet doPost函数)doPost的代码片段:

paypay: function (that, openid) {let operFlag = 'pay';wx.request({url: 'https://xxx/wechatserver/servlet/WechatServlet',data: {openid: openid,operFlag: operFlag},header: { 'content-type': 'application/json' },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) {if (res.errMsg == "requestPayment:ok") {wx.showToast({title: '支付成功'})}},'fail': function (res) {}})},fail: function (res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete: function (res) {}})},

2.4 前端上送订单信息、openid请求预下单(在此,为方便,订单信息直接写死在服务器端了),若成功,则根据服务器端返回数据发起支付。关注公众号互联网架构师,在后台回复:2T,可以获取我整理和创作的 Java 系列教程非常齐全

paypay: function (that, openid) {let operFlag = 'pay';wx.request({url: 'https://xxx/wechatserver/servlet/WechatServlet',data: {openid: openid,operFlag: operFlag},header: { 'content-type': 'application/json' },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) {if (res.errMsg == "requestPayment:ok") {wx.showToast({title: '支付成功'})}},'fail': function (res) {}})},fail: function (res) {console.log(res.data.errmsg);console.log(res.data.errcode);},complete: function (res) {}})},

2.5 服务器端预下单,2.6并签名返回支付请求数据

if("pay".equals(operFlag)){String openid = request.getParameter("openid");logger.info("openid = " + openid);String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";String reqStr = getReqStr(openid); //组装预下单的请求数据logger.info("reqStr=" + reqStr);results = sendPost(url,reqStr);//发送post数据到微信预下单logger.info("prepay from weixin: \n " + results);Map<String,String> return_data = null;try {return_data = WXPayUtil.xmlToMap(results);//微信的一个工具类} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();logger.error(e.getMessage());}String return_code = return_data.get("return_code");logger.info("return_code=" + return_code);if("SUCCESS".equals(return_code)){String prepay_id = return_data.get("prepay_id");results = conPayParam(prepay_id); //组装返回数据}else{results ="{\"return_code\":\"fail\"}";}}

附函数

//组装预下单的请求数据public static String getReqStr(String openid){Map<String,String> data = new HashMap<String,String>();String out_trade_no = setTradeNo();////data.put("appid", appid);data.put("mch_id",mer_id);data.put("nonce_str", WXPayUtil.generateUUID());data.put("sign_type", "MD5");data.put("body", "spy test");data.put("out_trade_no", out_trade_no);data.put("device_info", "");data.put("fee_type", "CNY");data.put("total_fee", "1");//1分钱data.put("spbill_create_ip", "123.12.12.123");data.put("notify_url", "http://xxx/wxpay/notify");data.put("trade_type", "JSAPI");data.put("product_id", "12");data.put("openid", openid);try {String sign = WXPayUtil.generateSignature(data, merKey, SignType.MD5);data.put("sign", sign);} catch (Exception e) {e.printStackTrace();logger.error("sign error");}String reqBody = null;try {reqBody = WXPayUtil.mapToXml(data);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return reqBody;}//保证唯一public static String setTradeNo(){String orderid = "20211909105011"+ getRandom(6);logger.info("orderid = " + orderid);return orderid;}//组装返回客户端的请求数据public static String conPayParam(String prepayid){logger.info("根据当前的prepayid构造返回参数= " + prepayid);String results = "";Map<String,String> map = new HashMap<String,String>();map.put("appId", appid);LocalDateTime time = LocalDateTime.now();map.put("timeStamp",  WXPayUtil.getCurrentTimestamp()+"");map.put("nonceStr", WXPayUtil.generateUUID() );map.put("package", "prepay_id=" + prepayid);map.put("signType", "MD5");String sign;try {sign = WXPayUtil.generateSignature(map, merKey, SignType.MD5);map.put("sign", sign);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();logger.error(e.getMessage());}return JSON.toJSONString(map);}

2.6 服务器端返回数据到微信小程序客户端后,发起微信支付,代码在2.3章节已附。2.8 服务器端收到微信的支付成功通知(省略)

三、实战中遇到的问题

1.预下单和支付请求中,签名的密钥使用的是商户密钥,但是用code获取openid是使用小程序对应的secret key,这个可以在小程序的后台看到。

2.微信小程序前端发起post请求到服务器端时,服务器端收不到请求参数。原因是:微信API接口wx.request中:a) 对于 GET 方法的数据,会将数据转换成 query string(encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)

b) 对于 POST 方法且 header[‘content-type’] 为 application/json 的数据,会对数据进行 JSON 序列化

c) 对于 POST 方法且 header[‘content-type’] 为 application/x-www-form-urlencoded 的数据,会将数据转换成 query string (encodeURIComponent(k)=encodeURIComponent(v)&encodeURIComponent(k)=encodeURIComponent(v)…)

所以,如果post请求,为省去服务器端反序列化的操作时,可使用header[‘content-type’] 为 application/x-www-form-urlencoded 的数据。

3.如果部署了servlet后,tomcat重启后,需要等几分钟才能生效(原因是我的机器内存比较小,而tomcat又很占用内存资源),待熟悉tomcat 调优。

作者:我是一个程序媛

来源:blog.csdn.net/proteen/article/details/80875670

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理和创作的 Java 系列教程非常齐全。

推荐阅读

1、2019 年 9 月全国程序员工资统计,你是什么水平?

2、如何才能成为优秀的架构师?

3、从零开始搭建创业公司后台技术栈

4、程序员一般可以从什么平台接私活?

5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6、滴滴业务中台构建实践,首次曝光

7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

8、15张图看懂瞎忙和高效的区别!

Java 接入微信小程序-登录+支付完整流程实战(环境搭建+源码),网友:看完后秒懂!...相关推荐

  1. java版微信小程序多商家入驻前后端分离商城源码 Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  2. JAVA+基于微信小程序的校园信息共享平台 毕业设计-附源码211615

    校园信息共享平台 摘 要 随着信息技术的发展,各大高校已经建立了各自的部门信息系统,但是由于这些应用系统开发时间迥异,开发平台不同,开发技术差异化的原因,各个系统间缺乏关联,使得信息不能有效共享,逐渐 ...

  3. JAVA基于微信小程序的校园信息共享平台毕业设计-附源码211615

    摘 要 随着信息技术的发展,各大高校已经建立了各自的部门信息系统,但是由于这些应用系统开发时间迥异,开发平台不同,开发技术差异化的原因,各个系统间缺乏关联,使得信息不能有效共享,逐渐形成了" ...

  4. java后端微信小程序登录与注册

    java后端微信小程序登录与注册&微信登录授权 分析: 微信小程序用户表 的字段来源于微信服务器 , 必须想办法去获取到对应的用户信息 找到微信开放平台: 微信开放平台 以下是微信开放平台给出 ...

  5. 微信小程序开发的完整流程介绍,新手必读

    自从跳一跳小程序游戏出现后,一夜之间,小程序就变得家喻户晓了,功能开发也越来越丰富,在微信搜一搜就会发现许多大品牌早已有自己的小程序了,越来越多的企业和商家都看中了这个风口,想快速开发出一款属于自己的 ...

  6. java版微信小程序登录商城源码Spring Cloud+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  7. java版微信小程序登录商城源码Spring Cloud+Spring Boot+mybatis+security+uniapp+Redis+MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  8. java版微信小程序登录商城源码MQ+VR全景+b2b2c多商家入驻前后端分离商城源码

    @源码地址来源: https://minglisoft.cn/honghu2/business.html 微信小程序登录代码: /*** Copyright © 2012-2017 <a hre ...

  9. Abp 微信小程序登录 基本的流程和实践

    需求:有个web端,然后移动端使用微信小程序.要把微信用户和系统中的用户对应起来 上一篇搞了个钉钉小程序登录:钉钉小程序登录 微信小程序登录,方便用户输入和系统中校验的也就只有手机号了,既能保证用户唯 ...

  10. 微信小程序+VUE食堂订餐点餐系统(含源码+论文+答辩PPT等)

    项目功能简介: 该项目含有源码.论文等资料.配套开发软件.软件安装教程.项目发布教程等 本系统包含微信小程序前台和Java做的后台管理系统,该后台采用前后台前后分离的形式使用Java+VUE 微信小程 ...

最新文章

  1. 藏在1.85亿人体内的隐形致癌病毒,有人确诊即是晚期
  2. freebsd mysql 安装_Freebsd中mysql安装及使用笔记-阿里云开发者社区
  3. 密码算法中iv值是什么_?标检测中的?极?值抑制算法(nms):python代码解析
  4. 微星z370黑苹果_记录一下装了第二台黑苹果(Z370 + High Sierra)
  5. SAP UI5 Input字段live change事件的一个例子
  6. Kafka学习(一)-------- Quickstart
  7. POJ1182--带权并查集
  8. 狗窝里的小日子 ...
  9. HTML作业-保护环境-保护地球
  10. 为什么李彦宏和雷军在一起了?
  11. java springcloud版b2b2c社交电商spring cloud分布式微服务(十五)Springboot整合RabbitMQ...
  12. echarts 饼图
  13. NodeJS+Express+MongoDB 简单实现数据录入及回显展示【Study笔记】
  14. Ansible基本配置以及使用示例
  15. 海外并购频频被阻 中国芯发展之路困难重重
  16. Spring Tool Suite 4(STS)的下载安装
  17. 统计学 | 峰度系数与肥尾理解
  18. 使用Xbox360手柄控制你的turtlebot/rbx1/mrobot小车机器人
  19. 【控制工程】PID控制的原理和特点
  20. 人工智能应用计算机的实例,人工智能应用实例介绍

热门文章

  1. 读书笔记——思维导图带你看《哲学起步》
  2. CentOS 7 启用远程连接和使用postgis等客户端连接
  3. 教你React Native使用fetch实现图片上传
  4. 京东黑科技引爆车联网时代 你的爱车升级了吗?
  5. Linux 下编译安装 PHP 5.6
  6. 大牛精心挑选的25个Visual Basic学习资料汇总
  7. Illustrator中文版教程,如何在 Illustrator 中创建几何图案?
  8. 强大的绘图和编辑工具Artstudio Pro mac
  9. 苹果Mac照片编辑插件套件:Nik Collection
  10. Mac上的文件拖拽增强工具space drop如何使用?