java开发Demo~微信扫码支付,java开发示例-程序员宅基地

技术标签: java  运维  数据库  

开发所需工具类


img_e9aae379ed635a160cdfa112351457ff.png

开发所需jar

img_91daabb3505225de542aac9f3599ac80.png

具体的代码不贴了,说明下PayConfigUtil中的参数


img_e785935e024bfb9944c69db8ebe76d95.png

APP_ID和APP_SECRET在公众平台 

MCH_ID和API_KEY在商户平台,其中API_KEY是自己设置的,并不是自动生成的。

Controller

通过此方法,前往可以生成二维码的页面

//微信前往支付页面

    @RequestMapping(value = "towxPay")

    public ModelAndView towxPay(ModelMap map,HttpServletRequest request,String chapterId,String chapterName,String price) throws IOException{

        ModelAndView mav = new ModelAndView();

        mav.setViewName("jsp/pay/weixinpayma");

        HttpSession session = request.getSession();

        session.setAttribute("chapterId", chapterId);

        session.setAttribute("chapterName", chapterName);

        session.setAttribute("price", price);

        return mav;

    }

返回的页面如下

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

                <%

    String path = request.getContextPath();

    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()

            + path + "/";

%>

Insert title here

   


<%=basePath%index/payImg style="min-height:null;min-width:null;" width=null height=null />


   

    /* ajax轮回,不停的访问Controller,直到wxPayType=1时,付款成功 */

        var num = 0;

        $(function(){

            panduanWXPay();

        });

        function panduanWXPay(){

            $.post("<%=basePath%>index/panduanPay",function(data){

                var wxPayType = data.wxPayType;

                if(wxPayType==1){

                /* 成功 */

                    window.location.href='<%=basePath%>index/gouMai';

                }else if(wxPayType==0 && num!=400){

                    num++;

                    panduanWXPay();

                }else{

                    alert("支付超时");

                }

            });

        } 


payImg方法

//微信支付,生成二维码

    @RequestMapping(value = "payImg")

    public  void payImg(HttpServletRequest request, HttpServletResponse response) throws IOException{

        HttpSession session = request.getSession();

        String chapterName=(String)session.getAttribute("chapterName");

        String price=(String)session.getAttribute("price");

        int defaultWidthAndHeight=200;

        String nonce_str = PayCommonUtil.getNonce_str();

        long time_stamp = System.currentTimeMillis() / 1000;

        String product_id = chapterName+"*"+price;//订单名字和价钱,拼到了一起,后面用到的时候再拆

        String key = PayConfigUtil.API_KEY; // key

        SortedMap packageParams = new TreeMap();

        packageParams.put("appid", PayConfigUtil.APP_ID);

        packageParams.put("mch_id", PayConfigUtil.MCH_ID);

        packageParams.put("time_stamp", String.valueOf(time_stamp));

        packageParams.put("nonce_str", nonce_str);

        packageParams.put("product_id", product_id);

//      packageParams.put("chapterId", chapterId);

//      packageParams.put("price", price);

        String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);//MD5哈希

        packageParams.put("sign", sign);

        //生成参数

        String str = ToUrlParams(packageParams);

        String payurl = "weixin://wxpay/bizpayurl?" + str;

