Java微信扫描支付模式二Demo ,整合官网直接运行版本

概述

场景介绍 用户使用微信“扫一扫”扫描二维码后,获取商品支付信息,引导用户完成支付。

详细

一、相关配置

QQ图片20180826105048.png

Demo上都有官网的默认值,不需要修改直接使用

支付扫描模式二,流程图

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5

SDK与DEMO下载

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

二、目录结构

QQ图片20180823103507.png

三、准备工作

(1)设置热部署

作为程序员都知道,每次修改后台代码都要重启项目,工作效率非常慢,所以我们要加快效率。

pom.xml

<dependencies>
    <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-devtools</artifactId>
       <optional>true</optional>
    </dependency>
</dependencies>   

<build>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <configuration>
            <fork>true</fork>
         </configuration>
      </plugin>
   </plugins>
</build>

application.properties

#禁止thymeleaf缓存(建议:开发环境设置为false,生成环境设置为true)
spring.thymeleaf.cache=false

开发工具是:idea

设置以下两项(第一项如已设置直接设置第二项)

  1) “File” -> “Settings” -> “Build,Execution,Deplyment” -> “Compiler”,选中打勾 “Build project automatically” 。

  2) 组合键:“Shift+Ctrl+Alt+/” ,选择 “Registry” ,选中打勾 “compiler.automake.allow.when.app.running”

相关链接:

https://www.cnblogs.com/jiangbei/p/8439394.html

https://blog.csdn.net/weixin_42884584/article/details/81561987

(2)内网穿透工具

让外网能直接访问,你本地的服务,场景用于,接口调试,支付方面等等。

为了大家找了一个,免费配置简单的。绝对不是卖广告,之前用过花生壳,麻烦到要死坑哇~,现在的所有穿透都要身份证登记,很正常国家出了对应的法规。

下载地址:https://natapp.cn/#download

配置和使用说明:https://blog.csdn.net/kingrome2017/article/details/77989442

四、功能讲解

(1)访问首页

打开WxPayController.java

/**
 * 二维码首页
 */
@RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String wxPayList(Model model){
    //商户订单号
    model.addAttribute("outTradeNo",WxUtil.mchOrderNo());
    return "/wxPayList";
}

我们和穿透工具连在一起使用

SpringBoot 默认端口号为:8080,穿透工具映射端口设置为:8080

双击,natapp.exe 执行

image.png

 

127.0.0:8080 <=> http://9xnrh8.natappfree.cc

 

image.pngimage.png

修改,application.properties

 

(划重点,支付成功后回调本地服务,修改后记得重启服务)

#统一下单-通知链接
wx.unifiedorder.notifyUrl=http://9xnrh8.natappfree.cc/wxPay/unifiedorderNotify

(2)生成二维码

从页面看到,有订单流水号和支付金额,0.01 代表一分钱。支付金额可以修改的,点击'生成二维码'按钮,然后把订单流水号和支付金额传到后台。

控制类:

final private String signType = WxConstants.SING_MD5;
/**
 * 统一下单-生成二维码
 */
@RequestMapping(value = {"/wxPay/payUrl"})
public void payUrl(HttpServletRequest request, HttpServletResponse response,
                   @RequestParam(value = "totalFee")Double totalFee,
                   @RequestParam(value = "outTradeNo")String outTradeNo) throws Exception{
    WxUtil.writerPayImage(response,wxMenuService.wxPayUrl(totalFee,outTradeNo,signType));
}

实现类:

