一、接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
二、请求字段
三、注意事项
(1)需要证书:
(2)证书来源:
(3)证书获取
四、代码开发
/**
* 微信退款 * @throws Exception */ public static String refundFunction(Map<String, Object> map) throws Exception { //这里的map主要有两个参数(商户号mchId和订单金额totalFee) String result = "";//这里用于返回处理返回结果 //xml转换为map,这里用于方便自己后面取出打印结果 XmlToMap xmlToMap = new XmlToMap(); //这里是自己封装的一些配置文件,大家可以跳过这一步,下面用到这里会和大家说明 MyConfig config = null; try { //加载配置 config = new MyConfig(); } catch (Exception e) { e.printStackTrace(); } //获取商户订单号和订单金额 String mchId = map.get("mchId").toString(); //获取订单金额(退款金额默认全部) //这里是自己做的一些格式的转换,有点笨拙,希望不影响大家的思路 String a = map.get("totalFee")+""; String b = Double.valueOf(a) + ""; int lastindex = b.indexOf("."); b = b.substring(0 , lastindex); int c = Integer.parseInt(b);// String d = c + "";// System.out.println("refundMoney--------->"+refundMoney); String totalFee = c + ""; //获取微信订单号// String transactionId = map.get("transactionId").toString(); SortedMap<Object,Object> parameters = new TreeMap<Object,Object>(); parameters.put("appid", config.getAppID());//appid parameters.put("mch_id", config.getMchID());//商户号 parameters.put("nonce_str", CreateNoncestr());//随机数 // parameters.put("transaction_id", transactionId);//微信支付单号 parameters.put("out_trade_no", mchId);//商户订单号 parameters.put("out_refund_no", CreateNoncestr());//我们自己设定的退款申请号,约束为UK parameters.put("total_fee", totalFee) ;//订单金额 单位为分!!!这里稍微注意一下 parameters.put("refund_fee", totalFee);//退款金额 单位为分!!! parameters.put("op_user_id", config.getMchID());//操作人员,默认为商户账号 String sign = createSign("utf-8", parameters); System.out.println("sign---->"+sign);//签名 parameters.put("sign", sign); //xml和map之间的转换 String reuqestXml = getRequestXml(parameters); Map<String, Object> xmlMap = XmlToMap.xmlStr2Map(reuqestXml); KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File(config.certPath));//放商户证书的路径 try { keyStore.load(instream, config.getMchID().toCharArray());//商户号 } finally { instream.close(); } //这里导包注意一下,可能会冲突 SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, config.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 httpPost = new HttpPost(config.refund_url);//退款接口 System.out.println("executing request" + httpPost.getRequestLine()); StringEntity reqEntity = new StringEntity(reuqestXml); // 设置类型 reqEntity.setContentType("application/x-www-form-urlencoded"); httpPost.setEntity(reqEntity); CloseableHttpResponse response = httpclient.execute(httpPost); try { HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8")); System.out.println("bufferedReader.readLine()--->"+bufferedReader.readLine()); String text; //这里是自己做的输出结果,方便查看错误原因 while ((text = bufferedReader.readLine()) != null) { System.out.println(text); if(!text.startsWith("</xml>")) { text = "<xml>"+text+"</xml>"; Map<String, Object> xmlResultMap = XmlToMap.xmlStr2Map(text); if(xmlResultMap.get("result_code") != null) { result = xmlResultMap.get("result_code")+""; } } } } EntityUtils.consume(entity); } finally { response.close(); } } finally { httpclient.close(); } return result; }