微信PC扫码支付(三)-申请退款

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cl11992/article/details/86712009

一、介绍

本文介绍了微信申请退款的代码实例,如有不足的请提出,我会做出改正。

二、官方文档

申请退款:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_4

三、微信SDK安装方法

微信PC扫码支付(一)-maven本地仓库安装:微信支付sdk

四、申请退款

注意:申请退款需要商家证书,需提前下载

  • 下文PayException为自定义异常类
  • 下文WeixinConfig为微信需要固定参数类

调用申请退款

public Object refund(Map<String, Object> map) throws PayException {
	Map<String,String> resultMap=new HashMap<>();
	try {
		if(map.isEmpty()){
			logger.error("微信申请退款缺少参数");
			throw new PayException("微信申请退款缺少参数");
		}
		//随机字符串
		String nonceStr=Long.toString(System.currentTimeMillis() / 1000);
		logger.info("微信退款-nonce_str:"+nonceStr);
		//商户订单号
		String outTradeNo = (String)map.get("outTradeNo");
		logger.info("微信退款-商户订单号out_trade_no:"+outTradeNo);
		//退款单号
		String outRefundNo = (String)map.get("outRefundNo");
		logger.info("微信退款-退款单号out_refund_no:"+outRefundNo);
		//订单总金额
		String totalFee = map.get("amountPaid").toString();
		logger.info("微信退款-订单总金额total_fee:"+totalFee);
		//退款总金额
		String refundFee = map.get("refundFee").toString();
		logger.info("微信退款-退款金额refund_fee:"+refundFee);
		//验证参数
		if(StringUtils.isBlank(outTradeNo)){
			logger.error("微信申请退款缺少参数-商户订单号为空");
			throw new PayException("微信申请退款缺少参数-商户订单号不能为空");
		}
		if(StringUtils.isBlank(outRefundNo)){
			logger.error("微信申请退款缺少参数-退款单号为空");
			throw new PayException("微信申请退款缺少参数-退款单号不能为空");
		}
		if(StringUtils.isBlank(totalFee)){
			logger.error("微信申请退款缺少参数-订单总金额为空");
			throw new PayException("微信申请退款缺少参数-订单总金额不能为空");
		}
		if(StringUtils.isBlank(refundFee)){
			logger.error("微信申请退款缺少参数-退款总金额为空");
			throw new PayException("微信申请退款缺少参数-退款总金额不能为空");
		}
		Map<String, String> packageParams = new HashMap<String, String>();
		WeixinConfig weixinConfig=new WeixinConfig();
		int price1 = (int)(Float.valueOf(totalFee)*100);//总钱数
		int price2 = (int)(Float.valueOf(refundFee)*100);//退款钱数
		packageParams.put("appid", weixinConfig.getAppID());
		packageParams.put("mch_id", weixinConfig.getMchID());
		packageParams.put("nonce_str", nonceStr);
		packageParams.put("notify_url", weixinConfig.getNotifyUrl());
		packageParams.put("out_trade_no",outTradeNo);
		packageParams.put("out_refund_no",outRefundNo);
		packageParams.put("total_fee", Integer.toString(price1));
		packageParams.put("refund_fee", Integer.toString(price2));
		//签名
		String sign=WXPayUtil.generateSignature(packageParams, weixinConfig.getKey());
		packageParams.put("sign",sign);
		logger.info("微信申请退款-sign:"+sign);
		//拼接需要提交微信的数据
		String xml = WXPayUtil.mapToXml(packageParams);
		String result = null;
		try {
			result = ClientCustomSSL.doRefund(xml);
			if(StringUtils.isBlank(result)){
				logger.error("微信申请退款发生错误");
				throw new PayException("微信申请退款发生错误");
			}
			Map<String, String> refundResultMap = WXPayUtil.xmlToMap(result);
			String returnCode = (String) refundResultMap.get("return_code");
			logger.info("微信申请退款-return_code:"+returnCode);
			if(!returnCode.equals("SUCCESS")){
				String returnMsg = (String) refundResultMap.get("return_msg");
				if(StringUtils.isBlank(returnMsg)){
					returnMsg = "微信申请退款发生错误";
				}
				logger.info("微信申请退款-return_msg:"+returnMsg);
				resultMap.put("returnCode","FAIL");
				resultMap.put("returnMsg", returnMsg);
				return resultMap;
			}
			String resultCode = (String)refundResultMap.get("result_code");
			if(!resultCode.equals("SUCCESS")){
				String errCodeDes = (String) refundResultMap.get("err_code_des");
				if(StringUtils.isBlank(errCodeDes)){
					errCodeDes = "微信申请退款发生错误";
				}
				logger.info("微信申请退款-err_code_des:"+errCodeDes);
				resultMap.put("returnCode","FAIL");
				resultMap.put("returnMsg", errCodeDes);
				return resultMap;
			}
			resultMap.put("returnCode", "SUCCESS");
			resultMap.put("returnMsg", "微信申请退款成功");
			logger.info("微信退款申请成功");
			return resultMap;
	    } catch (PayException e) {
	    	logger.error("微信申请退款发生错误:",e);
			throw new PayException("微信申请退款发生错误");
	    }
	} catch (Exception e) {
		logger.error("微信申请退款发生错误:",e);
		throw new PayException("微信申请退款发生错误");
	}
}

ClientCustomSSL.java

public class ClientCustomSSL {
	
	/*
	 * 使用商户证书去退款
	*/
	public static String doRefund(String data) throws Exception {
		WeixinConfig weixinConfig=new WeixinConfig();

		String payCert = "XXXXXXXXXX";//商户证书地址
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream is = new FileInputStream(payCert);
        try {
            keyStore.load(is, weixinConfig.getMchID().toCharArray());// 这里写密码..默认是你的MCHID(商户号)
        } finally {
            is.close();
        }

        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, weixinConfig.getMchID().toCharArray()).build();

        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund"); // 设置响应头信息
            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            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);
                return jsonStr;
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/cl11992/article/details/86712009