@Override
public String wxPayUrl(Double totalFee,String outTradeNo,String signType) throws Exception {
    HashMap<String, String> data = new HashMap<String, String>();
    //公众账号ID
    data.put("appid", WxConfig.appID);
    //商户号
    data.put("mch_id", WxConfig.mchID);
    //随机字符串
    data.put("nonce_str", WxUtil.getNonceStr());
    //商品描述
    data.put("body","测试支付");
    //商户订单号
    data.put("out_trade_no",outTradeNo);
    //标价币种
    data.put("fee_type","CNY");
    //标价金额
    data.put("total_fee",String.valueOf(Math.round(totalFee * 100)));
    //用户的IP
    data.put("spbill_create_ip","123.12.12.123");
    //通知地址
    data.put("notify_url",WxConfig.unifiedorderNotifyUrl);
    //交易类型
    data.put("trade_type","NATIVE");
    //签名类型
    data.put("sign_type",signType);
    //签名
    data.put("sign",WxUtil.getSignature(data, WxConfig.key,signType));

    String requestXML = WxUtil.mapToXml(data);
    String reponseString = HttpsClient.httpsRequestReturnString(WxConstants.PAY_UNIFIEDORDER,HttpsClient.METHOD_POST,requestXML);
    Map<String,String> resultMap = WxUtil.processResponseXml(reponseString,signType);
    if(resultMap.get(WxConstants.RETURN_CODE).equals("SUCCESS")){
        return resultMap.get("code_url");
    }
    return null;
}

最终返回一个,二维码链接 → 转成二维码图片

/**
 * 生成支付二维码
 * @param response 响应
 * @param contents url链接
 * @throws Exception
 */
public static void writerPayImage(HttpServletResponse response, String contents) throws Exception{
   ServletOutputStream out = response.getOutputStream();
   try {
      Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType,Object>();
      hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
      hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
      hints.put(EncodeHintType.MARGIN, 0);
      BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,300,300,hints);
      MatrixToImageWriter.writeToStream(bitMatrix,"jpg",out);
   }catch (Exception e){
      throw new Exception("生成二维码失败!");
   }finally {
      if(out != null){
         out.flush();
         out.close();
      }
   }
}

 

image.png

下面的请求是定时器,检查是否已支付,本来我想用socket。

(3)支付

 

QQ图片20180823150115.jpg

QQ图片20180823150123.jpg

(4)支付完毕

QQ图片20180823151809.png

(5)回调接口

收到微信支付结果通知后,请严格按照示例返回参数给微信支付

/**
 * 统一下单-通知链接
 */
