1.退款接口,

微信API文档地址https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_9.shtml

//微信退款,微信支持一个订单多次退款(上限为50),并且订单的交易完成时间不能超过一年
//退款结果,微信会回调通知
//outTradeNo        商户订单号(下单的时候,我们生成的订单))
//refundAmount      退款的金额(单位:分)
//refundReason      退款的说明
//salesId           退款单号,我们自己生成,多次退款的时候要每次不一样
public ReturnJson weChatRefundHighShop (String outTradeNo, String refundAmount, String refundReason,String salesId) throws Exception{
    //可以在此查询当前退款的订单信息,校验订单是否存在、获取金额等信息.....
    //订单金额
    int orderMoney = 1000;
    //通过加载文件的方式来读取私钥,或者也可以使用字符串的方式来加载私钥
    String path = this.getClass().getClassLoader().getResources("./apiclient_key.pem").nextElement().getPath();
    //加载商户私钥(私钥存储在文件)
    PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(path));
    // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(WX_MCH_ID, new PrivateKeySigner(WX_Serial_Number, merchantPrivateKey)),V3_key.getBytes("utf-8"));
    //初始化httpClient
    CloseableHttpClient builder = WechatPayHttpClientBuilder.create().withMerchant(WX_MCH_ID, WX_Serial_Number, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();
    //微信的退款接口
    HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");、
    //退款请求参数的说明
    //out_trade_no    商户订单号
    //out_refund_no   商户退款单号
    //reason          退款的原因
    //notify_url      退款结果通知的地址,此地址必须是一个公网地址
    //funds_account   退款资金的来源  AVAILABLE:可用余额账户
    //amount          资金信息
    //refund          退款金额 单位:分
    //total           退款原订单的总金额,需要我们查询我们自己的订单信息获取
    //currency        币种
    String requestData = "{\n" +
            "  \"out_trade_no\": \""+outTradeNo+"\",\n" +
            "  \"out_refund_no\": \""+ salesId +"\",\n" +
            "  \"reason\": \"优选商城退款\",\n" +
            "  \"notify_url\": \""+Wechat_H5_Refund+"\",\n" +
            "  \"funds_account\": \"AVAILABLE\",\n" +
            "  \"amount\": {\n" +
            "    \"refund\": "+refundAmount+",\n" +
            "    \"total\": "+ orderMoney +",\n" +
            "    \"currency\": \"CNY\"\n" +
            "  }" +
            "}";

    StringEntity entity = new StringEntity(requestData,"utf-8");
    entity.setContentType("application/json");
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept","application/json");
    CloseableHttpResponse response = builder.execute(httpPost);
    JSONObject jsonResult = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) {
            String refundEnum = jsonResult.getString("status");
            return ReturnUtils.returnVal(CommonConstants.appCode.SUCCESS.get(),refundEnum);
        }else {
            return ReturnUtils.returnVal(CommonConstants.appCode.DATAERROR.get(),jsonResult);
        }
    } finally {
        response.close();
    }
}

2.微信回调接口的编写

//退款成功后,微信方通知的回调地址
//在这里解析验签之后,获取到微信发送的退款相关信息
//判断退款状态为成功,然后进行我们自己的业务处理
//此接口微信可能会多次调用,请注意处理
@ResponseBody
@RequestMapping(value = "/wechatRefundNotify",produces = {"application/json;charset=utf-8"})
public ResultEntity wechatRefundNotify(@RequestBody Weixin weixin) {
    AesUtil aesutils = new AesUtil(this.V3_key.getBytes());
    try {
        String string = aesutils.decryptToString(weixin.getResource().getAssociated_data().getBytes(), weixin.getResource().getNonce().getBytes(), weixin.getResource().getCiphertext());
        JSONObject jsonObject = JSONObject.parseObject(string);
        //获取退款单号
        String out_refund_no = jsonObject.getString("out_refund_no");
        //获取退款状态 SUCCESS(退款成功)    CLOSE(退款关闭) ABNORMAL(退款异常)
        String refund_status = jsonObject.getString("refund_status");
        if(refund_status.equals("SUCCESS")){
            //这里是退款成功,进行我们自己的业务处理,然后告诉微信我们收到了,你不用再发了
            return new ResultEntity("SUCCESS", "成功");
        }else if(refund_status.equals("ABNORMAL")) {
            //这里是退款异常了,就需要我们自己另行处理,然后提示用户
            return new ResultEntity("SUCCESS", "成功");
        }
    } catch (Exception e) {
        //异常的记录.....
    }
    return new ResultEntity("FAIL", "失败");
}

3.微信回调的参数及说明

//微信退款回调的通知参数
public class Weixin {
    
    private String create_time;
    
    private String summary;

    private String resiyrce_type;
    
    private WeixinReturnEntities resource = new WeixinReturnEntities();
}
//微信回调的参数
public class WeixinReturnEntities {
    //退款状态
    private String trade_state;
    //退款单号
    private String out_trade_no;

    private String associated_data;

    private String nonce;

    private String ciphertext;
}