spring boot集成微信支付

spring boot集成微信支付


微信(坑货没有测试版)  

参数可以看微信开放平台提供的api接口文档 ---------话不多说、开始干

1. 在项目中加入jar包

<!--微信支付 SDk-->
        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>

 

2.原理与支付宝差不多,配置微信支付环境 这里我的公共参数写在impl实现类中

    //应用id
    private String app_id ="+++++++++++++++";
    //商户号id
    private String mch_id ="++++++++++++++";
    //密钥
    private String key ="+++++++++++++++++++++";
    //#APP和网页支付提交用户端ip, Native支付填调用微信支付API的机器IP, 即:服务器ip地址
    private String spbtll_create_ip ="127.0.0.1";
    //支付回调地址  
    //private String notify_url ="https://++++++++++++++++";
    //测试使用的支付回调地址
    private String notify_url ="http://+++++++++++++++++++++++++";
    //支付方式,取值如下:JSAPI,NATIVE,APP
    private String trade_type ="NATIVE";
    //微信支付 - 统一下单地址
    private String placeanoroer_url ="https://api.mch.weixin.qq.com/pay/unifiedorder";

3、开始写service接口吧

   //请求微信api
    Map<String,String> createNative(Integer id);

    //微信api回调
    String notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception;

    //查询支付状态
    Map<String,String> queryStatus(Integer id);

4、实现service提供的createNative()方法<<注意金额 、微信是以分为单位>><<这里是用的变动订单号、不然当扫码未支付、那么这个订单再次扫码时便支付不了了、死坑>>>

     这里请求需要与前端沟通,是否需要进行转码、如果不需要就直接将接收到的微信二维码连接返回给前端处理/如果需要就进行Base64的转码处理

  //请求微信api
    @Override
    public Map<String,String> createNative(Integer id) {
        try {
            QueryWrapper<SOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("id",id);
            SOrder order = orderMapper.selectList(wrapper).get(0);

            String num = order.getTotalPrice().multiply(BigDecimal.valueOf(100)).setScale(0).toString();
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("appid",app_id);
            paramMap.put("mch_id",mch_id);
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
            paramMap.put("body","++++++");

            String tradeNumber = order.getOId().substring(0,16);
            StringBuffer sb = new StringBuffer();
            int random=(int)((Math.random()*9+1)*100000);
            sb.append(tradeNumber);
            sb.append(random);

            SOrder sOrder = new SOrder();
            sOrder.setOId(sb.toString());
            QueryWrapper<SOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("id",id);
            orderMapper.update(sOrder,queryWrapper);
            SOrdertype orderType = new SOrdertype();
            orderType.setOId(sb.toString());
            QueryWrapper<SOrdertype> objectQueryWrapper = new QueryWrapper<>();
            objectQueryWrapper.eq("o_id",order.getOId());
            orderTypeMapper.update(orderType,objectQueryWrapper);


            paramMap.put("out_trade_no", sb.toString());

            paramMap.put("total_fee",num);
            paramMap.put("spbill_create_ip",spbtll_create_ip);
            paramMap.put("notify_url",notify_url);
            paramMap.put("trade_type",trade_type);
            String xmlparameters = WXPayUtil.generateSignedXml(paramMap,key);//签名
            String ulr = placeanoroer_url;
            HttpClientUtil httpClient = new HttpClientUtil(ulr);
            httpClient.setHttps(true);
            log.info("++我的请求信息:++\n"+xmlparameters);
            httpClient.setXmlParam(xmlparameters);

            httpClient.post();

            String result = httpClient.getContent();
            log.info("++返回的xml数据++\n"+result);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            log.info("++返回的xml转成map数据++"+resultMap);

            //生成微信二维码
            String codeUrl = resultMap.get("code_url"); // 二维码内容
            int width = 200; // 二维码图片宽度
            int height = 200; // 二维码图片高度
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 内容所使用字符集编码
            BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl,BarcodeFormat.QR_CODE, width, height, hints);
            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
            String base64 = QrCodeUtils.getBase64(bufferedImage);
            HashMap<String , String> map = new HashMap<>();
            map.put("base64",base64);
            map.put("totalFee", String.valueOf(order.getTotalPrice()));

            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

5.实现notifyUrl回调方法(处理完业务一定要返回微信<<

<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>

>>)否则微信会一直调用改接口

 //微信api回调
    @Override
    public String notifyUrl(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //获取网络输入流
        ServletInputStream inputStream = request.getInputStream();
        //定义缓存
        byte[] buffer = new byte[1024];
        //创建OutputStream输入文件
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //定义数组长度
        int len = 0;
        while ((len = inputStream.read(buffer)) != -1){
            baos.write(buffer,0,len);
        }
        //取得微信回调结果
        byte[] bytes = baos.toByteArray();
        String xmlResult = new String(bytes,"utf-8");
        //将取得的微信回调结果转成map
        Map<String, String> resultMap = WXPayUtil.xmlToMap(xmlResult);
        log.info("微信回调结果转成map"+resultMap);
        //获取通信标识
        String returnCode = resultMap.get("return_code");
        //判断是否支付是否回调
        if (returnCode.equals("SUCCESS")){
            //获取业务结果
            String resultCode = resultMap.get("result_code");
            //获取订单号
            String tradeNumber = resultMap.get("out_trade_no");
            //获取微信流水号
            String transactionId = resultMap.get("transaction_id");
            //获取交易完成时间
            String timeEnd = resultMap.get("time_end");
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = format.parse(timeEnd);
            if (resultCode.equals("SUCCESS")){//SUCCESS 支付成功
                SOrder order = new SOrder();
                order.setTradeNumber(transactionId); //微信流水号
                order.setOId(tradeNumber);//订单号
                order.setOrderStatus(1);//订单状态标识 (0:待支付;1:已支付;2:已取消;3:已退款)
                order.setPaymentTime(date);
                order.setPaymentMethod("微信");
                QueryWrapper<SOrder> wrapper = new QueryWrapper<>();
                wrapper.eq("o_id",tradeNumber);
                orderMapper.update(order,wrapper);

                SOrdertype sOrdertype = new SOrdertype();
                sOrdertype.setTradeNumber(transactionId);
                QueryWrapper<SOrdertype> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("o_id",order.getOId());
                orderTypeMapper.update(sOrdertype,queryWrapper);
                QueryWrapper<SOrder> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("o_id",tradeNumber);
                wrapper1.last("offset  0 rows fetch next 1 rows only");
                wrapper1.orderByDesc("id");
                SOrder sOrder = orderMapper.selectOne(wrapper1);
                HashMap<Object, Object> map = new HashMap<>();
                map.put("type","OrderPaymentSuccess");//{ type =”SubmitOrder", value = order.o_ id,
                map.put("value",sOrder.getOId());
                map.put("uid",order.getUid());
                String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                response.setContentType("text/xml");
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(result.getBytes());
                out.flush();
                out.close();
                return result;
            }else {//交易失败
                String result = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[交易失败!!]]></return_msg></xml>";
                response.setContentType("text/xml");
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
                out.write(result.getBytes());
                out.flush();
                out.close();
                return result;
            }
        }else {//回调信息错误
            String result = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[回调信息错误!!]]></return_msg></xml>";
            response.setContentType("text/xml");
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(result.getBytes());
            out.flush();
            out.close();
            return result;
        }
    }

