Java微信支付—app篇 基于springboot

一:简介

开发之前我们需要做一些准备工作,如下:
首先我们需要拿到微信的商户号,appid,API密钥等信息。在微信支付自己账号下获取。
之后我们查看微信支付统一下单的api接口文档。
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

话不啰嗦,接下来开始实战吧

二:集成步骤

1.引入微信支付SDK依赖:

		<dependency>
		  <groupId>com.github.wxpay</groupId>
		  <artifactId>wxpay-sdk</artifactId>
		  <version>0.0.3</version>
		</dependency>

2.微信app支付参数配置:

public class ConfigUtil {
    /**
     * 服务号相关信息
     */
    public final static String APPID = "XXXXX";//服务号的应用号
    public final static String MCH_ID = "XXXXXX";//商户号
    public final static String API_KEY = "XXXXX";//API密钥
    public final static String SIGN_TYPE = "MD5";//签名加密方式D

    public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";//请求下单的http
}

3.微信支付接口代码

	/**
     * 微信支付
     * @return
     */
    @PostMapping("/weChatPay")
    public HttpResult weChatPay(@RequestBody SysOrder order) throws Exception {
        log.info(">>>>>>>>>>>>>微信支付开始>>>>>>>>>>>>>>>");
        Map<String, String> parameters = buildWeChatPayOrderMap(sysOrder);
        //设置签名--微信SKD提供了获取签名的方法
        String sign=WXPayUtil.generateSignature(parameters,ConfigUtil.API_KEY);
        parameters.put("sign", sign);
        //封装请求参数结束 将map转xml
        String requestXML =  new String(WXPayUtil.mapToXml(parameters).getBytes("utf-8"), "iso8859-1");
        //调用统一下单接口--见标题4
        String result = PayCommonUtil.httpPostXML(ConfigUtil.UNIFIED_ORDER_URL, requestXML);   /**统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay**/
        String prepay_id = "";// 预支付id
        if (result.indexOf("SUCCESS") != -1) {//判断统一下单是否成功
            Map<String, String> map = WXPayUtil.xmlToMap(result);
            prepay_id = (String) map.get("prepay_id");
        }
    
        Map<String, String> payMap = new HashMap<String, String>();
        payMap.put("appid", ConfigUtil.APPID);
        payMap.put("partnerid", ConfigUtil.MCH_ID);
        payMap.put("prepayid",  prepay_id);//预支付id
        payMap.put("noncestr", WXPayUtil.generateNonceStr());
        payMap.put("package", "Sign=WXPay");
        payMap.put("timestamp", String.valueOf(System.currentTimeMillis()/1000).substring(0, 10));
        String paySign = WXPayUtil.generateSignature(payMap, ConfigUtil.API_KEY);
        payMap.put("sign", paySign);
        //将获取到的订单信息给到APP端
        JSONObject JSONObj = JSONObject.parseObject(JSON.toJSONString(payMap));
        return HttpResult.ok(JSONObj);
    }




	/**
     * 构造微信支付订单参数列表
     */
    private Map<String, String> buildWeChatPayOrderMap(SysOrder sysOrder) {
        BigDecimal amount=sysOrder.getAmountPayable();//订单金额
        amount = amount.multiply(new BigDecimal(100));// 单位分
        amount = amount.setScale(0, RoundingMode.DOWN);//取整
        Map<String, String> parameters = new HashMap<String, String>();
        parameters.put("appid", ConfigUtil.APPID);
        parameters.put("mch_id", ConfigUtil.MCH_ID);
        parameters.put("nonce_str", WXPayUtil.generateNonceStr());//32位以内的随机数
        parameters.put("body", "测试购买内容");//购买内容
        parameters.put("out_trade_no",XXX); //订单id
        parameters.put("fee_type", "CNY");
        //	微信中金额 1=0.01元。所以计算金额记得换算  X*100
        parameters.put("total_fee",String.valueOf(amount));//支付金额单位为【分】*100
        parameters.put("spbill_create_ip", "127.0.0.1");
        parameters.put("notify_url", "http://XXXXXXX-------/weCahtComback");//回调接口地址
        parameters.put("trade_type", "APP");
        return parameters;
    }

4.统一下单请求(标题4)

