package com.hfkj.channel.lakala;

import com.alibaba.fastjson.JSONObject;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.config.CommonSysConst;
import com.hfkj.entity.*;
import com.hfkj.channel.lakala.config.LaKaLaConfig;
import com.hfkj.service.*;
import com.hfkj.sysenum.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 拉卡拉交易 服务
 * @author hurui
 */
@Service("lklTradeService")
public class LaKaLaTradeService {

    private static Logger log = LoggerFactory.getLogger(LaKaLaTradeService.class);

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private BsTradeOrderRefundService tradeOrderRefundService;

    @Resource
    private BsTradeOrderMsgService tradeOrderMsgService;

    @Resource
    private BsMerPlatformNoService merPlatformNoService;

    @Resource
    private BsMerPlatformTermService merPlatformTermService;

    @Resource
    private BsMerService merService;

    @Resource
    private BsMerPlatformNoRateService merPlatformNoRateService;

    @Resource
    private LaKaLaTradeSeparateService laKaLaTradeSeparateService;

    @Resource
    private BsTradeOrderProfitSharingService tradeOrderProfitSharingService;


    /**
     * 交易【被扫】
     * @param tradeNo 订单号
     * @param authCode   授权码、条码
     */
    public Map<String, Object> microPay(String tradeNo,String authCode) {
        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
        }
        if (!order.getStatus().equals(TradeOrderStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于待支付状态");
        }
        // 查询商户号
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type1);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
        }
        // 查询终端号
        BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "QR_CODE_CARD");
        if (merPlatformTerm == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
        }

        // 比例
        BsMerPlatformNoRate rate = merPlatformNoRateService.getDetail(order.getMerId(), PlatformTypeEnum.type1.getNumber(), null);
        if (rate != null) {
            order.setProfitSharingStatus(true);
        } else {
            order.setProfitSharingStatus(false);
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");
        commonParam.put("out_org_code", CommonSysConst.getSysConfig().getLkl_v3_appid());

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", platformNo.getCupNo());
        map.put("term_no", merPlatformTerm.getTermNo());
        map.put("out_trade_no", order.getOutTradeNo());
        map.put("auth_code", authCode);
        map.put("total_amount", order.getTradeActualAmount().multiply(new BigDecimal("100")).intValue());
        map.put("notify_url", CommonSysConst.getSysConfig().getLkl_micro_pay_ret_url());
        map.put("settle_type", order.getProfitSharingStatus().equals(true)?"1":"0");

        Map<String, Object> locationInfo = new HashMap<>();
        locationInfo.put("request_ip", "10.176.1.192");
        map.put("location_info", locationInfo);

        commonParam.put("req_data", map);
        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        // 请求记录
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("Authorization", reqParam.get("Authorization"));
        requestMap.put("req_data", JSONObject.toJSONString(commonParam));
        BsTradeOrderMsg orderMsg = new BsTradeOrderMsg();
        orderMsg.setOutTradeNo(tradeNo);
        orderMsg.setType(TradeOrderMsgTypeEnum.type1.getNumber());
        orderMsg.setRequestContent(JSONObject.toJSONString(requestMap));
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        // 请求拉卡拉接口
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/labs/trans/micropay", commonParam, heard);
        orderMsg.setResponseContent(responseBody.toJSONString());
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        if (!responseBody.getString("code").equals("BBS00000")
                && !responseBody.getString("code").equals("BBS10000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }

        JSONObject data = responseBody.getJSONObject("resp_data");
        if (responseBody.getString("code").equals("BBS00000")) {
            order.setPayMode(data.getString("account_type"));
            order.setPlatformType(PlatformTypeEnum.type1.getNumber());
            order.setPlatformMerNo(platformNo.getCupNo());
            order.setPlatformTradeNo(data.getString("trade_no"));
            order.setPlatformLogNo(data.getString("log_no"));
            order.setAccTradeNo(data.getString("acc_trade_no"));
            order.setTradeActualAmount(data.getBigDecimal("payer_amount").divide(new BigDecimal("100")));
            order.setCardType(data.getString("card_type"));
            order.setStatus(TradeOrderStatusEnum.status3.getNumber());
            order.setPayTime(new Date());
            if (StringUtils.isNotBlank(data.getString("acc_discount_amount"))) {
                order.setAccDiscountAmount(data.getBigDecimal("acc_discount_amount").divide(new BigDecimal("100")));
            }
            if (StringUtils.isNotBlank(data.getString("acc_mdiscount_amount"))) {
                order.setAccMdiscountAmount(data.getBigDecimal("acc_mdiscount_amount").divide(new BigDecimal("100")));
            }
            order.setAccPaymentCode(authCode);
            tradeOrderService.editOrder(order);
        }

        if (responseBody.getString("code").equals("BBS10000")) {
            order.setPlatformType(PlatformTypeEnum.type1.getNumber());
            order.setPlatformMerNo(platformNo.getCupNo());
            order.setPlatformTradeNo(data.getString("trade_no"));
            order.setPlatformLogNo(data.getString("log_no"));
            order.setStatus(TradeOrderStatusEnum.status2.getNumber());
            order.setAccPaymentCode(authCode);
            tradeOrderService.editOrder(order);
        }

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("order", order);
        return returnMap;
    }

    /**
     * 交易【主扫】
     * @param tradeNo 订单号
     */
    public Map<String, Object> preorder(String tradeNo) {
        log.info("========= Start 交易【主扫】 Start ===========");
        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
        }
        if (!order.getStatus().equals(TradeOrderStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于待支付状态");
        }
        // 查询商户号
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type1);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
        }
        // 查询终端号
        BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
        if (merPlatformTerm == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
        }
        // 查询商户
        BsMer mer = merService.getMer(order.getMerId());
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户信息");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");
        commonParam.put("out_org_code", CommonSysConst.getSysConfig().getLkl_v3_appid());

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", platformNo.getCupNo());
        map.put("term_no", merPlatformTerm.getTermNo());
        map.put("out_trade_no", order.getOutTradeNo());
        map.put("account_type", order.getPayMode());
        map.put("trans_type", order.getTransType().equals("JSAPI")?51:41);
        map.put("total_amount", order.getTradeActualAmount().multiply(new BigDecimal("100")).intValue());
        map.put("settle_type", order.getProfitSharingStatus()==true?1:0);
        if (StringUtils.isNotBlank(order.getSubject())) {
            map.put("subject", order.getSubject());
        } else {
            map.put("subject", mer.getMerAbbreviate());
        }
        if (order.getCreateType() != null && order.getCreateType().equals(TradeOrderCreateTypeEnum.type3.getCode())) {
            map.put("notify_url", CommonSysConst.getSysConfig().getLkl_open_api_pay_notify_url());
        } else {
            map.put("notify_url", CommonSysConst.getSysConfig().getLkl_micro_pay_ret_url());
        }
        Map<String, Object> locationInfo = new HashMap<>();
        if (StringUtils.isNotBlank(order.getRequestIp())) {
            locationInfo.put("request_ip", order.getRequestIp());
        } else {
            locationInfo.put("request_ip", "0.0.0.0");
        }
        map.put("location_info", locationInfo);

        Map<String, Object> accBusiFieldsMap = new HashMap<>();
        if (order.getTimeoutExpress() != null) {
            accBusiFieldsMap.put("timeout_express", order.getTimeoutExpress());
        }
        if (order.getPayMode().equals(TradeOrderPayModeEnum.WECHAT.getCode())) {
            if (StringUtils.isBlank(order.getPayAppid())) {
                accBusiFieldsMap.put("sub_appid", "wxa075e8509802f826");
            } else {
                accBusiFieldsMap.put("sub_appid", order.getPayAppid());
            }
        } else if (order.getPayMode().equals(TradeOrderPayModeEnum.UQRCODEPAY.getCode())) {
            accBusiFieldsMap.put("customerIp", order.getPayAppid());
        }
        accBusiFieldsMap.put("user_id", order.getPayUserId());
        map.put("acc_busi_fields", accBusiFieldsMap);

        commonParam.put("req_data", map);
        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        // 请求记录
        log.info("请求参数：", JSONObject.toJSONString(commonParam));
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("Authorization", reqParam.get("Authorization"));
        requestMap.put("req_data", JSONObject.toJSONString(commonParam));
        BsTradeOrderMsg orderMsg = new BsTradeOrderMsg();
        orderMsg.setOutTradeNo(tradeNo);
        orderMsg.setType(TradeOrderMsgTypeEnum.type1.getNumber());
        orderMsg.setRequestContent(JSONObject.toJSONString(requestMap));
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        // 请求拉卡拉接口
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/labs/trans/preorder", commonParam, heard);
        log.info("响应参数：", JSONObject.toJSONString(responseBody));
        orderMsg.setResponseContent(responseBody.toJSONString());
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);
        if (!responseBody.getString("code").equals("BBS00000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("order", order);
        returnMap.put("payMode", order.getPayMode());
        returnMap.put("platformType", PlatformTypeEnum.type1.getNumber());
        returnMap.put("payParam", responseBody.getJSONObject("resp_data"));
        log.info("========= END 交易【主扫】 END ===========");

        return returnMap;
    }

    /**
     * 查询交易
     * @param tradeNo 订单号
     */
    public JSONObject queryTrade(String tradeNo) {
        log.info("========= Start 交易查询 Start ===========");
        try {
            // 查询交易订单
            BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
            }
            // 查询商户号
            BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type1);
            if (platformNo == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
            }
            // 查询终端号
            BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
            if (merPlatformTerm == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
            }
            Map<String, Object> commonParam = new HashMap<>();
            commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
            commonParam.put("version", "3.0");
            commonParam.put("out_org_code", CommonSysConst.getSysConfig().getLkl_v3_appid());

            Map<String, Object> map = new HashMap<>();
            map.put("merchant_no", order.getPlatformMerNo());
            map.put("term_no", merPlatformTerm.getTermNo());
            map.put("out_trade_no", order.getOutTradeNo());
            commonParam.put("req_data", map);

            Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

            // 头部参数
            Map<String, Object> heard = new HashMap<>();
            heard.put("Authorization", reqParam.get("Authorization"));

            // 请求记录
            // 请求拉卡拉接口
            JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/labs/query/tradequery", commonParam, heard);
            log.info("请求参数："+ JSONObject.toJSONString(commonParam));
            log.info("响应参数："+ JSONObject.toJSONString(responseBody));
            System.out.println("请求参数："+ JSONObject.toJSONString(commonParam));
            System.out.println("响应参数："+ JSONObject.toJSONString(responseBody));
            if (!responseBody.getString("code").equals("BBS00000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
            }
            return responseBody.getJSONObject("resp_data");

        } catch (Exception e) {
            return null;
        } finally {
            log.info("========= END 交易查询 END ===========");
        }
    }

    /**
     * 商户计费查询
     * @param tradeNo 订单号
     */
    public JSONObject queryTradeOrderTrans(String tradeNo) {
        log.info("========= Start 商户计费查询 Start ===========");
        try {
            // 查询交易订单
            BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
            if (order == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
            }
            // 查询商户号
            BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type1);
            if (platformNo == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
            }
            // 查询终端号
            BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
            if (merPlatformTerm == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
            }
            Map<String, Object> commonParam = new HashMap<>();
            commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
            commonParam.put("version", "3.0");

            Map<String, Object> map = new HashMap<>();
            map.put("merchant_no", platformNo.getCupNo());
            map.put("term_no", merPlatformTerm.getTermNo());
            map.put("log_no", order.getPlatformLogNo());
            commonParam.put("req_data", map);

            Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

            // 头部参数
            Map<String, Object> heard = new HashMap<>();
            heard.put("Authorization", reqParam.get("Authorization"));

            // 请求记录
            // 请求拉卡拉接口
            JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/lams/merchant/query_trans", commonParam, heard);
            log.info("请求参数："+ JSONObject.toJSONString(commonParam));
            log.info("响应参数："+ JSONObject.toJSONString(responseBody));
            System.out.println("请求参数："+ JSONObject.toJSONString(commonParam));
            System.out.println("响应参数："+ JSONObject.toJSONString(responseBody));
            if (!responseBody.getString("code").equals("000000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
            }
            return responseBody.getJSONObject("resp_data");

        } catch (Exception e) {
            return null;
        } finally {
            log.info("========= END 商户计费查询 END ===========");
        }
    }

    /**
     * 商户计费查询
     * @param refundNo 订单号
     */
    public JSONObject queryTradeOrderRefundTrans(String refundNo) {
        log.info("========= Start 商户计费查询 Start ===========");
        try {
            // 查询交易订单
            BsTradeOrderRefund orderRefund = tradeOrderRefundService.getRefundByRefundNo(refundNo);
            if (orderRefund == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易退款订单");
            }
            // 查询商户号
            BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(orderRefund.getMerId(), PlatformTypeEnum.type1);
            if (platformNo == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
            }
            // 查询终端号
            BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
            if (merPlatformTerm == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
            }
            Map<String, Object> commonParam = new HashMap<>();
            commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
            commonParam.put("version", "3.0");

            Map<String, Object> map = new HashMap<>();
            map.put("merchant_no", platformNo.getCupNo());
            map.put("term_no", merPlatformTerm.getTermNo());
            map.put("log_no", orderRefund.getPlatformLogNo());
            commonParam.put("req_data", map);

            Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

            // 头部参数
            Map<String, Object> heard = new HashMap<>();
            heard.put("Authorization", reqParam.get("Authorization"));

            // 请求记录
            // 请求拉卡拉接口
            JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/lams/merchant/query_trans", commonParam, heard);
            log.info("请求参数："+ JSONObject.toJSONString(commonParam));
            log.info("响应参数："+ JSONObject.toJSONString(responseBody));
            System.out.println("请求参数："+ JSONObject.toJSONString(commonParam));
            System.out.println("响应参数："+ JSONObject.toJSONString(responseBody));
            if (!responseBody.getString("code").equals("000000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
            }
            return responseBody.getJSONObject("resp_data");

        } catch (Exception e) {
            return null;
        } finally {
            log.info("========= END 商户计费查询 END ===========");
        }
    }

    /**
     * 退款
     * @param refundNo 订单号
     */
    public Map<String, Object> refund(String refundNo,BigDecimal refundAmount) {
        log.info("========= Start 交易退款 Start ===========");
        // 查询交易订单
        BsTradeOrderRefund orderRefund = tradeOrderRefundService.getRefundByRefundNo(refundNo);
        if (orderRefund == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
        }
        if (!orderRefund.getStatus().equals(TradeOrderRefundStatusEnum.status1.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于退款中状态");
        }
        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(orderRefund.getOutTradeNo());
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到交易订单");
        }
        // 查询商户号
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(orderRefund.getMerId(), PlatformTypeEnum.type1);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
        }
        // 查询终端号
        BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "WECHAT_PAY");
        if (merPlatformTerm == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");
        commonParam.put("out_org_code", CommonSysConst.getSysConfig().getLkl_v3_appid());

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", platformNo.getCupNo());
        map.put("term_no", merPlatformTerm.getTermNo());
        map.put("out_trade_no", orderRefund.getRefundNo());
        map.put("origin_trade_no", order.getPlatformTradeNo());
        map.put("refund_amount", refundAmount.multiply(new BigDecimal("100")).intValue());

        if (StringUtils.isNotBlank(orderRefund.getRefundReason())) {
            map.put("refund_reason",orderRefund.getRefundReason());
        }

        Map<String, Object> locationInfo = new HashMap<>();
        locationInfo.put("request_ip", "10.176.1.192");
        map.put("location_info", locationInfo);

        commonParam.put("req_data", map);
        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        // 请求记录
        log.info("请求参数：", JSONObject.toJSONString(commonParam));
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("Authorization", reqParam.get("Authorization"));
        requestMap.put("req_data", JSONObject.toJSONString(commonParam));
        BsTradeOrderMsg orderMsg = new BsTradeOrderMsg();
        orderMsg.setOutTradeNo(refundNo);
        orderMsg.setType(TradeOrderMsgTypeEnum.type1.getNumber());
        orderMsg.setRequestContent(JSONObject.toJSONString(requestMap));
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        // 是否分账
        if (order.getProfitSharingStatus().equals(true)) {
            // 查询分账记录
            BsTradeOrderProfitSharing tradeOrderProfitSharing = tradeOrderProfitSharingService.getProfitSharingByTradeOrderId(ProfitSharingCmdTypeEnum.CMD_TYPE_1, order.getId());
            if (tradeOrderProfitSharing != null && tradeOrderProfitSharing.getStatus().equals(ProfitSharingStatusEnum.status3.getNumber())) {
                laKaLaTradeSeparateService.cancel(tradeOrderProfitSharing.getProfitSharingOrderNo());
            }
        }

        // 请求拉卡拉退款接口
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/labs/relation/refund", commonParam, heard);
        log.info("响应参数：", JSONObject.toJSONString(responseBody));
        orderMsg.setResponseContent(responseBody.toJSONString());
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        if (!responseBody.getString("code").equals("BBS00000")
                && !responseBody.getString("code").equals("BBS10000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }

        JSONObject data = responseBody.getJSONObject("resp_data");
        if (responseBody.getString("code").equals("BBS00000")) {
            orderRefund.setPlatformOrderNo(data.getString("trade_no"));
            orderRefund.setPlatformLogNo(data.getString("log_no"));
            orderRefund.setAccTradeNo(data.getString("acc_trade_no"));
            orderRefund.setTotalAmount(data.getBigDecimal("total_amount").divide(new BigDecimal("100")));
            orderRefund.setRefundAmount(data.getBigDecimal("refund_amount").divide(new BigDecimal("100")));
            orderRefund.setPayerAmount(data.getBigDecimal("payer_amount").divide(new BigDecimal("100")));
            orderRefund.setRefundTime(new Date());
            orderRefund.setStatus(TradeOrderRefundStatusEnum.status2.getNumber());
            tradeOrderRefundService.editOrderRefund(orderRefund);

            order.setStatus(TradeOrderStatusEnum.status6.getNumber());
            tradeOrderService.editOrder(order);
        }

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("order", order);
        returnMap.put("orderRefund", orderRefund);
        log.info("========= END 交易退款 END ===========");
        return returnMap;
    }

    /**
     * 关单
     * @param tradeNo 订单号
     */
    public Map<String, Object> close(String tradeNo) {
        // 查询交易订单
        BsTradeOrder order = tradeOrderService.getOrderByOutTradeNo(tradeNo);
        if (order == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到订单");
        }
        if (!order.getStatus().equals(TradeOrderStatusEnum.status2.getNumber())) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "订单不处于支付中状态");
        }
        // 查询商户号
        BsMerPlatformNo platformNo = merPlatformNoService.getPlatformNo(order.getMerId(), PlatformTypeEnum.type1);
        if (platformNo == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户号");
        }
        // 查询终端号
        BsMerPlatformTerm merPlatformTerm = merPlatformTermService.getMerPlatformTerm(platformNo.getId(), "QR_CODE_CARD");
        if (merPlatformTerm == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到商户终端号");
        }

        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("req_time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("version", "3.0");
        commonParam.put("out_org_code", CommonSysConst.getSysConfig().getLkl_v3_appid());

        Map<String, Object> map = new HashMap<>();
        map.put("merchant_no", platformNo.getCupNo());
        map.put("term_no", merPlatformTerm.getTermNo());
        map.put("origin_out_trade_no", order.getOutTradeNo());
        Map<String, Object> locationInfo = new HashMap<>();
        locationInfo.put("request_ip", "10.176.1.192");
        map.put("location_info", locationInfo);

        commonParam.put("req_data", map);
        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV3(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        // 请求记录
        Map<String, Object> requestMap = new HashMap<>();
        requestMap.put("Authorization", reqParam.get("Authorization"));
        requestMap.put("req_data", JSONObject.toJSONString(commonParam));
        BsTradeOrderMsg orderMsg = new BsTradeOrderMsg();
        orderMsg.setOutTradeNo(tradeNo);
        orderMsg.setType(TradeOrderMsgTypeEnum.type3.getNumber());
        orderMsg.setRequestContent(JSONObject.toJSONString(requestMap));
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        // 请求拉卡拉接口
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v3/labs/relation/close", commonParam, heard);
        orderMsg.setResponseContent(responseBody.toJSONString());
        tradeOrderMsgService.editTradeOrderMsg(orderMsg);

        if (!responseBody.getString("code").equals("BBS00000")
                && !responseBody.getString("code").equals("BBS10000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, responseBody.getString("msg"));
        }

        if (responseBody.getString("code").equals("BBS00000")) {
            order.setStatus(TradeOrderStatusEnum.status5.getNumber());
            order.setCancelTime(new Date());
            tradeOrderService.editOrder(order);
        }

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("order", order);
        return returnMap;
    }

    /**
     * opendId查询
     * @param mercId 商户号
     * @param termNo 终端号
     * @param authCode  微信付款码 微信：付款码  银联二维码：付款方返回的临时授权码，一次有效
     * @param tradeCode 交易码 微信：010304   银联：030304
     * @param subAppid 	微信子商户公众号id
     * @param appUpIdentifier 银联支付标识,获取银联钱包userId时，必传
     */
    public Map<String, Object> openidQuery(String mercId,String termNo,String authCode, String tradeCode,String subAppid,String appUpIdentifier) {
        Map<String, Object> commonParam = new HashMap<>();
        commonParam.put("timestamp", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
        commonParam.put("ver", "1.0.0");
        commonParam.put("reqId", LaKaLaConfig.makeNonStr());

        Map<String, Object> map = new HashMap<>();
        map.put("mercId", mercId);
        map.put("termNo", termNo);
        map.put("authCode", authCode);
        map.put("tradeCode", tradeCode);
        map.put("subAppid", subAppid);
        map.put("appUpIdentifier", appUpIdentifier);

        commonParam.put("reqData", map);
        Map<String, Object> reqParam = LaKaLaConfig.generateSignParamsV2(JSONObject.parseObject(JSONObject.toJSONString(commonParam)));

        System.out.println(JSONObject.toJSONString(commonParam));

        // 头部参数
        Map<String, Object> heard = new HashMap<>();
        heard.put("Authorization", reqParam.get("Authorization"));

        // 请求拉卡拉接口
        JSONObject responseBody = HttpsUtils.doPost(CommonSysConst.getSysConfig().getLkl_request_url() + "/api/v2/saas/query/wx_openid_query", commonParam, heard);
        return responseBody;
    }

}
