开发的业务中可能会有支付完成后,需要进行退款的情况,我最近开发也遇到了,于是呢就对接了一下微信和支付宝的退款的接口
1、支付宝退款,支付宝退款还是很简单的
Map<String, String> websitemap = getAlipayInfo();// 获得支付宝配置 String appId = websitemap.get("alipayAppid"); // 支付宝合作伙伴id String privateKey = websitemap.get("privatekey");//支付宝的私钥 String publicKey = websitemap.get("publickey");//支付宝的公钥 AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", appId, privateKey, "json", "UTF-8", publicKey, "RSA2"); //请求参数 AlipayTradeRefundModel refundModel = new AlipayTradeRefundModel(); refundModel.setTradeNo(order.getExternalOrderNo()); refundModel.setOutTradeNo(order.getOrderNo()); refundModel.setRefundAmount(String.valueOf(order.getRealPrice())); refundModel.setRefundReason("商品退款"); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); request.setBizModel(refundModel); AlipayTradeRefundResponse response = alipayClient.execute(request); if (response.isSuccess()) { System.out.println("调用成功"); //退款账户 refundAccount = response.getBuyerLogonId(); } else { System.out.println("调用失败"); }
退款回来,需要记录下退款的账号,一般是手机号或者你得邮箱号码
2、微信退款,微信退款会比较麻烦一下,需要在微信商户平台下载证书
需要这三个证书参与,才能正常调用,不让会报ERROR: api.mch.weixin.qq.com:443 failed to respond [微信退款],直接上代码
Map<String, String> websitemap = getWxpayInfo();//获得微信支付配置 //退款链接 String mchId = websitemap.get("mchid"); String appId = websitemap.get("appid"); String payKey = websitemap.get("payKey"); //随机字符串 String nonceStr = PackageUtil.getNonceStr();// 随机字符串 // 设置package订单参数 SortedMap<String, String> packageParams = new TreeMap<String, String>(); // 必须字段 // 公众平台appid packageParams.put("appid", appId); packageParams.put("mch_id", mchId); // 商户号id packageParams.put("nonce_str", nonceStr); packageParams.put("transaction_id", order.getExternalOrderNo()); packageParams.put("out_refund_no", order.getOrderNo()); // 退款订单号 //价格乘100 BigDecimal realPrice = new BigDecimal(order.getRealPrice()).multiply(new BigDecimal("100")); packageParams.put("total_fee", String.valueOf(realPrice.intValue())); // 总金额 packageParams.put("refund_fee", String.valueOf(realPrice.intValue())); // 退款金额 // sign签名 String sign = PackageUtil.createSign(packageParams, payKey); // 统一支付请求参数xml String xmlPackage = XMLParse.refundPackage(packageParams, sign); logger.info("xmlPackage" + xmlPackage); // 预支付订单创建结果 String resultXmlStr = wxRefundLink(xmlPackage, mchId, request); Map<String, String> resultMap = MessageUtil.parseStringXml(resultXmlStr); logger.info("返回的resultMap" + resultMap); // 通信标识返回状态码 String returnCode = resultMap.get("return_code"); // 返回状态消息 String returnMsg = resultMap.get("return_msg"); logger.info("returnCode为" + returnCode); logger.info("returnMsg为" + returnMsg);
XMl解析:
/** * 微信支付package * @param packageParams * @param sign * @return */ public static String refundPackage(SortedMap<String, String> packageParams,String sign) { String xmlPackage=""; try { xmlPackage = "<xml>" + "<appid>"+packageParams.get("appid")+"</appid>" + "<mch_id>"+packageParams.get("mch_id")+"</mch_id>" + "<nonce_str>"+packageParams.get("nonce_str")+"</nonce_str>" + "<out_refund_no>"+packageParams.get("out_refund_no")+"</out_refund_no>" + "<total_fee>"+packageParams.get("total_fee")+"</total_fee>" + "<refund_fee>"+packageParams.get("refund_fee")+"</refund_fee>" + "<transaction_id>"+packageParams.get("transaction_id")+"</transaction_id>" + "<sign>"+sign+"</sign>" + "</xml>"; } catch (Exception e) { e.printStackTrace(); } return xmlPackage; }
/** * 微信退款链接 * * @param postDataXML * @param mch_id * @param request * @return * @throws Exception */ private String wxRefundLink(String postDataXML, String mch_id, HttpServletRequest request) throws Exception { CloseableHttpClient httpClient = null; CloseableHttpResponse httpResponse = null; try { String WX_REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //获取微信退款证书 KeyStore keyStore = getCertificate(mch_id, request); SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, mch_id.toCharArray()).build(); SSLConnectionSocketFactory sslf = new SSLConnectionSocketFactory(sslContext); httpClient = HttpClients.custom().setSSLSocketFactory(sslf).build(); HttpPost httpPost = new HttpPost(WX_REFUND_URL);//退款接口 StringEntity reqEntity = new StringEntity(postDataXML); // 设置类型 reqEntity.setContentType("application/x-www-form-urlencoded"); httpPost.setEntity(reqEntity); String result = null; httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); if (ObjectUtils.isNotNull(httpEntity)) { result = EntityUtils.toString(httpEntity, "UTF8"); EntityUtils.consume(httpEntity); } return result; } finally {//关流 httpClient.close(); httpResponse.close(); } } /** * @param mch_id * @description: 获取微信退款证书 */ private KeyStore getCertificate(String mch_id, HttpServletRequest request) { //try-with-resources 关流 try ( FileInputStream inputStream = new FileInputStream(new File(request.getSession().getServletContext().getRealPath("/cert/apiclient_cert.p12")))) { KeyStore keyStore = KeyStore.getInstance("PKCS12"); keyStore.load(inputStream, mch_id.toCharArray()); return keyStore; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } }
需要放到服务器上进行测试,即可退款成功,退款不能记录退款人的信息,只是会展示是零钱还是退还银行卡的信息,这个在本平台记录的时候需要记录下