package com.crm.pay.service.impl.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.crm.pay.dao.repository.FinanceWithdrawRepository;
import com.crm.pay.dto.finance.withdraw.automatic.FinanceWithdrawUGatePayDto;
import com.crm.pay.entity.callback.UGatePayCallbackEntity;
import com.crm.pay.entity.property.UGatePayPropertyEntity;
import com.crm.pay.entity.property.UGateWithdrawPropertyEntity;
import com.crm.pay.entity.ugatepay.UGagePayWithdrawQueryEntity;
import com.crm.pay.service.FinanceDepositService;
import com.crm.pay.service.UGatePayService;
import com.crm.pay.service.impl.base.BasePayServiceImpl;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.model.constant.PayConstants;
import com.crm.rely.backend.model.dto.finance.withdraw.FinanceWithdrawDto;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceDepositAddEntity;
import com.crm.pay.entity.FinanceDepositCallbackUpdateEntity;
import com.crm.rely.backend.model.entity.finance.deposit.FinanceMerchantDepositAddEntity;
import com.crm.pay.entity.finance.withdraw.FinanceWithdrawApproveChannelEntity;
import com.crm.pay.entity.finance.withdraw.FinanceWithdrawApproveChannelSubmitEntity;
import com.crm.pay.entity.finance.withdraw.automatic.FinanceWithdrawInfoEntity;
import com.crm.pay.entity.finance.withdraw.automatic.FinanceWithdrawUGateEntity;
import com.crm.rely.backend.model.pojo.table.FinanceDepositTable;
import com.crm.rely.backend.model.pojo.table.FinanceWithdrawTable;
import com.crm.rely.backend.model.pojo.table.SysRemitChannelTable;
import com.crm.rely.backend.model.pojo.table.SysRemittanceChannelTable;
import com.crm.rely.backend.core.exception.PayValidatedException;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.AESUtil;
import com.crm.rely.backend.util.HttpUtil;
import com.crm.rely.backend.util.MD5Util;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Connection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class UGatePayServiceImpl extends BasePayServiceImpl implements UGatePayService {

    @Autowired
    private FinanceDepositService financeDepositService;
    @Autowired
    private MqSendService mqSendService;
    @Autowired
    private FinanceWithdrawRepository financeWithdrawRepository;

    public static void main(String[] args) throws IOException {
        String con = "";
        System.out.println(AESUtil.encrypt(con, "bfa5559109f94c78af615bcf00d52060"));


        System.out.println(AESUtil.decrypt("", "bfa5559109f94c78af615bcf00d52060"));

//        Map<String, Object> map = new LinkedHashMap<>();
//        map.put("MerchantUID", "311469");
//        map.put("MerchantBuyOrderNo", "mt1936521584561623868465");
//        map.put("MerchantBuyOrderMoney", "125.32");
//        map.put("MerchantBuyOrderUniqueCode", UUID.randomUUID().toString().replace("-", ""));
//        map.put("MerchantBuyOrderPayType", "1");
//        map.put("MerchantBuyOrderPayerName", "张三");
//        map.put("MerchantBuyOrderPayerUID", "112");
//        map.put("JumpUrl", "https://pay.6cd7e0f0b52.com");
//
//
//        String body = JSON.toJSONString(map);
//        System.out.println("body : " + body);
//        String key = "8456aa036e7aaf8ba1b1a15d8b2ac0b1";
//        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
//
//        Map<String, String> mm = new HashMap<>();
//        mm.put("body", body);
//        mm.put("sign", MD5Util.getMD5(body + key + timestamp));
//        mm.put("timestamp", timestamp);
//
//        String requestBody = JSON.toJSONString(mm);
//        int contentLength = requestBody.getBytes(StandardCharsets.UTF_8).length;
//        Map<String, String> heardMap = new LinkedHashMap<>();
//        heardMap.put("Content-type", "application/json");
//        heardMap.put("Content-Length", String.valueOf(contentLength));
//
//        String baseUrl = "https://open.ugate.cc/Merchant/CreateBuyOrder";
//        Connection.Response response = HttpUtil.post(baseUrl, heardMap, mm);
//
//        JSONObject requestEntity = JSON.parseObject(response.body());
//        JSONObject jsonData = JSONObject.parseObject(requestEntity.get("data").toString());
//        String checkOutUrl = String.valueOf(jsonData.get("CheckOutUrl"));
//        String domain = String.valueOf(jsonData.get("Domain"));
//        String url = "https://" + domain + checkOutUrl;
//        System.out.println(url);
//
//        String body = "{\"MerchantUID\":\"311469\",\"OrderNo\":\"311469_YHK20251124065651046\"," +
//                "\"MerchantBuyOrderNo\":\"PD20251124005651599387_66780594\",
//                \"MerchantBuyOrderStatus\":\"E_FINISH\"," +
//                "\"MerchantBuyOrderMoney\":\"5370.00\",\"OrderFinishTime\":\"2025-11-24 07:53:26\"}";
//        String timestamp = "1763942068";
//        String secretKey = "";
//        UGatePayCallbackEntity callback = JSONObject.parseObject(body,
//                UGatePayCallbackEntity.class);
//        Map<String, Object> map = new LinkedHashMap<>();
//        map.put("MerchantUID", callback.getMerchantUID());
//        map.put("MerchantBuyOrderNo", callback.getMerchantBuyOrderNo());
//        map.put("MerchantBuyOrderStatus", callback.getMerchantBuyOrderStatus());
//        map.put("MerchantBuyOrderMoney", callback.getMerchantBuyOrderMoney());
//        map.put("OrderFinishTime", callback.getOrderFinishTime());
//        String signature = MD5Util.getMD5(body + secretKey + timestamp);
//
//        System.out.println(signature);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String pay(FinanceDepositAddEntity balanceSaveEntity) throws Exception {
        //通道配置
        SysRemittanceChannelTable channel = getPayChannel(balanceSaveEntity.getPayType());
        //通道配置实体
        UGatePayPropertyEntity payProperty = getPayProperty(channel, UGatePayPropertyEntity.class);

        balanceSaveEntity.setCurrency(channel.getCurrency());
        balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency());

        FinanceDepositTable balanceTable = financeDepositService.save(balanceSaveEntity, channel);

        String url = getUrl(payProperty, balanceTable, balanceSaveEntity);
        balanceTable.setFormUrl(url);
        
        return url;
    }

    @Override
    public String pay(FinanceMerchantDepositAddEntity balanceSaveEntity) throws Exception {
        //通道配置
        SysRemittanceChannelTable channel = getPayChannel(balanceSaveEntity.getPayType());
        //通道配置实体
        UGatePayPropertyEntity propertyEntity = getPayProperty(channel, UGatePayPropertyEntity.class);

        balanceSaveEntity.setCurrency(channel.getCurrency());
        balanceSaveEntity.setTransformCurrency(channel.getTransformCurrency());

        FinanceDepositTable balanceTable = financeDepositService.save(balanceSaveEntity, channel);

//        String url = getUrl(payProperty, balanceTable, balanceSaveEntity);
//        balanceTable.setFormUrl(url);
//        return url;

        String orderNo = balanceTable.getSerial() + "_" + balanceTable.getLogin();

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("MerchantUID", propertyEntity.getMerchantUID());
        map.put("MerchantBuyOrderNo", orderNo);
        map.put("MerchantBuyOrderMoney", String.format("%.2f", balanceTable.getTransformAmount().doubleValue()));
        map.put("MerchantBuyOrderUniqueCode", UUID.randomUUID().toString().replace("-", ""));
        switch (balanceSaveEntity.getBankCode()) {
            case PayConstants.UGATE_BANK:
                map.put("MerchantBuyOrderPayType", "1");
                break;
            case PayConstants.UGATE_WECHAT:
                map.put("MerchantBuyOrderPayType", "2");
                break;
            case PayConstants.UGATE_ALIPAY:
                map.put("MerchantBuyOrderPayType", "3");
                break;
            default:
                break;
        }
        map.put("MerchantBuyOrderPayerName", balanceSaveEntity.getName());
        map.put("MerchantBuyOrderPayerUID", balanceSaveEntity.getMerCustomId());
        map.put("JumpUrl", propertyEntity.getReturnUrl());

        String url = getUrl(propertyEntity, map);
//        String url = "https://xxx.xxx.com/pay.html";
        balanceTable.setFormUrl(url);
        return url;
    }

    /**
     * 回调处理数据
     *
     * @param callbackEntity
     * @throws ServiceException
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String callback(UGatePayCallbackEntity callbackEntity, String payType) throws Exception {
        log.info(String.format("callback data:%s", JSON.toJSONString(callbackEntity)));
        if (Strings.isNullOrEmpty(callbackEntity.getSign())) {
            return Constants.FAIL;
        }
        //获取配置
        UGatePayPropertyEntity payProperty = getPayProperty(payType,
                UGatePayPropertyEntity.class);
        String signature = getSign(payProperty.getSecretKey(), callbackEntity);
        if (!callbackEntity.getSign().equals(signature)) {
            return Constants.FAIL;
        }

        //验证传输数据
        UGatePayCallbackEntity callDataEntity = JSON.parseObject(callbackEntity.getBody(),
                UGatePayCallbackEntity.class);
        String orderStatus = callDataEntity.getMerchantBuyOrderStatus();
        int status = PayConstants.CALLBACE_PROCESSING_STATUS;
        if ("E_ADMIN_FINISH".equals(orderStatus) || "E_FINISH".equals(orderStatus)) {
            status = PayConstants.CALLBACE_SUCCESS_STATUS;
        } else if ("E_ADMIN_CANCEL".equals(orderStatus) || "E_CANCEL".equals(orderStatus)
                || "E_PAY_TIMEOUT".equals(orderStatus) || "E_RECEIVE_TIMEOUT".equals(orderStatus)) {
            status = PayConstants.CALLBACE_FAIL_STATUS;
        }

        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = payProperty.getSecretKey();
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("MerchantUID", payProperty.getMerchantUID());
        map.put("MerchantBuyOrderNo", callDataEntity.getMerchantBuyOrderNo());

        String body = JSON.toJSONString(map);

        Map<String, String> params = new HashMap<>();
        params.put("body", body);
        params.put("sign", MD5Util.getMD5(body + key + timestamp));
        params.put("timestamp", timestamp);

        String request = JSON.toJSONString(params);
        int contentLength = request.getBytes(StandardCharsets.UTF_8).length;
        Map<String, String> heardMap = new LinkedHashMap<>();
        heardMap.put("Content-type", "application/json");
        heardMap.put("Content-Length", String.valueOf(contentLength));

        Connection.Response response = HttpUtil.post(payProperty.getBaseUrl() + payProperty.getQueryUrl(), heardMap,
                params);
        log.info(String.format("url:%s,body:%s", payProperty.getBaseUrl() + payProperty.getQueryUrl(),
                response.body()));

        JSONObject requestEntity = JSON.parseObject(response.body());
        if (requestEntity == null || requestEntity.getInteger("code") != 200) {
            log.error("Ugate platform is abnormal, please try again later or contact customer service.");
            return Constants.FAIL;
        }
        JSONObject jsonData = JSONObject.parseObject(requestEntity.get("data").toString());

        if (!callDataEntity.getMerchantBuyOrderStatus().equals(jsonData.get("MerchantBuyOrderStatus").toString()) || !callDataEntity.getMerchantBuyOrderMoney().equals(jsonData.get("MerchantBuyOrderMoney").toString())) {
            return Constants.FAIL;
        }

        FinanceDepositCallbackUpdateEntity balanceCallbackUpdateEntity =
                getFinanceDepositCallbackUpdateEntity(callDataEntity.getMerchantBuyOrderNo(),
                        callDataEntity.getMerchantBuyOrderNo(),
                        status, callbackEntity);
        balanceCallbackUpdateEntity.setTransformAmount(new BigDecimal(callDataEntity.getMerchantBuyOrderMoney()));

        /**
         * 更新数据
         */
        financeDepositService.updateCallback(balanceCallbackUpdateEntity);
        return Constants.SUCCESS;
    }

    /**
     * 获取支付url
     *
     * @param balanceTable
     * @return
     * @throws ServiceException
     */
    private String getUrl(UGatePayPropertyEntity propertyEntity, FinanceDepositTable balanceTable,
                          FinanceDepositAddEntity balanceSaveEntity) throws ServiceException, IOException,
            PayValidatedException {
        String orderNo = balanceTable.getSerial() + "_" + balanceTable.getLogin();

        Map<String, Object> map = new LinkedHashMap<>();
        map.put("MerchantUID", propertyEntity.getMerchantUID());
        map.put("MerchantBuyOrderNo", orderNo);
        map.put("MerchantBuyOrderMoney", String.format("%.2f", balanceTable.getTransformAmount().doubleValue()));
        map.put("MerchantBuyOrderUniqueCode", UUID.randomUUID().toString().replace("-", ""));
        switch (balanceSaveEntity.getBankCode()) {
            case PayConstants.UGATE_BANK:
                map.put("MerchantBuyOrderPayType", "1");
                break;
            case PayConstants.UGATE_WECHAT:
                map.put("MerchantBuyOrderPayType", "2");
                break;
            case PayConstants.UGATE_ALIPAY:
                map.put("MerchantBuyOrderPayType", "3");
                break;
            default:
                break;
        }
        map.put("MerchantBuyOrderPayerName", balanceTable.getName());
        map.put("MerchantBuyOrderPayerUID", balanceTable.getCId());
        map.put("JumpUrl", propertyEntity.getReturnUrl());

//        String body = JSON.toJSONString(map);
//
//        Map<String, String> params = new HashMap<>();
//        params.put("body", body);
//        params.put("sign", MD5Util.getMD5(body + key + timestamp));
//        params.put("timestamp", timestamp);

//        String request = JSON.toJSONString(params);
//        int contentLength = request.getBytes(StandardCharsets.UTF_8).length;
//        Map<String, String> heardMap = new LinkedHashMap<>();
//        heardMap.put("Content-type", "application/json");
//        heardMap.put("Content-Length", String.valueOf(contentLength));
//
//        Connection.Response response = HttpUtil.post(propertyEntity.getBaseUrl() + propertyEntity.getCreateOrderUrl()
//                , heardMap, params);
//        log.info(String.format("url:%s,json:%s,body:%s",
//                propertyEntity.getBaseUrl() + propertyEntity.getCreateOrderUrl(), JSON.toJSON(params),
//                response.body()));
//
//        JSONObject requestEntity = JSON.parseObject(response.body());
//        if (requestEntity == null || requestEntity.getInteger("code") != 200) {
//            throw new PayValidatedException("Ugate platform is abnormal, please try again later or contact customer
//            " +
//                    "service.");
//        }
//        JSONObject jsonData = JSONObject.parseObject(requestEntity.get("data").toString());
//        String checkOutUrl = String.valueOf(jsonData.get("CheckOutUrl"));
//        String domain = String.valueOf(jsonData.get("Domain"));
//        String url = "https://" + domain + checkOutUrl;
//
//        log.info(String.format("支付请求,请求orderNo:%s,请求url:%s", map.get("MerchantBuyOrderNo"), url));
//
//        return url;

        return getUrl(propertyEntity, map);
    }

    private String getUrl(UGatePayPropertyEntity propertyEntity, Map<String, Object> map) throws ServiceException,
            IOException,
            PayValidatedException {

        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = propertyEntity.getSecretKey();

        String body = JSON.toJSONString(map);

        Map<String, String> params = new HashMap<>();
        params.put("body", body);
        params.put("sign", MD5Util.getMD5(body + key + timestamp));
        params.put("timestamp", timestamp);

        String request = JSON.toJSONString(params);
        int contentLength = request.getBytes(StandardCharsets.UTF_8).length;
        Map<String, String> heardMap = new LinkedHashMap<>();
        heardMap.put("Content-type", "application/json");
        heardMap.put("Content-Length", String.valueOf(contentLength));

        Connection.Response response = HttpUtil.post(propertyEntity.getBaseUrl() + propertyEntity.getCreateOrderUrl()
                , heardMap, params);
        log.info(String.format("url:%s,json:%s,body:%s",
                propertyEntity.getBaseUrl() + propertyEntity.getCreateOrderUrl(), JSON.toJSON(params),
                response.body()));

        JSONObject requestEntity = JSON.parseObject(response.body());
        if (requestEntity == null || requestEntity.getInteger("code") != 200) {
            if (!Strings.isNullOrEmpty(requestEntity.getString("msg"))) {
                throw new PayValidatedException(requestEntity.getString("msg"));
            }
            throw new PayValidatedException("Ugate platform is abnormal, please try again later or contact customer " +
                    "service.");
        }
        JSONObject jsonData = JSONObject.parseObject(requestEntity.get("data").toString());
        String checkOutUrl = String.valueOf(jsonData.get("CheckOutUrl"));
        String domain = String.valueOf(jsonData.get("Domain"));
        String url = "https://" + domain + checkOutUrl;

        log.info(String.format("支付请求,请求orderNo:%s,请求url:%s", map.get("MerchantBuyOrderNo"), url));

        return url;
    }

    @Override
    public FinanceWithdrawUGatePayDto withdrawInfo(FinanceWithdrawInfoEntity entity) throws Exception {
        FinanceWithdrawDto withdrawDto = null;
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            withdrawDto = financeWithdrawService.searchSingle(entity.getId());

        } else {
            //withdrawDto = financeAgentWithdrawService.searchSingle(entity.getId());
        }
        entity.setPayType(entity.getPayType());

        SysRemitChannelTable withdrawChannel = getWithdrawChannel(entity.getPayType());

        FinanceWithdrawUGatePayDto dto = new FinanceWithdrawUGatePayDto();
        dto.setReceiverName(withdrawDto.getName());
        dto.setMerchantSellOrderMoney(withdrawDto.getTransformAmount() == null ? null :
                withdrawDto.getTransformAmount().setScale(2, RoundingMode.DOWN).toString());
        dto.setReceiverAccount(withdrawDto.getBankCardNum());
        dto.setReceiverBankName(withdrawDto.getBankName());
        dto.setReceiverBankAddress(withdrawDto.getBankBranchName());

        dto.setId(withdrawDto.getId());
        dto.setWithdrawUrl(withdrawChannel.getWithdrawUrl());
        dto.setSerial(withdrawDto.getSerial());
        dto.setPayType(entity.getPayType());

        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String withdraw(FinanceWithdrawUGateEntity entity) throws Exception {
        FinanceWithdrawDto withdrawDto = null;
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            withdrawDto = financeWithdrawService.searchSingle(entity.getId());
        } else {
            //withdrawDto = financeAgentWithdrawService.searchSingle(entity.getId());
        }
        entity.setCId(withdrawDto.getCId());
        entity.setSerial(withdrawDto.getSerial());
        entity.setLogin(withdrawDto.getLogin());

        UGateWithdrawPropertyEntity proxpayWithdrawProperty = getWithdrawProperty(entity.getPayType(),
                UGateWithdrawPropertyEntity.class);

        payout(entity, proxpayWithdrawProperty);

        FinanceWithdrawApproveChannelSubmitEntity financeWithdrawApproveChannelSubmitEntity =
                new FinanceWithdrawApproveChannelSubmitEntity();
        financeWithdrawApproveChannelSubmitEntity.setSubmitStatus(PayConstants.PASSED_STATUS);
        financeWithdrawApproveChannelSubmitEntity.setId(entity.getId());
        financeWithdrawApproveChannelSubmitEntity.setActualPayType(entity.getPayType());
        if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
            financeWithdrawService.approve(financeWithdrawApproveChannelSubmitEntity);

        } else {
            //financeAgentWithdrawService.approve(financeWithdrawApproveChannelSubmitEntity);
        }

        // 发送mq，延迟一小时查询出金订单状态
        UGagePayWithdrawQueryEntity queryEntity = new UGagePayWithdrawQueryEntity();
        queryEntity.setMerchantSellOrderNo(entity.getSerial());
        queryEntity.setWithdrawInfoType(entity.getWithdrawInfoType());
        queryEntity.setPayType(entity.getPayType());
        mqSendService.send(PayConstants.UGATE_PAY_WITHDRAW_QUERY_CALLBACK, JSONObject.toJSONString(queryEntity),
                60 * 60 * 1000);

        return null;
    }

    private void payout(FinanceWithdrawUGateEntity entity, UGateWithdrawPropertyEntity propertyEntity) throws ServiceException, IOException, PayValidatedException {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = propertyEntity.getSecretKey();
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("MerchantUID", propertyEntity.getMerchantUID());
        map.put("MerchantSellOrderMoney", entity.getMerchantSellOrderMoney());
        map.put("MerchantSellOrderNo", entity.getSerial());
        map.put("ReceiverName", entity.getReceiverName());
        map.put("ReceiverAccount", entity.getReceiverAccount());
        map.put("ReceiverBankName", entity.getReceiverBankName());
        map.put("ReceiverBankAddress", entity.getReceiverBankAddress());

        String body = JSON.toJSONString(map);

        Map<String, String> params = new HashMap<>();
        params.put("body", body);
        params.put("sign", MD5Util.getMD5(body + key + timestamp));
        params.put("timestamp", timestamp);

        String request = JSON.toJSONString(params);
        int contentLength = request.getBytes(StandardCharsets.UTF_8).length;
        Map<String, String> heardMap = new LinkedHashMap<>();
        heardMap.put("Content-type", "application/json");
        heardMap.put("Content-Length", String.valueOf(contentLength));

        Connection.Response response = HttpUtil.post(propertyEntity.getBaseUrl() + propertyEntity.getWithdrawUrl(),
                heardMap, params);
        log.info(String.format("url:%s,json:%s,body:%s",
                propertyEntity.getBaseUrl() + propertyEntity.getWithdrawUrl(), JSON.toJSON(params), response.body()));

        JSONObject requestEntity = JSON.parseObject(response.body());
        if (requestEntity == null || requestEntity.getInteger("code") != 200) {
            log.error("UGate:" + requestEntity.toString());
            throw new PayValidatedException("Ugate platform is abnormal, please try again later or contact customer " +
                    "service.");
        }
    }

    private Integer payoutQuery(UGagePayWithdrawQueryEntity queryEntity, UGateWithdrawPropertyEntity propertyEntity) throws ServiceException, IOException, PayValidatedException {
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = propertyEntity.getSecretKey();
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("MerchantSellOrderNo", queryEntity.getMerchantSellOrderNo());
        map.put("MerchantUID", propertyEntity.getMerchantUID());

        String body = JSON.toJSONString(map);

        Map<String, String> params = new HashMap<>();
        params.put("body", body);
        params.put("sign", MD5Util.getMD5(body + key + timestamp));
        params.put("timestamp", timestamp);

        String request = JSON.toJSONString(params);
        int contentLength = request.getBytes(StandardCharsets.UTF_8).length;
        Map<String, String> heardMap = new LinkedHashMap<>();
        heardMap.put("Content-type", "application/json");
        heardMap.put("Content-Length", String.valueOf(contentLength));

        Connection.Response response = HttpUtil.post(propertyEntity.getBaseUrl() + propertyEntity.getQueryUrl(),
                heardMap, params);
        log.info(String.format("url:%s,json:%s,body:%s",
                propertyEntity.getBaseUrl() + propertyEntity.getWithdrawUrl(), JSON.toJSON(params), response.body()));

        JSONObject requestEntity = JSON.parseObject(response.body());
        if (requestEntity == null || requestEntity.getInteger("code") != 200) {
            log.error("UGate:" + requestEntity.toString());
            throw new PayValidatedException("Ugate platform is abnormal, please try again later or contact customer " +
                    "service.");
        }

        if ("E_ADMIN_FINISH".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "E_FINISH".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "E_ADMIN_FINISH".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "E_FINISH".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus"))) {
            return PayConstants.CALLBACE_SUCCESS_STATUS;
        }
        if ("T_CONFIRM_PAY_TODO".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "T_CONFIRM_RECEIVE_TODO".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "T_MATCH_TODO".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "E_SELLER_CANCEL".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus")) ||
                "T_MERCHANT_VERIFY_TODO".equals(requestEntity.getJSONObject("data").get("MerchantSellOrderStatus"))) {
            mqSendService.send(PayConstants.UGATE_PAY_WITHDRAW_QUERY_CALLBACK, JSONObject.toJSONString(queryEntity),
                    60 * 60 * 1000);
            return PayConstants.CALLBACE_PROCESSING_STATUS;
        }
        return PayConstants.CALLBACE_FAIL_STATUS;
    }

    @JmsListener(destination = PayConstants.UGATE_PAY_WITHDRAW_QUERY_CALLBACK)
    public void withdrawCallback(String content) throws Exception {
        log.info(String.format("UGATE_PAY_WITHDRAW_QUERY_CALLBACK,content:%s", content));
        UGagePayWithdrawQueryEntity entity = JSON.parseObject(content, UGagePayWithdrawQueryEntity.class);

        if (entity == null || StringUtils.isEmpty(entity.getMerchantSellOrderNo())) {
            log.error("UGATE_PAY_WITHDRAW_QUERY_CALLBACK,entity is null");
            return;
        }

        FinanceWithdrawTable table = financeWithdrawRepository.getFirstBySerial(entity.getMerchantSellOrderNo());


        if (table != null &&
                PayConstants.CALLBACE_PROCESSING_STATUS.equals(table.getCallbackStatus())) {
            UGateWithdrawPropertyEntity proxpayWithdrawProperty = getWithdrawProperty(entity.getPayType(),
                    UGateWithdrawPropertyEntity.class);

            Integer callbackStatus = payoutQuery(entity, proxpayWithdrawProperty);

            if (PayConstants.CALLBACE_PROCESSING_STATUS.equals(callbackStatus)) {
                return;
            }

            FinanceWithdrawApproveChannelEntity financeWithdrawApproveChannelEntity =
                    new FinanceWithdrawApproveChannelEntity();
            financeWithdrawApproveChannelEntity.setChannelSerial(entity.getMerchantSellOrderNo());
            financeWithdrawApproveChannelEntity.setCallbackStatus(callbackStatus);
            financeWithdrawApproveChannelEntity.setSerial(entity.getMerchantSellOrderNo());

            /**
             * 更新数据
             */
            if (entity.getWithdrawInfoType() == null || entity.getWithdrawInfoType().equals(1)) {
                financeWithdrawService.approve(financeWithdrawApproveChannelEntity);
            } else {
                //financeAgentWithdrawService.channel(financeWithdrawApproveChannelEntity);
            }
        }

    }

    /**
     * 回调请求加密sign
     */
    private String getSign(String secretKey, UGatePayCallbackEntity callbackEntity) {
        UGatePayCallbackEntity callback = JSONObject.parseObject(callbackEntity.getBody(),
                UGatePayCallbackEntity.class);
//        Map<String, Object> map = new LinkedHashMap<>();
//        map.put("MerchantUID", callback.getMerchantUID());
//        map.put("MerchantBuyOrderNo", callback.getMerchantBuyOrderNo());
//        map.put("MerchantBuyOrderStatus", callback.getMerchantBuyOrderStatus());
//        map.put("MerchantBuyOrderMoney", callback.getMerchantBuyOrderMoney());
//        map.put("OrderFinishTime", callback.getOrderFinishTime());
        String signature = MD5Util.getMD5(callbackEntity.getBody() + secretKey + callbackEntity.getTimestamp());

        log.info(String.format("回调结果加密处理--请求orderNo:%s,sign:%s", callback.getMerchantBuyOrderNo(), signature));

        return signature;
    }

}