@RequestMapping(value = {"/wxPay/unifiedorderNotify"})
public void unifiedorderNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{

    //商户订单号
    String outTradeNo = null;
    String xmlContent = "<xml>" +
            "<return_code><![CDATA[FAIL]]></return_code>" +
            "<return_msg><![CDATA[签名失败]]></return_msg>" +
            "</xml>";

    try{
        String requstXml = WxUtil.getStreamString(request.getInputStream());
        System.out.println("requstXml : " + requstXml);
        Map<String,String> map = WxUtil.xmlToMap(requstXml);
        String returnCode= map.get(WxConstants.RETURN_CODE);
        //校验一下
        if(StringUtils.isNotBlank(returnCode) && StringUtils.equals(returnCode,"SUCCESS")  &&  WxUtil.isSignatureValid(map, WxConfig.key,signType)){
            //商户订单号
            outTradeNo = map.get("out_trade_no");
            System.out.println("outTradeNo : "+ outTradeNo);
            //微信支付订单号
            String transactionId = map.get("transaction_id");
            System.out.println("transactionId : "+ transactionId);
            //支付完成时间
            SimpleDateFormat payFormat= new SimpleDateFormat("yyyyMMddHHmmss");
            Date payDate = payFormat.parse(map.get("time_end"));

            SimpleDateFormat systemFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("支付时间:" + systemFormat.format(payDate));
            //临时缓存
            WxConfig.setPayMap(outTradeNo,"SUCCESS");
            xmlContent = "<xml>" +
                    "<return_code><![CDATA[SUCCESS]]></return_code>" +
                    "<return_msg><![CDATA[OK]]></return_msg>" +
                    "</xml>";
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    WxUtil.responsePrint(response,xmlContent);
}

QQ图片20180823161109.png

更多的信息,请看官网

官网相关链接:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7&index=8

(6)微信支付,关于XML解析存在的安全问题指引

代码已修改

image.png

更多的信息,请看官网

官网相关链接:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5

(7)前端页面

<html>
<head >
    <title>微信支付二维码生产</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="/js/jquery/jquery.timers-1.2.js"></script>
    <script type='text/javascript'>

        $(function () {
            getOutTradeNo();

        });

        //生成二维码
        function save(){
            var outTradeNo = $("#outTradeNo").val();
            $("#payImg").attr("src",'/wxPay/payUrl'+"?totalFee="+ $("#totalFee").val()+"&outTradeNo=" + outTradeNo);

            $('body').everyTime('2s','payStatusTimer',function(){
                $.ajax({
                    type : "POST",
                    url : '/wxPay/payStatus?outTradeNo='+ outTradeNo +"&random=" + new Date().getTime(),
                    contentType:"application/json",
                    dataType : "json",
                    async : "false",
                    success : function(json) {
                        if(json != null && json.status == 0){
                            alert("支付成功!");
                            $('body').stopTime ('payStatusTimer');
                            return false;
                        }
                    },
                    error:function(XMLHttpRequest,textStatus,errorThrown){
                        alert("服务器错误!状态码:"+json.status);
                        // 状态
                        console.log(json.readyState);
                        // 错误信息
                        console.log(json.statusText);
                        return false;
                    }
                })
            });



        }

        //获取流水号
        function getOutTradeNo(){
            $.ajax({
                type : "POST",
                url : '/wxPay/outTradeNo',
                success : function(json) {
                    if(json != null){
                        $("h3").html(json);
                        $("#outTradeNo").val(json);
                    }else{
                        alert("获取流水号失败!");
                    }
                    return false;
                },
                error:function(XMLHttpRequest,textStatus,errorThrown){
                    alert("服务器错误!状态码:"+XMLHttpRequest.status);
                    // 状态
                    console.log(XMLHttpRequest.readyState);
                    // 错误信息
                    console.log(textStatus);
                    return false;
                }
            });
        }



    </script>
</head>
<body>
<p>订单流水号:<h3></h3></p>
支付金额:<input id="totalFee"    type="text"   value="0.01"/>
<button type="button" οnclick="save();">生成二维码</button>
<input id="outTradeNo"  type="hidden" value="${outTradeNo}"/>
&nbsp;&nbsp;<img  id="payImg" width="300" height="300"  >

</body>
</html>

启动一个定时器,每个2秒去扫描是否已经支付~

因为相关配置,我是从官网下载的,所以支付后还有退款功能(退款要等很多天,请耐心等待),是不是很神奇~

QQ图片20180826105250.jpg

还有微信登录,自定义微信公众号菜单创建-修改-删除功能(前台-数据库保存),微信公众号接受、回复信息Demo

但是,没有官网例子直接运行的,很多地方不能截图,后面我想想怎么做吧~

谢谢大家观看~

 

 

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java微信App支付demo是一个简单的示例程序,展示了如何使用Java语言进行微信App支付的集成。在这个示例中,我们可以学习如何通过微信支付API实现App支付并处理支付结果。 首先,在这个demo程序中,我们需要将微信开放平台提供的SDK库引入到项目中,并创建一个微信支付类。这个类包含了配置微信支付的必要参数,如appID、商户号、API密钥等等。我们还需要创建一个支付请求类,在这个请求类中我们需要设置支付参数,如订单号、金额、商品名称等等。 在集成过程中,我们需要保证我们的应用通过HTTPS进行通信,以保证数据传输的安全性。我们还需要在支付请求完成后,将相关数据发送到微信支付服务器,并处理微信支付返回的支付结果。这部分的处理逻辑包括支付结果验证、异步通知回调等等。 值得注意的是,在Java中使用微信App支付时,我们需要注意线程安全性的问题。为了避免这个问题,我们可以考虑使用单例模式或将支付所需的操作封装成异步任务等方式来确保数据的安全性和正确性。 在完成整个集成过程后,我们就可以通过启动一个简单的应用,使用集成的微信支付功能完成购买流程。Java微信App支付demo给我们提供了一个很好的示例,来学习如何使用Java语言进行微信支付集成。同时,通过这个demo我们还能够了解微信支付的相关知识,并从中掌握Java编程语言的技巧和实践。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值