微信和支付宝退款

开发的业务中可能会有支付完成后,需要进行退款的情况,我最近开发也遇到了,于是呢就对接了一下微信和支付宝的退款的接口

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);
    }
}

 

需要放到服务器上进行测试,即可退款成功,退款不能记录退款人的信息,只是会展示是零钱还是退还银行卡的信息,这个在本平台记录的时候需要记录下

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值