//      logger.info("payurl:"+payurl);

        //生成二维码

        Map  hints=new HashMap();

        // 指定纠错等级 

        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); 

        // 指定编码格式 

        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); 

        hints.put(EncodeHintType.MARGIN, 1);

        try {

            BitMatrix bitMatrix = new MultiFormatWriter().encode(payurl,BarcodeFormat.QR_CODE, defaultWidthAndHeight, defaultWidthAndHeight, hints);

            OutputStream out = response.getOutputStream();

            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);//输出二维码

            out.flush();

            out.close();

        } catch (WriterException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

public String ToUrlParams(SortedMap packageParams){

        //实际可以不排序

        StringBuffer sb = new StringBuffer(); 

        Set es = packageParams.entrySet(); 

        Iterator it = es.iterator(); 

        while (it.hasNext()) { 

            Map.Entry entry = (Map.Entry) it.next(); 

            String k = (String) entry.getKey(); 

            String v = (String) entry.getValue(); 

            if (null != v && !"".equals(v)) { 

                sb.append(k + "=" + v + "&"); 

            } 

        }

        sb.deleteCharAt(sb.length()-1);//删掉最后一个&

        return sb.toString();

    }

扫码时触动此方法,会在手机端显示付款信息

要将此方法的路径配置到回调url里,微信公众平台–>微信支付–>开发配置 


img_7cb898cf7db0bad23d60a98ead78bbe2.png

//微信扫码的时候,触发此方法

    @RequestMapping(value = "Re_notify")

    public void Re_notify(HttpServletRequest request, HttpServletResponse response) throws IOException{

        HttpSession session = request.getSession();

        String chapterId=(String)session.getAttribute("chapterId");

        String chapterName=(String)session.getAttribute("chapterName");

        String price=(String)session.getAttribute("price");

        System.out.println(chapterId+":"+chapterName+":"+price);

        // 读取xml

                InputStream inputStream;

                StringBuffer sb = new StringBuffer();

                inputStream = request.getInputStream();

                String s;

                BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

                while ((s = in.readLine()) != null) {

                    sb.append(s);

                }

                in.close();

                inputStream.close();

                SortedMap packageParams = PayCommonUtil.xmlConvertToMap(sb.toString());

//              logger.info(packageParams);

                // 账号信息

                String key = PayConfigUtil.API_KEY; // key

                String resXml="";//反馈给微信服务器

                // 验签

                if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {

                    //appid openid mch_id is_subscribe nonce_str product_id sign

                    //统一下单

                    String openid = (String)packageParams.get("openid");

                    String product_id = (String)packageParams.get("product_id");

                    //解析product_id,计算价格等

                    String thePricce = product_id.substring(product_id.lastIndexOf("*")+1);

                    String newProductId = product_id.substring(0, product_id.indexOf("*"));

                    String out_trade_no = String.valueOf(System.currentTimeMillis()); // 订单号 

                    String order_price = thePricce; // 价格"1"  注意:价格的单位是分 

                    String body = newProductId;  // 商品名称product_id  这里设置为product_id

                    String attach = "十倍课"; //附加数据

                    String nonce_str0 = PayCommonUtil.getNonce_str();

                    // 获取发起电脑 ip 

                    String spbill_create_ip = PayConfigUtil.CREATE_IP;   

                    String trade_type = "NATIVE";

                    SortedMap unifiedParams = new TreeMap(); 

                    unifiedParams.put("appid", PayConfigUtil.APP_ID); // 必须

                    unifiedParams.put("mch_id", PayConfigUtil.MCH_ID); // 必须

                    unifiedParams.put("out_trade_no", out_trade_no); // 必须

                    unifiedParams.put("product_id", product_id);

                    unifiedParams.put("body", body); // 必须

                    unifiedParams.put("attach", attach);

                    unifiedParams.put("total_fee", order_price);  // 必须

                    unifiedParams.put("nonce_str", nonce_str0);  // 必须

                    unifiedParams.put("spbill_create_ip", spbill_create_ip); // 必须

                    unifiedParams.put("trade_type", trade_type); // 必须 

                    unifiedParams.put("openid", openid); 

                    unifiedParams.put("notify_url", PayConfigUtil.NOTIFY_URL);//异步通知url

                    String sign0 = PayCommonUtil.createSign("UTF-8", unifiedParams,key); 

                    unifiedParams.put("sign", sign0); //签名

                    String requestXML = PayCommonUtil.getRequestXml(unifiedParams); 

//                  logger.info(requestXML);

                    //统一下单接口

                    String rXml = HttpUtil.postData(PayConfigUtil.UFDODER_URL, requestXML); 

                    //统一下单响应

                    SortedMap reParams = PayCommonUtil.xmlConvertToMap(rXml);

//                  logger.info(reParams);

                    //验签

                    if (PayCommonUtil.isTenpaySign("UTF-8", reParams, key)) {

                        // 统一下单返回的参数

                        String prepay_id = (String)reParams.get("prepay_id");//交易会话标识  2小时内有效

                        String nonce_str1 = PayCommonUtil.getNonce_str();

                        SortedMap resParams = new TreeMap(); 

                        resParams.put("return_code", "SUCCESS"); // 必须

                        resParams.put("return_msg", "OK");

                        resParams.put("appid", PayConfigUtil.APP_ID); // 必须

                        resParams.put("mch_id", PayConfigUtil.MCH_ID);

                        resParams.put("nonce_str", nonce_str1); // 必须

                        resParams.put("prepay_id", prepay_id); // 必须

                        resParams.put("result_code", "SUCCESS"); // 必须

                        resParams.put("err_code_des", "OK");

                        String sign1 = PayCommonUtil.createSign("UTF-8", resParams,key); 

                        resParams.put("sign", sign1); //签名

                        resXml = PayCommonUtil.getRequestXml(resParams);

//                      logger.info(resXml);

                    }else{

//                      logger.info("签名验证错误");

                        resXml = "" + "" 

                                + "" + " ";

                    }

                }else{

//                  logger.info("签名验证错误");

                    resXml = "" + "" 

                            + "" + " ";

                }

                //------------------------------ 

                //处理业务完毕 

                //------------------------------ 

                BufferedOutputStream out = new BufferedOutputStream( 

                        response.getOutputStream()); 

                out.write(resXml.getBytes()); 

                out.flush(); 

                out.close(); 

    }

微信支付成功时访问的方法

密码错误等未支付成功的情况下,不会访问。 

此路径是PayConfigUtil中配置的

int wxPayType = 0;

    //微信扫码支付回调

    @RequestMapping(value = "Notify1")

    public void Notify1(HttpServletRequest request, HttpServletResponse response) throws IOException{

        InputStream inputStream;

        StringBuffer sb = new StringBuffer();

        inputStream = request.getInputStream();

        String s;

        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

        while ((s = in.readLine()) != null) {

            sb.append(s);

        }

        in.close();

        inputStream.close();

        SortedMap packageParams = PayCommonUtil.xmlConvertToMap(sb.toString());

//      logger.info(packageParams);

        // 账号信息

        String key = PayConfigUtil.API_KEY; // key

        String resXml = ""; // 反馈给微信服务器

        // 判断签名是否正确

        if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {

            // ------------------------------

            // 处理业务开始

            // ------------------------------

            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {

                // 这里是支付成功

                // 执行自己的业务逻辑

                String mch_id = (String) packageParams.get("mch_id");

                String openid = (String) packageParams.get("openid");

                String is_subscribe = (String) packageParams.get("is_subscribe");

                String out_trade_no = (String) packageParams.get("out_trade_no");

                String total_fee = (String) packageParams.get("total_fee");

将用于标记是否成功的全局变量wxPayType设置为1,ajax轮回时,可以获取到其变化,从而进行页面跳转

                wxPayType=1;

                System.out.println("33333333333333333333333333333:"+wxPayType);

//          "支付成功"

// 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.

                resXml = "" + ""

                        + "" + " ";

            } else {

//              logger.info("支付失败,错误信息:" + packageParams.get("err_code"));

                resXml = "" + ""

                        + "" + " ";

            }

        } else {

//          logger.info("签名验证错误");

            resXml = "" + "" 

                    + "" + " ";

        }

        // ------------------------------

        // 处理业务完毕

        // ------------------------------

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());

        out.write(resXml.getBytes());

        out.flush();

        out.close();

    }

