微信支付-退款操作(JAVA版 Spring Cloud Spring Boot) 基于Linux系统

本demo基于微信扫码支付退款

官方地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_4

   /**
    *
    * @author hubl
    * @date 2020/1/14  
    * @param * @param json 1 退款信息
    * @return com.qiang.base.page.JsonResult
    */  
public JsonResult refund(JSONObject json) throws Exception {
        Integer total_fee = json.getBigDecimal("total_fee").multiply(new BigDecimal("100")).setScale(2).intValue();
        Integer refund_fee = json.getBigDecimal("refund_fee").multiply(new BigDecimal("100")).setScale(2).intValue();
        HashMap<String, Object> map = new HashMap<>();
        String appid = WxForm.appid;
        String mch_id = WxForm.mch_id;
        String nonce_str = WxUtils.createNonceStr();
        String transaction_id = json.getString("transaction_id");
        String out_refund_no = UtilUuId.get18UUID();
        map.put("appid", appid);
        map.put("mch_id", mch_id);
        map.put("nonce_str", nonce_str);
        map.put("sign_type", "MD5");
        map.put("transaction_id", transaction_id);
        map.put("out_refund_no",out_refund_no);
        map.put("total_fee", total_fee.toString());
        map.put("refund_fee", refund_fee.toString());
        String stringA = WxUtils.formatBizQueryParaMap(map, false);//对参数按照key=value的格式,并按照参数名ASCII字典序排序
        System.out.println(stringA);
        String stringSignTemp = stringA + "&key=" + WxForm.key;//拼接API密钥
        String sign = MdFive.MD5(stringSignTemp).toUpperCase();
        System.out.println(sign);

        String xml = "<xml>" +
                "<appid>" + appid + "</appid>" +
                "<mch_id>" + mch_id + "</mch_id>" +
                "<nonce_str>" + nonce_str + "</nonce_str>" +
                "<sign_type>MD5</sign_type>" +
                "<transaction_id>"+transaction_id+"</transaction_id>"+
                "<out_refund_no>"+out_refund_no+"</out_refund_no>"+
                "<total_fee>"+total_fee+"</total_fee>"+
                "<refund_fee>"+refund_fee+"</refund_fee>"+
                "<sign>" + sign + "</sign>" +
                "</xml>";

        System.out.println(xml);
        String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";//微信统一下单接口
        try {
            //预下单 获取接口地址
            Map map1 = WebUtils.doRefund(mch_id,createOrderURL, xml);//注意了退款.p12证书在这里面配置,官方文档没有怎么详细说明,所以很多同学很头大。
            String return_code = (String) map1.get("return_code");
            String return_msg = (String) map1.get("return_msg");
            if ("SUCCESS".equals(return_code) && "OK".equals(return_msg)) {
                return JsonResult.ok("success").put("out_refund_no", out_refund_no);
            } else {
                System.out.println(JSONObject.toJSONString(map));
                return JsonResult.error("统一退单接口出错");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonResult.error("统一退单接口出错");
        }
    }

退款逻辑代码

  /**
     *
     * @param mchId 商户ID
     * @param url 请求URL
     * @param data 退款参数
     * @return
     * @throws Exception
     */
public static Map doRefund(String mchId, String url, String data) throws Exception {
        /**
         * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的
         */
        KeyStore keyStore = KeyStore.getInstance("PKCS12");//证书格式
        //这里自行实现我是使用数据库配置将证书上传到了服务器可以使用 FileInputStream读取本地文件
        ClassPathResource cl = new ClassPathResource("xxx您的证书名称cert.p12");//基于linux系统,获取证书相对路径
        try {
            //这里写密码..默认是你的MCHID
            keyStore.load(cl.getInputStream(), mchId.toCharArray());
        } finally {
            cl.getInputStream().close();
        }
        SSLContext sslcontext = SSLContexts.custom()
                //这里也是写密码的
                .loadKeyMaterial(keyStore, mchId.toCharArray())
                .build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslcontext,
                SSLConnectionSocketFactory.getDefaultHostnameVerifier());
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .build();
        try {
            HttpPost httpost = new HttpPost(url);
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();
                //接受到返回信息
                String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
                EntityUtils.consume(entity);
                Map<String,Object> map = XMLUtils.parseXmlToList(jsonStr);
                return map;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
发布了87 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_38188762/article/details/103969471