6.实现查询支付状态queryStatus接口

/**
     * 查询支付状态
     * */
    @Override
    public Map<String,String> queryStatus(Integer id) {
        Map<String,String> map = new HashMap<>();
        try {
            QueryWrapper<SOrder> wrapper = new QueryWrapper<>();
            wrapper.eq("id",id);
            SOrder order = orderMapper.selectList(wrapper).get(0);
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("appid",app_id);
            paramMap.put("mch_id",mch_id);
            paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

            paramMap.put("out_trade_no",order.getOId());

            String xmlparameters = WXPayUtil.generateSignedXml(paramMap,key);//签名
            String ulr = "https://api.mch.weixin.qq.com/pay/orderquery";
            HttpClientUtil httpClient = new HttpClientUtil(ulr);
            httpClient.setHttps(true);
            log.info("++查询支付状态的请求信息:++\n"+xmlparameters);
            httpClient.setXmlParam(xmlparameters);
            httpClient.post();
            String result = httpClient.getContent();
            log.info("++查询支付状态的返回的xml数据++\n"+result);
            Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
            log.info("++查询支付状态的返回的xml转成map数据++"+resultMap);
            if (resultMap.get("trade_state").equals("SUCCESS")){
                int sum = Integer.parseInt(resultMap.get("total_fee"));
                BigDecimal price = BigDecimal.valueOf(sum).divide(BigDecimal.valueOf(100));
                map.put("price", String.valueOf(price));
                map.put("tradeNumber",resultMap.get("out_trade_no"));
                map.put("time_end",resultMap.get("time_end"));
                map.put("trade_state",resultMap.get("trade_state"));
                map.put("trade_state_desc",resultMap.get("trade_state_desc"));

                return map;
            }
            map.put("tradeNumber",resultMap.get("out_trade_no"));
            map.put("trade_state",resultMap.get("trade_state"));
            map.put("trade_state_desc",resultMap.get("trade_state_desc"));
            return map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

7.controller层

 @Autowired
    private WeiXinPayService weiXinPayService;
    //支付
    @RequiresAuthentication
    @RequestMapping(value = "/pay",method = RequestMethod.POST)
    public ResultVo createNative(Integer id){
        Map<String,String> result= weiXinPayService.createNative(id);
        System.out.println("result="+result);
        log.info("{=========================》》》》》》》微信支付请求信息}"+result);
        return ResultVoUtil.success(result);
    }
    //微信api回调
    @RequestMapping("/notifyUrl")
    public String notifyUrl(HttpServletRequest request, HttpServletResponse response)throws Exception{
        //log.info("{====================================》》》》》微信支付回调信息}"+weiXinPayService.notifyUrl(request,response));
        return weiXinPayService.notifyUrl(request,response);
    }
    //查询支付状态
    @RequestMapping(value = "/status/query",method = RequestMethod.GET)
    public ResultVo queryStatus(Integer id){
        Map<String,String> result= weiXinPayService.queryStatus(id);
        log.info("{==========================》》》》》》微信支付状态查询}"+result);
        if (result.get("trade_state_desc").equals("支付成功")){ //支付成功
            return ResultVoUtil.success(result,"true");
        }else if (result.get("trade_state_desc").equals("未支付")){//未支付
            return ResultVoUtil.success(result,"false");
        }else if (result.get("trade_state_desc").equals("用户支付中")){//用户支付中
            return ResultVoUtil.success(result,"false");
        }
        return ResultVoUtil.success(null,"false");
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值