public class PayCommonUtil {
    /**
     * post请求并得到返回结果
     * @param requestUrl
     * @param xml
     * @return
     */
    public static String httpPostXML(String requestUrl, String xml) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(requestUrl);
        StringEntity postEntity = new StringEntity(xml, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml;charset=UTF-8");
        httpPost.setEntity(postEntity);
        try {
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        } catch (Exception var7) {
        }
        return "";
    } 
}

注:注意HttpResponse 引入的包是 package org.apache.http;下面的

5.微信回调接口

@RequestMapping("/weCahtComback")
    public void wxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream)request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while((line = br.readLine()) != null){
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        Map parameters = WXPayUtil.xmlToMap(notityXml);
        String returnCode = (String) parameters.get("return_code");
        if("SUCCESS".equals(returnCode)){
            //验证签名是否正确(根据订单信息重新获取签名)
            String sign=WXPayUtil.generateSignature(parameters,ConfigUtil.API_KEY);

            //根据微信官网的介绍,此处不仅对回调的参数进行验签,还需要对返回的金额与系统订单的金额进行比对等
            if(sign.equals(parameters.get("sign"))){
                // 这里是支付成功
                //执行自己的业务逻辑
                String out_trade_no = (String) parameters.get("out_trade_no"); //订单号id
                String transaction_id = (String) parameters.get("transaction_id"); //微信支付订单号 
                    }
                }

                /**回调逻辑代码编写*/
                //通知微信服务器已经支付成功
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                System.out.println("微信支付回调失败!签名不一致");
            }
        }else{
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        System.out.println(resXml);
        System.out.println("微信支付回调数据结束");

        BufferedOutputStream out = new BufferedOutputStream(
                response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

如果觉得笔者写的文章对你有些用处,麻烦点个赞让我知道一下~哈哈,谢谢!!有问题同学也可以留言,大家一起学习~~

展示下支付页面
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
注意要点: 1,Topay里面的参数要填好:appid,appsecret,mch_id,partnerkey,spbill_create_ip 2,openid 需要微信授权获取到 3,每次支付orderNo要不同 openid参考实例: 1,授权链接地址:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxba3445566677&redirect_uri=http://www.acc.com/weixin/pay/paydispatcher&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect 2,转向处理地址:通过第一个链接微信会把code传过来,之前参数获取就行 @RequestMapping(value = "/paydispatcher", method = { RequestMethod.GET }) public void payDispatcher(HttpServletRequest request, HttpServletResponse response) throws Exception { String code = request.getParameter("code"); String msg=""; if(code==null||code.equals("")){ msg="获取微信Code失败!"; request.setAttribute("msg" ,msg); request.getRequestDispatcher("/jsp/login.jsp").forward(request,response); }else{ WeixinUtil util = new WeixinUtil(); UserAccessToken token = (UserAccessToken) request.getSession().getAttribute("UserAccessToken"); if(null==token){ token = util.getAccessToken3(Constants.APPID, Constants.SECRET,code); request.getSession().setAttribute("UserAccessToken",token); } request.setAttribute("openid", token.getOpenid()); request.setAttribute("accessToken", token.getAccessToken()); request.setAttribute("refreshToken", token.getRefreshToken()); request.setAttribute("expiresIn", token.getExpiresIn()); request.getRequestDispatcher("/pay/index.jsp").forward(request,response); } } // 获取用户openid accesstoken public static UserAccessToken getAccessToken3(String appid , String appsecret,String code) { UserAccessToken accessToken = null; String requestUrl = Constants.GET_OPENID_ACCESSTOKEN_URL.replace("APPID" , appid).replace("APPSECRET" , appsecret).replace("CODE" , code); String json = httpRequest(requestUrl , "GET" , null); JSONObject jsonObject = JSONObject.fromObject(json); // 如果请求成功 if (null != jsonObject) { try { accessToken = new UserAccessToken(); accessToken.setAccessToken(jsonObject.getString("access_token")); accessToken.setRefreshToken(jsonObject.getString("refresh_token")); accessToken.setExpiresIn(jsonObject.getInt("expires_in")); accessToken.setOpenid(jsonObject.getString("openid")); accessToken.setScope(jsonObject.getString("scope")); } catch (Exception e) { accessToken = null; // 获取token失败 System.out.println("获取token失败 errcode:{} errmsg:{}"); } } return accessToken; }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值