应用场景
当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。
注意:
1、交易时间超过一年的订单无法提交退款;
2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
1.首先我们需要准备以下参数:
// 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔 String out_refund_no = "4003832001201605045494929094"; // 商户侧传给微信的订单号 String out_trade_no = "C70E285B10B000011C8312B2D82011F4"; // 总金额 String total_fee = "1"; // 退款金额 String refund_fee = "1"; // 随机字符串 String nonce_str = "C70E285B10B000011C8312B2D82011F4"; //微信商户id String mch_id = "1230177801"; //就是MCHID String op_user_id = "1230177801"; //微信公众号apid String appid = "wx832f85feb2e76b14"; String appsecret = "43cab6b2766381683f6cb1b4ee6db27a"; String partnerkey = "be9aded460e78703b889f18e2915ea6b";
2.用appid、appsecret、partnerkey生成签名
详情可参考微信签名生成API或者参考附件方法
3.执行退款请求
//参数 String data= "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>" + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign><![CDATA[" + sign + "]]></sign>" + "<out_trade_no>" + out_trade_no + "</out_trade_no>" + "<out_refund_no>" + out_refund_no + "</out_refund_no>" + "<total_fee>" + total_fee + "</total_fee>" + "<refund_fee>" + refund_fee + "</refund_fee>" + "<op_user_id>" + op_user_id + "</op_user_id>" + "</xml>"; //响应头信息 String url= "https://api.mch.weixin.qq.com/secapi/pay/refund"; /** * 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 */ KeyStore keyStore = KeyStore.getInstance("PKCS12"); FileInputStream instream = new FileInputStream(new File("D:/refund/apiclient_cert.p12"));//P12文件目录 try { keyStore.load(instream, "1230177801".toCharArray());//这里写密码..默认是你的MCHID } finally { instream.close(); } SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, "1230177801".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(url); // 设置响应头信息 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 =""; if (entity != null) { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(entity.getContent()); Element rootElt = document.getRootElement(); // 结果码 String returnCode = rootElt.elementText("return_code"); String resultCode = rootElt.elementText("result_code"); if ("SUCCESS".equals(returnCode)&&"SUCCESS".equals(resultCode)) { String strResponse=returnCode; System.out.println(strResponse); jsonStr="退款成功"; }else { String strResponse=rootElt.elementText("err_code_des"); System.out.println(strResponse); jsonStr="退款失败"; } } /* String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); EntityUtils.consume(entity);*/ return jsonStr; } finally { response.close(); } } finally { httpclient.close(); } }
评一波