ajax不停轮回,判断是否登录成功的方法

@RequestMapping(value = "panduanPay")

        @ResponseBody

        public Map panduanPay(HttpServletRequest request) throws IOException{

            Map map = new HashMap();

            try {

                Thread.sleep(500);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            //给页面返回wxPayType值,成功是返回的是1;还未支付成功,返回的是初始值0

            map.put("wxPayType",wxPayType);

            return map;

        }

成功后页面跳转的方法

//购买成功,存入购买表中

    @RequestMapping(value="gouMai")

    @ResponseBody

    public ModelAndView gouMai(HttpServletRequest req,String a,String urlName,String couName,ModelMap map){

        ModelAndView mav = new ModelAndView();

        Map mapp1 = new HashMap();

//      SysUserTab login_user = sysuserService.getSysUserById(userId);

        HttpSession session = req.getSession();

        SysUserTab login_user1 = (SysUserTab) session.getAttribute("login_user");

        String userId = login_user1.getUserId();

//      session.setAttribute("login_user", login_user);

        String chapterId = (String) session.getAttribute("chapterId");

        mapp1.put("userId", userId);

        mapp1.put("chapterId", chapterId);

        int num = sysBuyService.getBuyCount(mapp1);

        if(num==0){

            mapp1.put("buyId", UUID.randomUUID().toString().replace("-", ""));

            sysBuyService.insertBuy(mapp1);

        }

Java高架构师、分布式架构、高可扩展、高性能、高并发、性能优化、Spring boot、Redis、ActiveMQ、Nginx、Mycat、Netty、Jvm大型分布式项目实战学习架构师视频免费学习加群:835638062 点击链接加入群聊【Java高级架构】:https://jq.qq.com/?_wv=1027&k=5S3kL3v

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34161029/article/details/89590546

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文