package com.liquidnet.service.dragon.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.HttpUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.dragon.channel.wepay.resp.AliPayRefundReturnCallBackDto;
import com.liquidnet.service.dragon.channel.wepay.resp.WePayRefundReturnCallBackDto;
import com.liquidnet.service.dragon.channel.wepay.resp.WePayRefundReturnCallBackInfoDto;
import com.liquidnet.service.dragon.channel.wepay.resp.WePayRefundReturnDto;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.dto.DragonRefundAppDto;
import com.liquidnet.service.dragon.dto.DragonRefundChannelDto;
import com.liquidnet.service.dragon.dto.NotifyUrlDto;
import com.liquidnet.service.dragon.dto.RefundContentDto;
import com.liquidnet.service.dragon.service.IDragonOrderRefundsService;
import com.liquidnet.service.dragon.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.SortedMap;
import java.util.TreeMap;

@Slf4j
@Service
public class DragonOrderRefundsServiceImpl implements IDragonOrderRefundsService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    DataUtils dataUtils;
    @Autowired
    MqHandleUtil mqHandleUtil;
    @Value("${liquidnet.dragon.url}")
    private String url;

    @Override
    public ResponseDto<DragonRefundAppDto> dragonRefund(String orderCode, String code, String orderRefundCode, String reason, String notifyUrl, BigDecimal price, String paymentType, String paymentId, BigDecimal priceTotal) {
        try {
            LocalDateTime nowTime = LocalDateTime.now();
            String refundCode = IDGenerator.refundCode();
            //创建退款单
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_order_refund.insert"),
                    new Object[]{code, refundCode, orderRefundCode, price, reason, notifyUrl, paymentType, nowTime, nowTime},
                    DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
            );
            dataUtils.setRefundNotifyUrl(orderRefundCode, notifyUrl);
            DragonRefundChannelDto dto = null;
            String localWePayCallBackUrl = url + "/refund/callBack/wepay";
            if (insertResult) {
                switch (paymentType) {
                    case DragonConstant.REFUND_TYPE_APP_ALIPAY:
                        dto = aliPayRefund(code, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_WAP_ALIPAY:
                        dto = aliPayRefund(code, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_WEB_ALIPAY:
                        dto = aliPayRefund(code, orderRefundCode, code, reason, price, paymentId, paymentType, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_APP_WEPAY:
                        dto = weyPayRefund(code, orderRefundCode, code, reason, price, priceTotal, paymentId, paymentType, localWePayCallBackUrl, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_WAP_WEPAY:
                        dto = weyPayRefund(code, orderRefundCode, code, reason, price, priceTotal, paymentId, paymentType, localWePayCallBackUrl, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_WEB_WEPAY:
                        dto = weyPayRefund(code, orderRefundCode, code, reason, price, priceTotal, paymentId, paymentType, localWePayCallBackUrl, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_JS_WEPAY:
                        dto = weyPayRefund(code, orderRefundCode, code, reason, price, priceTotal, paymentId, paymentType, localWePayCallBackUrl, nowTime);
                        break;
                    case DragonConstant.REFUND_TYPE_APPLET_WEPAY:
                        dto = weyPayRefund(code, orderRefundCode, code, reason, price, priceTotal, paymentId, paymentType, localWePayCallBackUrl, nowTime);
                        break;
                }

                log.info("dto = " + JSON.toJSONString(dto));

                if (dto == null) {
                    return ResponseDto.failure("退款失败:参数异常");
                } else if (dto.getResult().equalsIgnoreCase("refunding")) {
                } else if (dto.getResult().equalsIgnoreCase("refunded")) {
                    //调用回调
                } else if (dto.getResult().equalsIgnoreCase("error")) {
                    //调用回调
                    return ResponseDto.failure("退款失败:" + dto.getMessage());
                } else if (dto.getResult().equalsIgnoreCase("exception")) {
                }
                DragonRefundAppDto refundAppDto = new DragonRefundAppDto();
                refundAppDto.setOrderCode(orderCode);
                refundAppDto.setCode(code);
                refundAppDto.setOrderRefundCode(orderRefundCode);
                refundAppDto.setRefundCode(refundCode);

                log.info("refundAppDto = " + JSON.toJSONString(refundAppDto));
                return ResponseDto.success(refundAppDto);
            } else {
                return ResponseDto.failure("退款失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("orderCode = " + orderCode + "", e);
            return ResponseDto.failure("退款失败:" + e.getMessage());
        }
    }

    //微信退款接口
    public DragonRefundChannelDto weyPayRefund(String orderRefundId, String refundCode, String code, String reason, BigDecimal price, BigDecimal priceTotal, String paymentId, String paymentType, String notifyUrl, LocalDateTime nowTime) {
        try {
            String refundStatus = DragonConstant.RefundStatusEnum.STATUS_ERROR.getCode();
            DragonRefundChannelDto channelDto = new DragonRefundChannelDto();
            RefundContentDto contentDto = new RefundContentDto();
            String nonceStr = PayWepayUtils.getInstance().getNonceStr();
            SortedMap<String, Object> parameters = new TreeMap<>();
            parameters.put("mch_id", PayWepayUtils.getInstance().getMerchantId());
            if (paymentType.equalsIgnoreCase(DragonConstant.PayTypeEnum.PAYMENT_TYPE_JS_WEPAY.getCode())) {
                parameters.put("appid", PayWepayUtils.getInstance().getJS_APP_ID());
            } else if (paymentType.equalsIgnoreCase(DragonConstant.PayTypeEnum.PAYMENT_TYPE_WEB_WEPAY.getCode())) {
                parameters.put("appid", PayWepayUtils.getInstance().getWEB_APP_ID());
            } else if (paymentType.equalsIgnoreCase(DragonConstant.PayTypeEnum.PAYMENT_TYPE_APP_WEPAY.getCode())) {
                parameters.put("appid", PayWepayUtils.getInstance().getAPP_ID());
            } else if (paymentType.equalsIgnoreCase(DragonConstant.PayTypeEnum.PAYMENT_TYPE_APPLET_WEPAY.getCode())) {
                parameters.put("appid", PayWepayUtils.getInstance().getAPPLET_APP_ID());
            } else if (paymentType.equalsIgnoreCase(DragonConstant.PayTypeEnum.PAYMENT_TYPE_WAP_WEPAY.getCode())) {
                parameters.put("appid", PayWepayUtils.getInstance().getWAP_APP_ID());
            }
            parameters.put("nonce_str", nonceStr);
            parameters.put("out_refund_no", refundCode);
            parameters.put("out_trade_no", code);
            parameters.put("refund_fee", (int) (price.doubleValue() * 100) + "");
            parameters.put("total_fee", (int) (priceTotal.doubleValue() * 100) + "");
            parameters.put("notify_url", notifyUrl);
            parameters.put("refund_desc", reason);
            parameters.put("refund_account", "REFUND_SOURCE_RECHARGE_FUNDS");
            String sign = PayWepayUtils.getInstance().createSign(parameters);
            parameters.put("sign", sign);
            String data = PayWepayUtils.getInstance().getRequestXml(parameters);
            String refundError = "";
            try {
                HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");
                httpost.setEntity(new StringEntity(data, "UTF-8"));
                CloseableHttpResponse response = PayWepayUtils.getInstance().getHttpClient().execute(httpost);
                try {
                    HttpEntity entity = response.getEntity();
                    entity.getContent();
                    String jsonStr = EntityUtils.toString(entity, "UTF-8");
                    log.info("JSONSTR = " + jsonStr);
                    WePayRefundReturnDto wePayRefundReturnDto = XmlUtil.toBean(jsonStr, WePayRefundReturnDto.class);
                    if (wePayRefundReturnDto.getErrCodeDes() != null) {
                        channelDto.setResult("error");
                        channelDto.setMessage(wePayRefundReturnDto.getErrCodeDes());
                        contentDto.setRequest(data);
                        contentDto.setResponse(jsonStr);
                        channelDto.setContent(contentDto);
                        return channelDto;
                    }
                    if (!wePayRefundReturnDto.getReturnCode().equalsIgnoreCase("SUCCESS") || wePayRefundReturnDto.getReturnCode() == null) {
                        try {
                            refundStatus = DragonConstant.RefundStatusEnum.STATUS_ERROR.getCode();
                            if (null == wePayRefundReturnDto.getReturnMsg()) {
                                refundError = "退款失败，原因未知";
                            } else {
                                refundError = wePayRefundReturnDto.getReturnMsg();
                            }
                            // 修改退款订单
                            mqHandleUtil.sendMySqlRedis(
                                    SqlMapping.get("dragon_order_refund_error.update"),
                                    new Object[]{nowTime, refundError, refundStatus, code},
                                    DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                            );
                        } catch (Exception e) {
                            e.printStackTrace();
                            //保存错误信息
                            log.error("");
                            channelDto.setResult("exception");
                            channelDto.setMessage("update order refund with db error: " + e.getMessage());
                            contentDto.setRequest(data);
                            contentDto.setResponse(jsonStr);
                            channelDto.setContent(contentDto);
                            return channelDto;
                        }
                        channelDto.setResult("error");
                        channelDto.setMessage(refundError);
                        contentDto.setRequest(data);
                        contentDto.setResponse(jsonStr);
                        channelDto.setContent(contentDto);
                        return channelDto;
                    }

                    // 创建退款日志
                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_log.insert"),
                            new Object[]{orderRefundId, paymentType, data, nowTime, nowTime},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                    try {
                        if (wePayRefundReturnDto.getReturnCode().equalsIgnoreCase("SUCCESS")) {
                            refundStatus = DragonConstant.RefundStatusEnum.STATUS_REFUNDED.getCode();
                        }
                        mqHandleUtil.sendMySqlRedis(
                                SqlMapping.get("dragon_order_refund_success.update"),
                                new Object[]{nowTime, null, refundStatus, code},
                                DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                        );
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("");
                        channelDto.setResult("exception");
                        channelDto.setMessage("update order refund with db error: " + e.getMessage());
                        contentDto.setRequest(data);
                        contentDto.setResponse(jsonStr);
                        channelDto.setContent(contentDto);
                        return channelDto;
                    }
                    channelDto.setResult("refunded");
                    channelDto.setMessage(paymentType + " refund info: ");
                    contentDto.setRequest(data);
                    contentDto.setResponse(jsonStr);
                    channelDto.setContent(contentDto);
                    EntityUtils.consume(entity);
                    return channelDto;
                } finally {
                    response.close();
                }
            } finally {
//                PayWepayUtils.getInstance().getHttpClient().close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("");
            return null;
        }
    }

    //支付宝退款接口
    public DragonRefundChannelDto aliPayRefund(String orderRefundId, String refundCode, String code, String reason, BigDecimal price, String paymentId, String paymentType, LocalDateTime nowTime) {
        String refundStatus;
        DragonRefundChannelDto channelDto = new DragonRefundChannelDto();
        RefundContentDto contentDto = new RefundContentDto();
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();//创建API对应的request类
        try {
            String refundError = "";
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + code + "\"," +
                    "\"trade_no\":\"" + paymentId + "\"," +
                    "\"out_request_no\":\"" + refundCode + "\"," +
                    "\"refund_reason\":\"" + reason + "\"," +
                    "\"refund_amount\":\"" + price.doubleValue() + "\"}"); //设置业务参数
            AlipayTradeRefundResponse response = PayAlipayUtils.getInstance().getHttpClient().execute(request);
            if (response.getFundChange() == null || response.getFundChange().equals("N")) {
                try {
                    refundStatus = DragonConstant.RefundStatusEnum.STATUS_ERROR.getCode();
                    if (null == response.getSubMsg()) {
                        refundError = "退款失败，原因未知";
                    } else {
                        refundError = response.getSubMsg();
                    }
                    // 修改退款订单
                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_error.update"),
                            new Object[]{nowTime, refundError, refundStatus, code},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                } catch (Exception e) {
                    e.printStackTrace();
                    //保存错误信息
                    log.error("");
                    channelDto.setResult("exception");
                    channelDto.setMessage("update order refund with db error: " + e.getMessage());
                    contentDto.setRequest(JSON.toJSONString(response.getParams()));
                    contentDto.setResponse(response.getBody());
                    channelDto.setContent(contentDto);
                    return channelDto;
                }
                channelDto.setResult("error");
                channelDto.setMessage(refundError);
                contentDto.setRequest(JSON.toJSONString(response.getParams()));
                contentDto.setResponse(response.getBody());
                channelDto.setContent(contentDto);
                return channelDto;
            }

            // 创建退款日志
            mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_order_refund_log.insert"),
                    new Object[]{orderRefundId, paymentType, response.getBody(), nowTime, nowTime},
                    DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
            );
            try {
                String refundAt = "";
                if (response.getFundChange().equals("Y")) {
                    refundStatus = DragonConstant.RefundStatusEnum.STATUS_REFUNDED.getCode();
                    refundAt = DateUtil.format(response.getGmtRefundPay(), DateUtil.Formatter.yyyyMMddHHmmss);
                } else {
                    refundStatus = DragonConstant.RefundStatusEnum.STATUS_REFUNDING.getCode();
                }
                mqHandleUtil.sendMySqlRedis(
                        SqlMapping.get("dragon_order_refund_success.update"),
                        new Object[]{nowTime, refundAt, refundStatus, code},
                        DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                );
            } catch (Exception e) {
                e.printStackTrace();
                channelDto.setResult("exception");
                channelDto.setMessage("update order refund with db error: " + e.getMessage());
                contentDto.setRequest(JSON.toJSONString(response.getParams()));
                contentDto.setResponse(response.getBody());
                channelDto.setContent(contentDto);
                return channelDto;
            }
            channelDto.setResult("refunded");
            channelDto.setMessage(paymentType + " refund info: ");
            contentDto.setRequest(JSON.toJSONString(response.getParams()));
            contentDto.setResponse(response.getBody());
            channelDto.setContent(contentDto);
            return channelDto;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("");
            return null;
        }
    }

    @Override
    public String wePayRefundCallBack(HttpServletRequest request, HttpServletResponse response) {
        InputStream inStream;
        ByteArrayOutputStream outSteam;
        LocalDateTime nowTime = LocalDateTime.now();
        try {
            inStream = request.getInputStream();
            outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            // 获取微信调用我们notify_url的返回信息
            String jsonStr = new String(outSteam.toByteArray(), "utf-8");
            outSteam.close();
            inStream.close();
            WePayRefundReturnCallBackDto callBackDto = XmlUtil.toBean(jsonStr, WePayRefundReturnCallBackDto.class);
            log.info("callBackDto = " + callBackDto);
            if (callBackDto.getReturnCode().equalsIgnoreCase("SUCCESS")) {
                String reqInfo = PayWepayUtils.getInstance().unCodeReqInfo(callBackDto.getReqInfo());
                WePayRefundReturnCallBackInfoDto info = XmlUtil.toBean(reqInfo, WePayRefundReturnCallBackInfoDto.class);
                String outRefundNo = info.getOutRefundNo();
                String refundAt = info.getSuccessTime();
                try {
                    NotifyUrlDto dto = new NotifyUrlDto();
                    if (info.getRefundStatus().equalsIgnoreCase("SUCCESS")) {
                        dto.setStatus(1);
                    } else {
                        dto.setStatus(0);
                    }
                    dto.setOrderRefundCode(info.getOutRefundNo());
                    dto.setRefundCode(info.getOutTradeNo());
                    dto.setRefundPrice(new BigDecimal(info.getRefundFee()).divide(BigDecimal.valueOf(100)).toString());
                    dto.setRefundAt(refundAt);
                    dto.setRefundError(callBackDto.getReturnMsg());
                    log.info("SEND WEPAY NOTIFTURL = " + JSON.toJSONString(dto));
                    sendNotifyUrl(dto, null);

                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_log.insert"),
                            new Object[]{outRefundNo, info.getRefundRequestSource(), JSON.toJSONString(info), nowTime, nowTime},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_success.update"),
                            new Object[]{nowTime, refundAt, DragonConstant.RefundStatusEnum.STATUS_REFUNDED.getCode(), outRefundNo},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                    return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("");
                    return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>";
                }
            } else {
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>";
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("");
            return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>";
        }
    }

    @Override
    public String aliPayRefundCodeStatus(String outTradeNo, String tradeNo, String outBizNo, String callBackUrl) {
        try {
            LocalDateTime nowTime = LocalDateTime.now();
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();//创建API对应的request类
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + outTradeNo + "\"," +
                    "\"trade_no\":\"" + tradeNo + "\"," +
                    "\"out_request_no\":\"" + outBizNo + "\"}"); //设置业务参数
            AlipayTradeFastpayRefundQueryResponse response = PayAlipayUtils.getInstance().getHttpClient().execute(request);
            log.info("AlipayTradeFastpayRefundQueryRequest -> data = " + response);

            if (response.isSuccess()) {
                try {
                    NotifyUrlDto dto = new NotifyUrlDto();
                    if (response.getMsg().equalsIgnoreCase("SUCCESS")) {
                        dto.setStatus(1);
                    } else {
                        dto.setStatus(0);
                    }
                    dto.setOrderRefundCode(response.getOutRequestNo());
                    dto.setRefundCode(response.getOutTradeNo());
                    dto.setRefundPrice(response.getRefundAmount());
                    dto.setRefundAt(DateUtil.Formatter.yyyyMMddHHmmss.format(LocalDateTime.now()));
                    dto.setRefundPrice(response.getRefundAmount());
                    dto.setRefundError("");
                    sendNotifyUrl(dto, callBackUrl);

                    log.debug("SEND ALIPAY NOTIFTURL2 = " + JSON.toJSONString(dto));

                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_log.insert"),
                            new Object[]{outBizNo, "ALIPAY", JSON.toJSONString(response), nowTime, nowTime},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );

                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_success.update"),
                            new Object[]{nowTime, DateUtil.format(response.getGmtRefundPay(), DateUtil.Formatter.yyyyMMddHHmmss), DragonConstant.RefundStatusEnum.STATUS_REFUNDED.getCode(), response.getOutRequestNo()},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );

                    return "success";
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("");
                    return "fail";
                }
            } else {
                log.error("response.isSuccess() -> fail ");
                return "fail";
            }

        } catch (Exception e) {

        }
        return null;
    }

    public String aliPayRefundCallBack(String jsonStr) {
        LocalDateTime nowTime = LocalDateTime.now();
        try {
            AliPayRefundReturnCallBackDto callBackDto = JsonUtils.fromJson(jsonStr, AliPayRefundReturnCallBackDto.class);
            AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();//创建API对应的request类
            request.setBizContent("{" +
                    "\"out_trade_no\":\"" + callBackDto.getOutTradeNo() + "\"," +
                    "\"trade_no\":\"" + callBackDto.getTradeNo() + "\"," +
                    "\"out_request_no\":\"" + callBackDto.getOutBizNo() + "\"}"); //设置业务参数
            AlipayTradeFastpayRefundQueryResponse response = PayAlipayUtils.getInstance().getHttpClient().execute(request);
            log.info("AlipayTradeFastpayRefundQueryRequest -> data = " + JSON.toJSONString(response));

            if (response.isSuccess()) {
                try {
                    NotifyUrlDto dto = new NotifyUrlDto();
                    if (response.getMsg().equalsIgnoreCase("SUCCESS")) {
                        dto.setStatus(1);
                    } else {
                        dto.setStatus(0);
                    }
                    dto.setOrderRefundCode(response.getOutRequestNo());
                    dto.setRefundCode(response.getOutTradeNo());
                    dto.setRefundPrice(response.getRefundAmount());
                    dto.setRefundAt(callBackDto.getGmtRefund());
                    dto.setRefundPrice(response.getRefundAmount());
                    dto.setRefundError("");
                    sendNotifyUrl(dto, null);

                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_log.insert"),
                            new Object[]{callBackDto.getOutBizNo(), "ALIPAY", jsonStr, nowTime, nowTime},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                    log.debug("SEND MQ INSERT");
                    mqHandleUtil.sendMySqlRedis(
                            SqlMapping.get("dragon_order_refund_success.update"),
                            new Object[]{nowTime, callBackDto.getGmtRefund(), DragonConstant.RefundStatusEnum.STATUS_REFUNDED.getCode(), response.getOutRequestNo()},
                            DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
                    );
                    log.debug("SEND MQ UPDATE");
                    return "success";
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("");
                    return "fail";
                }
            } else {
                log.error("response.isSuccess() -> fail ");
                return "fail";
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("");
            return "fail";
        }
    }

    private void sendNotifyUrl(NotifyUrlDto notifyUrlDto, String url) {
        LocalDateTime nowTime = LocalDateTime.now();
        MultiValueMap<String, String> params = new LinkedMultiValueMap();
        params.add("orderRefundCode", notifyUrlDto.getOrderRefundCode());
        params.add("refundAt", notifyUrlDto.getRefundAt());
        params.add("refundCode", notifyUrlDto.getRefundCode());
        params.add("refundError", notifyUrlDto.getRefundError());
        params.add("refundPrice", notifyUrlDto.getRefundPrice());
        params.add("status", notifyUrlDto.getStatus().toString());
        String response = HttpUtil.post(url == null ? dataUtils.getRefundNotifyUrl(notifyUrlDto.getOrderRefundCode()) : url, params);
        log.info("RETURN RESPONSE=" + response);
        if (response.equals("success")) {
            mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_order_refund_call_back.update"),
                    new Object[]{nowTime, DateUtil.Formatter.yyyyMMddHHmmss.format(nowTime), DragonConstant.RefundStatusEnum.STATUS_SUCCESS.getCode(), notifyUrlDto.getRefundCode()},
                    DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
            );
        } else {
            mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_order_refund_call_back.update"),
                    new Object[]{nowTime, DateUtil.Formatter.yyyyMMddHHmmss.format(nowTime), DragonConstant.RefundStatusEnum.STATUS_FAIL.getCode(), notifyUrlDto.getRefundCode()},
                    DragonConstant.MysqlRedisQueueEnum.DRAGON_REFUND_KEY.getCode()
            );
        }
    }

}
