package cn.freemud.service.impl;

import cn.freemud.adapter.OrderAdapter;
import cn.freemud.base.entity.BaseResponse;
import cn.freemud.base.util.DateUtil;
import cn.freemud.constant.KgdRedisKeyConstant;
import cn.freemud.constant.RedisKeyConstant;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.SvcComPayRequestDto;
import cn.freemud.entities.dto.SvcComPayResponseDto;
import cn.freemud.entities.dto.order.CreateOrderOperateDto;
import cn.freemud.entities.dto.order.CreatePrepayRequestDto;
import cn.freemud.entities.dto.order.FacePayRequestDto;
import cn.freemud.entities.dto.order.FacePayResponseDto;
import cn.freemud.entities.dto.pay.*;
import cn.freemud.entities.dto.pay.svc.SVCCardAmountRequestDto;
import cn.freemud.entities.dto.pay.svc.SVCCardAmountResponseDto;
import cn.freemud.entities.dto.shoppingCart.ShoppingCartGoodsDto;
import cn.freemud.entities.vo.CreateOrderResponseVo;
import cn.freemud.entities.vo.CreateOrderVo;
import cn.freemud.entities.vo.PaysuccessNoticeMessage;
import cn.freemud.enums.*;
import cn.freemud.interceptor.ServiceException;
import cn.freemud.management.entities.dto.request.BatchOrderRefundV2Request;
import cn.freemud.management.entities.dto.response.pay.PayBatchRefundResponse;
import cn.freemud.management.thirdparty.MulitiPaymentClient;
import cn.freemud.redis.RedisCache;
import cn.freemud.service.thirdparty.ComPayClient;
import cn.freemud.service.thirdparty.PaymentNewClient;
import cn.freemud.service.thirdparty.SvcAppClient;
import cn.freemud.service.thirdparty.SvcComPayClient;
import cn.freemud.utils.AppLogUtil;
import cn.freemud.utils.RedisUtil;
import cn.freemud.utils.ResponseUtil;
import cn.freemud.utils.ValidationCode;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformIappWxappStore;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartner;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformPartnerConfig;
import com.freemud.api.assortment.datamanager.entity.db.AssortmentOpenPlatformWxapp;
import com.freemud.api.assortment.datamanager.entity.vo.AssortmentCustomerInfoVo;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformIappWxappStoreManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerConfigManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformPartnerManager;
import com.freemud.api.assortment.datamanager.manager.AssortmentOpenPlatformWxappManager;
import com.freemud.application.sdk.api.base.SDKCommonBaseContextWare;
import com.freemud.application.sdk.api.constant.ResponseResultEnum;
import com.freemud.application.sdk.api.log.LogThreadLocal;
import com.freemud.application.sdk.api.ordercenter.entities.v1.OrderBeanV1;
import com.freemud.application.sdk.api.ordercenter.entities.v1.ProductBeanV1;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.enums.OrderClientType;
import com.freemud.application.sdk.api.ordercenter.enums.PayChannelType;
import com.freemud.application.sdk.api.ordercenter.enums.PayStatusEnum;
import com.freemud.application.sdk.api.ordercenter.request.OrderCancelReq;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import com.freemud.application.sdk.api.ordercenter.request.UpdateOrderReq;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderPayItemResp;
import com.freemud.application.sdk.api.ordercenter.service.OrderSdkService;
import com.freemud.application.sdk.api.paymentcenter.client.request.CodePayRequest;
import com.freemud.application.sdk.api.paymentcenter.client.request.PaymentCloseUnifiedOrderRequest;
import com.freemud.application.sdk.api.paymentcenter.client.request.PaymentQueryRequest;
import com.freemud.application.sdk.api.paymentcenter.client.response.CodePayResponse;
import com.freemud.application.sdk.api.paymentcenter.client.response.PaymentCloseUnifiedOrderResponse;
import com.freemud.application.sdk.api.paymentcenter.client.response.PaymentQueryResponse;
import com.freemud.application.sdk.api.paymentcenter.client.service.PaymentNewService;
import com.freemud.application.sdk.api.storecenter.response.StoreResponse;
import com.freemud.sdk.api.assortment.order.request.order.CancelOrderRequest;
import com.freemud.sdk.api.assortment.order.request.order.MultiOrderRefundRequest;
import com.freemud.sdk.api.assortment.order.request.order.OrderEditRequest;
import com.freemud.sdk.api.assortment.order.request.order.PaymentRequest;
import com.freemud.sdk.api.assortment.order.request.payment.CombPayRequest;
import com.freemud.sdk.api.assortment.order.response.order.MultiOrderRefundResponse;
import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest;
import com.freemud.sdk.api.assortment.payment.response.OrderRefundResponse;
import com.freemud.sdk.api.assortment.payment.response.UnifiedOrderResponse;
import com.freemud.sdk.api.assortment.payment.service.StandardPaymentService;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class PayServiceImpl {

    @Autowired
    private StandardPaymentService standardPaymentService;
    @Autowired
    private PaymentNewService paymentNewService;
    @Autowired
    private SvcAppClient svcAppClient;
    @Autowired
    private ComPayClient comPayClient;
    @Autowired
    private SvcComPayClient svcComPayClient;
    @Autowired
    private MulitiPaymentClient mulitiPaymentClient;
    @Autowired
    private PaymentNewClient paymentNewClient;

    @Autowired
    private AssortmentOpenPlatformWxappManager openPlatformWxappManager;
    @Autowired
    private AssortmentOpenPlatformPartnerManager assortmentOpenPlatformPartnerManager;
    @Autowired
    private AssortmentOpenPlatformPartnerConfigManager openPlatformPartnerConfigManager;
    @Autowired
    private AssortmentOpenPlatformIappWxappStoreManager assortmentOpenPlatformIappWxappStoreManager;
    @Autowired
    private OrderQueueService orderQueueService;
    @Autowired
    private OrderSdkService orderSdkService;


    @Autowired
    private OrderAdapterServiceImpl orderAdapterService;
    @Autowired
    private OrderAdapter orderAdapter;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisService redisService;


    @Value("${saas.reverseNotifyiDcUrl}")
    private String reverseNotifyiDcUrl;
    @Value("${collage.pre_order_pay.goods_tag_list}")
    private String collageGoodsTagList;
    @Value("${collage.pre_order_pay.goods_tag}")
    private String collageGoodsTag;


    private static final Integer MULITI_RESPONSE = 200;
    private static final String SUCCESS = "SUCCESS";

    /**
     * 创建预支付订单
     */
    public BaseResponse createPrepayOrder(CreatePrepayRequestDto createPrepayRequestDto) {

        CreateOrderResponseVo createOrderResponse;
        OrderPayResponse orderPayResponse = null;
        PaymentRequest paymentRequest = orderBodyConvertToPaymentBody(createPrepayRequestDto.getOpenId(), createPrepayRequestDto.getPartnerId(),
                createPrepayRequestDto.getWxAppId(), createPrepayRequestDto.getPayCode(), createPrepayRequestDto.getFatherOrderBean().getShopId());
        long totalAmount = createPrepayRequestDto.getTotalAmount();
        String cardCode = createPrepayRequestDto.getCardCode();
        String transId = createPrepayRequestDto.getTransId();
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else if (totalAmount > 0 && Objects.nonNull(createPrepayRequestDto.getUnionPayCard())) {
            // 电子风味卡支付
            orderPayResponse = uSvcPay(createPrepayRequestDto.getFatherOrderBean(), paymentRequest, transId, LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getUnionPayCard());
        } else if (totalAmount > 0 && StringUtils.isBlank(cardCode)) {
            //现金线上支付
            String partnerPayOvertime = this.getPartnerPayOvertime(createPrepayRequestDto.getPartnerId());
            orderPayResponse = getPreOrderPay(createPrepayRequestDto.getFatherOrderBean(), paymentRequest, LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getCardAmount(), transId, partnerPayOvertime, createPrepayRequestDto.getOrderExtInfoDTO());
        } else if (totalAmount > 0 && StringUtils.isNotBlank(cardCode)) {
            //混合支付+svc卡(礼品卡)
            orderPayResponse = switchSvcOrComb(totalAmount, cardCode, createPrepayRequestDto.getFatherOrderBean(), paymentRequest, transId, createPrepayRequestDto.getChannel(), createPrepayRequestDto.getStoreId(), LogThreadLocal.getTrackingNo());
        } else {
            // 0元订单如果不需要支付，自定义支付单号
            orderPayResponse = getOrderPayResponse(paymentRequest, createPrepayRequestDto.getFatherOrderBean());
            // 这里如果抖音卖券价格为0元，不能设置支付方式为0元购，否则后面mq送券的判断会走到通用送券逻辑
            if (PayChannelType.TIKTOKPAY.getEbcode().equals(createPrepayRequestDto.getChannel())) {
                orderPayResponse.setPayChannelType(PayChannelType.TIKTOKPAY);
            }
        }
        if (orderPayResponse == null || Objects.isNull(orderPayResponse.getFmId())) {
            BaseResponse baseResponse = failPreOrderPay(LogThreadLocal.getTrackingNo(), createPrepayRequestDto.getProductOrderBean(), cardCode, createPrepayRequestDto.getOrderClient(),
                    Objects.isNull(orderPayResponse) ? null : orderPayResponse.getMsg());
            // 电子风味卡需要给用户特殊的返回
            if (totalAmount > 0 && Objects.nonNull(createPrepayRequestDto.getUnionPayCard())) {
                baseResponse.setMessage(Objects.nonNull(orderPayResponse) &&
                        (ResponseCodeConstant.PASSWORD_WRONG.equals(orderPayResponse.getPayTransId())
                                || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(orderPayResponse.getPayTransId())) ?
                        orderPayResponse.getMsg() : "支付失败");
            }
            return baseResponse;
        }
        createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, createPrepayRequestDto.getProductOrderBean());
        //更新订单支付信息
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, createPrepayRequestDto.getOrderExtInfoDTO(), createPrepayRequestDto.getProductOrderBean(), LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        if (totalAmount > 0 && StringUtils.isBlank(cardCode) && Objects.isNull(createPrepayRequestDto.getUnionPayCard())) {
            createOrderResponse.setPaySuccess(false);
        } else if (orderPayResponse.getPayChannelType() != null && PayChannelType.COMB.getEbcode().equals(orderPayResponse.getPayChannelType().getEbcode())) {
            createOrderResponse.setPaySuccess(false);
        } else if (orderPayResponse.getPayChannelType() != null && PayChannelType.SVC.getEbcode().equals(orderPayResponse.getPayChannelType().getEbcode())) {
            createOrderResponse.setPaySuccess(true);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        if (!createOrderResponse.getPaySuccess()) {
            return ResponseUtil.success(createOrderResponse);
        } else {
            //如果是商品券支付0元，调用回调接口
            /**
             *  - 老的svc卡或是0元订单下单成功直接核销 这里不处理
             *  - 混合支付纯svc支付 需要直接内部核销 其他支付方式需依靠外部回调
             */
            PaysuccessNoticeMessage message = new PaysuccessNoticeMessage();
            message.setResult_code(100);
            message.setOut_trade_no(createOrderResponse.getFmId());
            message.setTrans_id(createOrderResponse.getOid());
            message.setTotal_fee(0);
            message.setOpenid(createPrepayRequestDto.getOpenId());
            message.setPlatform_coupon(0);
            message.setMerchant_coupon(0);
            message.setSource(PaySuccessSource.OUTSIDE.getSource());
            orderAdapterService.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }


    /**
     * 下单支付 扫脸支付　（目前不在使用）
     */
    // TODO: 21-9-17 待合并
    public BaseResponse createOrderPay(CreateOrderVo createOrderVo, StoreResponse.BizVO storeResponseDto, ShoppingCartGoodsDto shoppingCartGoodsDto,
                                       AssortmentCustomerInfoVo userLoginInfoDto, OrderExtInfoDto orderExtInfoDTO, CreateOrderOperateDto operateDto) {
        //创建订单--包括下单购买会员卡创建父子订单
        long totalAmount = operateDto.getTotalAmount();
        int cardAmount = operateDto.getCardAmount();
        OrderBeanV1 fatherOrderBean = operateDto.getFatherOrderBean();
        OrderBeanV1 productOrderBean = operateDto.getProductOrderBean();
        //支付-- 包含商品券无需支付、唤起微信支付、储值卡支付直接支付、扫脸支付
        OrderPayResponse orderPayResponse = pay(userLoginInfoDto, createOrderVo, totalAmount, cardAmount, fatherOrderBean);
        // 默认支付成功必有非码订单号
        if (orderPayResponse == null || Objects.isNull(orderPayResponse.getFmId())) {
            if (createOrderVo.getFaceCode() != null) {
                createOrderVo.setCardCode(createOrderVo.getFaceCode());
            }
            BaseResponse baseResponse = failPreOrderPay(LogThreadLocal.getTrackingNo(), productOrderBean, createOrderVo.getCardCode(), null,
                    Objects.isNull(orderPayResponse) ? null : orderPayResponse.getMsg());
            // 电子风味卡需要给用户特殊的返回
            if (totalAmount > 0 && Objects.nonNull(createOrderVo.getUnionPayCard())) {
                baseResponse.setMessage(Objects.nonNull(orderPayResponse) &&
                        (ResponseCodeConstant.PASSWORD_WRONG.equals(orderPayResponse.getPayTransId())
                                || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(orderPayResponse.getPayTransId())) ?
                        orderPayResponse.getMsg() : "支付失败");
            }
            return baseResponse;
        }
        //更新订单extinfo信息
        BaseResponse baseEditResponse = this.updateOrderInfo(orderPayResponse, orderExtInfoDTO, productOrderBean, LogThreadLocal.getTrackingNo());
        if (baseEditResponse != null) {
            return baseEditResponse;
        }
        CreateOrderResponseVo createOrderResponse = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, productOrderBean);
        //设置是否唤起微信支付
        if (totalAmount > 0 && StringUtils.isBlank(createOrderVo.getCardCode()) && StringUtils.isBlank(createOrderVo.getFaceCode())) {
            createOrderResponse.setPaySuccess(false);
        } else {
            createOrderResponse.setPaySuccess(true);
        }
        if (!createOrderResponse.getPaySuccess()) {
            return ResponseUtil.success(createOrderResponse);
        } else {
            //如果是商品券支付0元，调用回调接口
            PaysuccessNoticeMessage message = new PaysuccessNoticeMessage();
            message.setResult_code(100);
            message.setOut_trade_no(createOrderResponse.getFmId());
            message.setTrans_id(createOrderResponse.getOid());
            message.setTotal_fee(0);
            message.setOpenid(userLoginInfoDto.getOpenId());
            message.setPlatform_coupon(0);
            message.setMerchant_coupon(0);
            //0元订单内部调支付成功
            orderAdapterService.paySuccessCallback(message);
            return ResponseUtil.success(createOrderResponse);
        }
    }


    /**
     * 创建预支付信息 (围餐用)
     * cardCode svc卡号
     */
    // TODO: 21-9-17 待合并
    public CreateOrderResponseVo createPrePaymentOrder(OrderBeanV1 orderBean, AssortmentCustomerInfoVo assortmentCustomerInfoVo, String partnerId, int cardAmount, String cardCode) {
        OrderPayResponse orderPayResponse = null;
        String wxAppId = assortmentCustomerInfoVo.getWxAppId();
        //设置支付信息
        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setOpenId(assortmentCustomerInfoVo.getOpenId());
        paymentRequest.setWxAppId(wxAppId);
        AssortmentOpenPlatformWxapp wxApp = openPlatformWxappManager.findByPartnerIdAndWxappId(partnerId, wxAppId);
        paymentRequest.setPrincipalName(wxApp.getPrincipalName());
        // fisherman 2227 测试商户号, 下个版本需要删除
        if ("2080".equals(partnerId)) {
            //【ID1035981】【蜜雪冰城】订单C端，拼接order_body字段：蜜雪冰城+门店编号
            paymentRequest.setPrincipalName("蜜雪冰城" + orderBean.getShopId() + "店");
        }
        paymentRequest.setReverseNotifyiDcUrl(reverseNotifyiDcUrl);
        //修改订单信息
        OrderExtInfoDto orderExtInfoDto = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class) == null ? new OrderExtInfoDto() : JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
        if (orderBean.getAmount() > 0 && StringUtils.isEmpty(cardCode)) {
            try {
                String transId = orderBean.getOid() + redisService.increment(RedisUtil.getPaymentTransIdSequenceKey(orderBean.getOid()), 1L, TimeUnit.DAYS);
                UnifiedOrderRequest request = orderAdapter.convent2UnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, transId);

                if (SDKCommonBaseContextWare.getProfile().equals(SDKCommonBaseContextWare.profiles.DEFAULT.getProfile())
                        || SDKCommonBaseContextWare.getProfile().equals(SDKCommonBaseContextWare.profiles.DEV.getProfile())
                        || SDKCommonBaseContextWare.getProfile().equals(SDKCommonBaseContextWare.profiles.TEST.getProfile())) {
                    request.setAmount(1L);
                }
                AppLogUtil.infoLog("支付transId :{},payRequest:{}", request.getTransId(), JSON.toJSONString(request));
                redisService.savePaymentTransIdOrder(RedisUtil.getPaymentTransIdOrderKey(transId), orderBean.getOid(), 1L, TimeUnit.DAYS);
                com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> responseBase = standardPaymentService.unifiedOrder(request, LogThreadLocal.getTrackingNo());
                if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode())) {
                    return null;
                }
                orderPayResponse = orderAdapter.convent2OrderPayResponse(responseBase.getData());
                orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
                orderPayResponse.setOpenId(paymentRequest.getOpenId());
                orderPayResponse.setPartnerId(orderBean.getCompanyId());
                orderPayResponse.setOrderId(orderBean.getOid());

                orderExtInfoDto.setPrePayTransId(request.getTransId());
            } catch (Exception e) {
                AppLogUtil.errorLog("getPreOrderPay_error", JSONObject.toJSONString(orderBean), JSONObject.toJSONString(paymentRequest), e);
                //给出支付失败提示
                return null;
            }
        } else if (orderBean.getAmount() > 0 && StringUtils.isNotEmpty(cardCode)) {
            //svc卡支付
            orderPayResponse = svcPay(cardCode, orderBean, paymentRequest, orderBean.getOid(), LogThreadLocal.getTrackingNo());
            orderExtInfoDto.setPrePayTransId(orderPayResponse.getPayTransId());
        } else if (orderBean.getAmount() < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        } else {
            String fmId = "SPAY" + ValidationCode.getRandomUuid();
            orderPayResponse = orderAdapter.getOrderPayResponse(orderBean.getCompanyId(), paymentRequest,
                    orderBean.getOid(), fmId);
            orderExtInfoDto.setPrePayTransId(orderPayResponse.getPayTransId());
        }
        CreateOrderResponseVo createOrderResponseVo = orderAdapter.convent2CreateFatherSonOrderResponseVo(orderPayResponse, orderBean);
        orderExtInfoDto.setFmId(createOrderResponseVo.getFmId());
        orderExtInfoDto.setPrePayUserId(assortmentCustomerInfoVo.getMemberId());
        orderExtInfoDto.setPhone(assortmentCustomerInfoVo.getMobile());
        orderExtInfoDto.setAppid(wxAppId);
        UpdateOrderReq updateOrderReq = new UpdateOrderReq();
        updateOrderReq.setOrderCode(orderBean.getOid());
        updateOrderReq.setExtInfo(JSONObject.toJSONString(orderExtInfoDto));
        com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp response = orderSdkService.editOrder(updateOrderReq, LogThreadLocal.getTrackingNo());
        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, response.getCode())) {
            throw new ServiceException(ResponseResult.ORDER_EDIT_ERROR, response.getMessage());
        }
        if (orderBean.getAmount() > 0 && StringUtils.isBlank(cardCode)) {
            createOrderResponseVo.setPaySuccess(false);
        } else {
            createOrderResponseVo.setPaySuccess(true);
        }
        return createOrderResponseVo;
    }


    /**
     * 支付
     * 包含唤起微信支付、储值卡支付直接支付、扫脸支付、商品券无需支付
     */
    private OrderPayResponse pay(AssortmentCustomerInfoVo userLoginInfoDto, CreateOrderVo createOrderVo, long totalAmount, int cardAmount,
                                 OrderBeanV1 fatherBeanListOne) {
        //<!---创建订单公共方法执行逻辑--->
        OrderPayResponse orderPayResponse = null;
        String appId = userLoginInfoDto.getWxAppId();
        PaymentRequest paymentRequest = orderBodyConvertToPaymentBody(userLoginInfoDto.getOpenId(), createOrderVo.getPartnerId(), appId, null, fatherBeanListOne.getShopId());
        //支付金额异常
        if (totalAmount < 0) {
            throw new ServiceException(ResponseResult.PAY_AMOUNT_ERROR);
        }
        //电子风味卡支付
        if (totalAmount > 0 && Objects.nonNull(createOrderVo.getUnionPayCard())) {
            return uSvcPay(fatherBeanListOne, paymentRequest, fatherBeanListOne.getOid(), LogThreadLocal.getTrackingNo(), createOrderVo.getUnionPayCard());
        }
        //唤起微信支付
        if (totalAmount > 0 && StringUtils.isBlank(createOrderVo.getCardCode()) && StringUtils.isBlank(createOrderVo.getFaceCode())) {
            String partnerPayOvertime = this.getPartnerPayOvertime(createOrderVo.getPartnerId());
            orderPayResponse = getPreOrderPay(fatherBeanListOne, paymentRequest, LogThreadLocal.getTrackingNo(), cardAmount, fatherBeanListOne.getOid(), partnerPayOvertime, null);
            return orderPayResponse;
        }
        //储值卡支付
        if (totalAmount > 0 && StringUtils.isNotBlank(createOrderVo.getCardCode())) {
            //svc卡支付
            orderPayResponse = svcPay(createOrderVo.getCardCode(), fatherBeanListOne, paymentRequest, fatherBeanListOne.getOid(), LogThreadLocal.getTrackingNo());
            return orderPayResponse;
        }
        //扫脸支付
        if (totalAmount > 0 && StringUtils.isNotBlank(createOrderVo.getFaceCode())) {
            //svc卡支付
            orderPayResponse = facePay(createOrderVo.getFaceCode(), fatherBeanListOne, paymentRequest, LogThreadLocal.getTrackingNo());
            return orderPayResponse;
        }
        //0元订单，商品券订单等等
        if (totalAmount == 0) {
            // 0元订单如果不需要支付，自定义支付单号
            String fmId = "SPAY" + ValidationCode.getRandomUuid();
            orderPayResponse = orderAdapter.getOrderPayResponse(fatherBeanListOne.getCompanyId(), paymentRequest, fatherBeanListOne.getOid(), fmId);
            return orderPayResponse;
        }
        return orderPayResponse;
    }

    /**
     * 扫脸支付
     */
    public OrderPayResponse facePay(String cardCode, OrderBeanV1 orderBean, PaymentRequest paymentRequest, String trackingNo) {
        FacePayRequestDto request = new FacePayRequestDto();
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        String partnerId = orderBean.getCompanyId();
        request.setBody(orderBean.getShopName());
        request.setBusinessDate(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
        request.setCode(cardCode);
        request.setPartnerId(partnerId);
        request.setStoreId(orderBean.getShopId());
        request.setAmount(orderBean.getAmount());
        request.setTransId(orderBean.getOid());
        request.setStationId("1");
        request.setOperatorId("1");
        request.setVer("2");
        //支付服务扫脸付接口
        AppLogUtil.infoLog("facePay_request", JSONObject.toJSON(request), null);
        com.freemud.application.sdk.api.base.BaseResponse<FacePayResponseDto> responseDto = null;
        try {
            responseDto = paymentNewClient.facePay(request);
            AppLogUtil.infoLog("facePay_response", null, JSONObject.toJSON(responseDto));
        } catch (Exception e) {
            AppLogUtil.errorLog("facePay_error", null, null, e);
        }
        if (responseDto == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseDto.getCode()) || responseDto.getData() == null) {
            // 1.9.34 预支付失败需要把原因进行记录
            orderPayResponse.setMsg(Objects.isNull(responseDto) ? "扫脸支付异常" : responseDto.getMessage());
        } else {
            FacePayResponseDto response = responseDto.getData();
            orderPayResponse.setFmId(response.getFmId());
            orderPayResponse.setPayTransId(response.getPayTransId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
        }
        return orderPayResponse;
    }


    /**
     * 查询支付配置
     */
    private PaymentRequest orderBodyConvertToPaymentBody(String openId, String partnerId, String appId, String payCode, String storeId) {
        //设置支付信息
        PaymentRequest paymentRequest = new PaymentRequest();
        paymentRequest.setOpenId(openId);
        paymentRequest.setWxAppId(appId);
        paymentRequest.setReverseNotifyiDcUrl(reverseNotifyiDcUrl);
        paymentRequest.setPayCode(payCode);
        if ("2080".equals(partnerId)) {
            //【ID1035981】【蜜雪冰城】订单C端，拼接order_body字段：蜜雪冰城+门店编号
            paymentRequest.setPrincipalName("蜜雪冰城" + storeId + "店");
        } else {
            // saas 查询小程序配置
            paymentRequest.setPrincipalName(this.getPaymentPrincipalName(partnerId, appId));
        }
        return paymentRequest;
    }

    /**
     * 查询支付配置
     */
    private String getPaymentPrincipalName(String partnerId, String appId) {
        String redisKey = MessageFormat.format(KgdRedisKeyConstant.PARTNER_PAYMENT_PRINCIPAL_NAME, partnerId);
        // 先从redis中查询支付商户名称
        String principalName = redisCache.hashGet(redisKey, appId);
        if (StringUtils.isEmpty(principalName)) {
            AssortmentOpenPlatformWxapp wxApp = openPlatformWxappManager.findByPartnerIdAndWxappId(partnerId, appId);
            if (wxApp == null || StringUtils.isEmpty(wxApp.getPrincipalName())) {
                // 小程序如果没有配置支付商户名称，则去商户名称替代
                AssortmentOpenPlatformPartner platformPartner = assortmentOpenPlatformPartnerManager.selectOpenPlatformPartner(partnerId);
                if (null != platformPartner) principalName = platformPartner.getCompanyName();
            } else {
                principalName = wxApp.getPrincipalName();
            }
            if (StringUtils.isEmpty(principalName)) {
                //如果还是没有查到，就用非码代替
                principalName = "上海非码网络科技有限公司";
            }
            // 加载到redis，有效期一天
            redisCache.hashPut(redisKey, appId, principalName);
            redisCache.updateTTL(redisKey, 24, TimeUnit.HOURS);
        }
        return principalName;
    }


    /**
     * 电子风味卡支付
     * unionPay card pay
     */
    private OrderPayResponse uSvcPay(OrderBeanV1 orderBean, PaymentRequest paymentRequest, String transId, String trackingNo, CreateOrderVo.UnionPayCard unionPayCard) {
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        if (Objects.isNull(unionPayCard) || StringUtils.isBlank(unionPayCard.getCode()) || StringUtils.isBlank(unionPayCard.getPassword())) {
            orderPayResponse.setMsg("电子风味卡信息缺失");
            return orderPayResponse;
        }
        CodePayRequest request = new CodePayRequest();
        String partnerId = orderBean.getCompanyId();
        request.setBody(orderBean.getShopName());
        request.setBusinessDate(DateTimeFormatter.ofPattern(DateUtil.FORMAT_YYYY_MM_DD_HHMMSS).format(LocalDateTime.now()));
        // paymentRequest 的 payCode可能为null,不保险
        request.setPayCode(PayChannel.USVCP.getCode());
        // 电子风味卡信息
        request.setCode(unionPayCard.getCode());
        request.setCardPassword(unionPayCard.getPassword());
        request.setPartnerId(partnerId);
        request.setStoreId(orderBean.getShopId());
        request.setAmount(orderBean.getAmount());
        request.setTransId(transId);
        request.setStationId("2");
        request.setOperatorId("2");
        request.setVer("2");
        request.setMerchantDiscount(orderBean.getOriginalAmount().longValue() - orderBean.getAmount());
        com.freemud.application.sdk.api.base.BaseResponse<CodePayResponse> responseBase = paymentNewService.codePay(request, trackingNo);
        if (responseBase == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode()) || responseBase.getData().getData() == null) {
            // 需要把2种特殊情况抛给用户
            if (Objects.nonNull(responseBase) && (ResponseCodeConstant.PASSWORD_WRONG.equals(responseBase.getCode()) || ResponseCodeConstant.NOT_SUFFICIENT_FUND.equals(responseBase.getCode()))) {
                orderPayResponse.setPayTransId(responseBase.getCode());
            }
            orderPayResponse.setMsg(Objects.isNull(responseBase) ? "电子风味卡支付异常" : responseBase.getMessage());
        } else {
            CodePayResponse.CodePayDate codePayResponse = responseBase.getData().getData();
            orderPayResponse.setFmId(codePayResponse.getFmId());
            orderPayResponse.setPayTransId(codePayResponse.getPayTransId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            orderPayResponse.setPayChannelType(PayChannelType.USVCP);
        }
        return orderPayResponse;
    }


    /**
     * 获取商户支付超时时间
     */
    private String getPartnerPayOvertime(String partnerId) {
        return Optional.ofNullable(openPlatformPartnerConfigManager.selectPartnerConfigByPartnerKey(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME))
                .orElseGet(() -> {
                    AssortmentOpenPlatformPartnerConfig config = new AssortmentOpenPlatformPartnerConfig();
                    config.setPartnerValue("30");
                    openPlatformPartnerConfigManager.addPartnerConfig(partnerId, RedisKeyConstant.PARTNER_PAY_OVERTIME, config);
                    return config;
                }).getPartnerValue();
    }


    /**
     * 现金支付
     */
    public OrderPayResponse getPreOrderPay(OrderBeanV1 orderBean, PaymentRequest paymentRequest, String trackingNo, Integer cardAmount, String transId, String partnerPayOvertime, OrderExtInfoDto orderExtInfoDto) {
        OrderPayResponse orderPayResponse;
        UnifiedOrderRequest request = orderAdapter.convent2UnifiedOrderRequest(orderBean, paymentRequest, orderBean.getAmount(), cardAmount, transId, partnerPayOvertime);
        // add by miaohui for 拼单群收款判断拼单人数大于1时参与微信平台补贴活动，创建预支付时上送goodsTag，后续抽成促销服务活动时删除此逻辑 start
        if (null != orderBean.getMarketingType() && OrderMarketType.COLLAGE.getIndex() == orderBean.getMarketingType()) {
            // 拼单人数大于1人时参加拼单补贴
            if (null != orderBean.getProductList() && orderBean.getProductList().stream().map(ProductBeanV1::getUserId).distinct().collect(Collectors.toList()).size() > 1) {
                Map<String, String> goodsTagMap = this.goodsTagMap();
                String goodsTag = goodsTagMap.get(orderBean.getCompanyId());
                request.setGoodsTag(StringUtils.isBlank(goodsTag) ? collageGoodsTag : goodsTag);
            }
        }
        // add by miaohui for 拼单群收款判断拼单人数大于1时参与微信平台补贴活动，创建预支付时上送goodsTag，后续抽成促销服务活动时删除此逻辑 end
        if (orderExtInfoDto != null && StringUtils.isNotBlank(orderExtInfoDto.getStationId())) {
            request.setStationId(orderExtInfoDto.getStationId());
        }
        com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> responseBase = standardPaymentService.unifiedOrder(request, trackingNo);
        if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode())) {
            // 1.9.34 预支付失败需要把原因进行记录
            orderPayResponse = new OrderPayResponse();
            orderPayResponse.setMsg(responseBase.getMessage());
        } else {
            putDelMq(request.getPartnerId(), request.getStoreId(), responseBase.getData().getFmId(), orderBean.getOid(), null);
            orderPayResponse = orderAdapter.convent2OrderPayResponse(responseBase.getData());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            orderPayResponse.setPayChannelType(PayChannelType.WECHAT);
            if (orderPayResponse.getPayOrder() != null && StringUtils.isNotBlank(orderPayResponse.getPayOrder().getAliPayOrder())) {
                orderPayResponse.setPayChannelType(PayChannelType.ALIPAY);
            }
            //抖音支付
            if (PayChannelType.TIKTOKPAY.getIndex().toString().equalsIgnoreCase(orderBean.getPayChannelType())) {
                orderPayResponse.setPayChannelType(PayChannelType.TIKTOKPAY);
            }

        }
        return orderPayResponse;
    }


    /**
     * 混合支付
     */
    private OrderPayResponse switchSvcOrComb(Long totalAmount
            , String cardCode
            , OrderBeanV1 orderBean
            , PaymentRequest paymentRequest
            , String transId
            , String channel
            , String storeId
            , String trackingNo) {

        OrderPayResponse orderPayResponse = null;
        //混合支付开关
        boolean check = this.checkSvcComPay(orderBean.getCompanyId(), orderBean.getShopId());
        //混合支付
        if (check && StringUtils.isNotBlank(channel)) {
            String partnerPayOvertime = this.getPartnerPayOvertime(orderBean.getCompanyId());
            orderPayResponse = comPayOrder(cardCode, orderBean, paymentRequest, partnerPayOvertime, totalAmount.intValue(), channel, storeId, trackingNo);
        } else {//svc 支付
            orderPayResponse = svcPay(cardCode, orderBean, paymentRequest, transId, trackingNo);
        }
        return orderPayResponse;
    }


    /**
     * 创建混合支付
     */
    public OrderPayResponse comPayOrder(String cardNo
            , OrderBeanV1 orderBean
            , PaymentRequest paymentRequest
            , String partnerPayOvertime
            , Integer totalAmount
            , String channel
            , String storeId
            , String trackingNo) {

        String ebCode = this.getPayCodeByChanel(paymentRequest.getWxAppId(), channel, storeId);
        OrderPayResponse orderPayResponse = new OrderPayResponse();

        if (StringUtils.isBlank(ebCode)) {
            orderPayResponse.setMsg("请先联系相关人员配置商户对应的支付渠道");
            return orderPayResponse;
        }

        CombPayRequest combPayRequest = orderAdapter.convent2CombPayOrderRequest(cardNo, orderBean, paymentRequest, partnerPayOvertime, ebCode, channel, totalAmount);
        CombPayResponse combPayResponse = comPayClient.combPay(combPayRequest, combPayRequest.getPartner_id());
        if (combPayResponse == null || !ResponseCodeConstant.PAYMENT_RESPONSE_SUCCESS.equals(combPayResponse.getCode())) {
            orderPayResponse.setMsg(combPayResponse != null ? "支付：" + combPayResponse.getMsg() : "混合支付忙不过来啦，请稍后再试");
            return orderPayResponse;
        }
        List<CombPayResponse.PayPlatform> payPlatforms = combPayResponse.getData().getPayPlatformResponseList();
        if (payPlatforms.size() == 0) {
            orderPayResponse.setMsg("混合支付:生成预支付失败");
            return orderPayResponse;
        }

        orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
        orderPayResponse.setOpenId(paymentRequest.getOpenId());
        orderPayResponse.setPartnerId(orderBean.getCompanyId());
        orderPayResponse.setOrderId(orderBean.getOid());
        orderPayResponse.setMsg("success");
        orderPayResponse.setPayId("");

        CombPayResponse.PayPlatform cashPay = null;
        for (CombPayResponse.PayPlatform pt : payPlatforms) {
            if (!PayChannelType.SVC.getEbcode().equals(pt.getEbCode())) {
                cashPay = pt;
            }
            orderPayResponse.setFmId(pt.getTransId());
            orderPayResponse.setPayTransId(pt.getTransId());
            PayChannelType payChannelType = PayChannelType.getByEbcode(pt.getEbCode());
            if (pt.getCardType() != null && pt.getCardType() == 0) {
                payChannelType = PayChannelType.GIFTCARD;
            }
            orderPayResponse.setPayChannelType(payChannelType);
            orderPayResponse.setPayEbcode(pt.getEbCode());
            OrderPayItemResp payItem = new OrderPayItemResp();
            payItem.setFmTradeNo(pt.getFmTradeNo());
            payItem.setStoreId(storeId);
            payItem.setPayChannelType(payChannelType.getIndex().intValue());
            payItem.setPayChannelName(payChannelType.getName());
            payItem.setTransId(pt.getTransId());
            payItem.setPartnerId(combPayRequest.getPartner_id());
            payItem.setPayAmount(new BigDecimal(pt.getPayAmount()));
            orderPayResponse.getPayItem().add(payItem);
            CombPayResponse.PayPlatform.PayOrderBean payOrderBean = pt.getPayOrder();
            if (null != payOrderBean) {
                OrderPayResponse.PayOrderBean payBean = new OrderPayResponse.PayOrderBean();
                payBean.setAppid(payOrderBean.getAppId());
                payBean.setNonceStr(payOrderBean.getNonceStr());
                payBean.setPackageX(payOrderBean.getPackageX());
                payBean.setSign(payOrderBean.getPaySign());
                payBean.setSignType(payOrderBean.getSignType());
                payBean.setTimestamp(payOrderBean.getTimeStamp());
                payBean.setAliPayOrder(payOrderBean.getAliPayOrder());
                orderPayResponse.setPayOrder(payBean);
            }
        }
        if (payPlatforms.size() > 1) {
            orderPayResponse.setPayChannelType(PayChannelType.COMB);
        }
        //现金线上支付
        if (cashPay != null) {
            String transId = cashPay.getTransId();
            orderPayResponse.setFmId(cashPay.getFmTradeNo());
            redisCache.save(RedisUtil.getPaymentTransIdOrderKey(transId), orderBean.getOid(), 1L, TimeUnit.DAYS);
            //加入轮训队列
            putDelMq(orderBean.getCompanyId(), storeId, orderPayResponse.getFmId(), orderBean.getOid(), PayChannelType.getByEbcode(transId).getIndex().intValue());
        }
        return orderPayResponse;
    }


    /**
     * 纯储值卡或礼品卡支付
     */
    public OrderPayResponse svcPay(String cardCode, OrderBeanV1 orderBean, PaymentRequest paymentRequest, String transId, String trackingNo) {
        CodePayRequest request = new CodePayRequest();
        OrderPayResponse orderPayResponse = new OrderPayResponse();
        String partnerId = orderBean.getCompanyId();
        request.setBody(orderBean.getShopName());
        request.setBusinessDate(DateUtil.convert2String(new Date(), DateUtil.FORMAT_YYYY_MM_DD_HHMMSS));
        request.setCode(cardCode);
        request.setPartnerId(partnerId);
        request.setStoreId(orderBean.getShopId());
        request.setAmount(orderBean.getAmount());
        request.setTransId(transId);
        request.setStationId("1");
        request.setOperatorId("1");
        request.setVer("2");
        request.setMerchantDiscount(orderBean.getOriginalAmount().longValue() - orderBean.getAmount());
        SVCCardAmountRequestDto svcRequest = new SVCCardAmountRequestDto();
        svcRequest.setPartnerId(partnerId);
        svcRequest.setCardCodes(Arrays.asList(cardCode));
        //查询svc卡余额
        BaseResponse<SVCCardAmountResponseDto> svcCardAmountResponseBaseResponse = svcAppClient.batchQueryCardAmount(svcRequest);
        if (svcCardAmountResponseBaseResponse == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(svcCardAmountResponseBaseResponse.getCode())
                || svcCardAmountResponseBaseResponse.getResult() == null || CollectionUtils.isEmpty(svcCardAmountResponseBaseResponse.getResult().getCardSimpleInfos())) {
            orderPayResponse.setMsg(Objects.isNull(svcCardAmountResponseBaseResponse) ? "获取卡余额异常" : svcCardAmountResponseBaseResponse.getMessage());
            return orderPayResponse;
        }
        Integer amount = svcCardAmountResponseBaseResponse.getResult().getCardSimpleInfos().get(0).getAmount();
        Integer vamount = svcCardAmountResponseBaseResponse.getResult().getCardSimpleInfos().get(0).getVamount();
        Integer applyType = svcCardAmountResponseBaseResponse.getResult().getCardSimpleInfos().get(0).getApplyType();
        applyType = applyType == null ? 3 : applyType;
        PayChannelType payChannelType = applyType == 3 ? PayChannelType.SVC : PayChannelType.GIFTCARD;
        if (amount + vamount < orderBean.getAmount()) {
            orderPayResponse.setMsg("卡余额不足");
            return orderPayResponse;
        }
        //svc卡支付
        com.freemud.application.sdk.api.base.BaseResponse<CodePayResponse> responseBase = paymentNewService.codePay(request, trackingNo);
        if (responseBase == null || !ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(responseBase.getCode()) || responseBase.getData().getData() == null) {
            // 1.9.34 预支付失败需要把原因进行记录
            orderPayResponse.setMsg(Objects.isNull(responseBase) ? "卡支付异常" : responseBase.getMessage());
        } else {
            CodePayResponse.CodePayDate codePayResponse = responseBase.getData().getData();
            orderPayResponse.setFmId(codePayResponse.getFmId());
            orderPayResponse.setPayTransId(codePayResponse.getPayTransId());
            orderPayResponse.setWxAppid(paymentRequest.getWxAppId());
            orderPayResponse.setOpenId(paymentRequest.getOpenId());
            orderPayResponse.setPartnerId(orderBean.getCompanyId());
            orderPayResponse.setOrderId(orderBean.getOid());
            orderPayResponse.setPayChannelType(payChannelType);
        }
        return orderPayResponse;
    }

    /**
     * 唤起预支付
     */
    public com.freemud.application.sdk.api.base.BaseResponse<UnifiedOrderResponse> unifiedOrder(UnifiedOrderRequest request) {
        return standardPaymentService.unifiedOrder(request, LogThreadLocal.getTrackingNo());
    }

    /**
     * 支付退款
     */
    public com.freemud.application.sdk.api.base.BaseResponse<OrderRefundResponse> orderRefund(com.freemud.sdk.api.assortment.payment.request.OrderRefundRequest orderPayRefundRequest) {
        return standardPaymentService.orderRefund(orderPayRefundRequest, LogThreadLocal.getTrackingNo());
    }

    /**
     * 混合支付退款接口
     */
    public MultiOrderRefundResponse paymentApplicationRefund(MultiOrderRefundRequest multiOrderRefundRequest, String partnerId) {
        return mulitiPaymentClient.paymentApplicationRefund(multiOrderRefundRequest, partnerId);
    }

    /**
     * 批量支付退款
     */
    public PayBatchRefundResponse batchRefund(BatchOrderRefundV2Request batchOrderRefundV2Request) {
        return mulitiPaymentClient.batchRefund(batchOrderRefundV2Request);
    }


    /**
     * 关闭预支付
     */
    public boolean closePrePay(OrderBeanV1 orderBean) {
        //是否支付成功
        boolean paySuccess = false;
        OrderExtInfoDto extInfo = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);

        List<OrderPayItemResp> orderPayItemList = orderBean.getOrderPayItem();
        if (null != orderPayItemList && orderPayItemList.size() > 0) {
            Integer partnerId = Integer.valueOf(orderBean.getCompanyId());
            MultiQueryRequest request = new MultiQueryRequest();
            request.setEnable_platform_data_query(false);
            request.setPartnerId(partnerId);
            request.setStoreId(orderBean.getShopId());
            request.setOutOrderNo(orderBean.getOid());
            //查询聚合支付结果
            MultiQueryRespDto<MultiQueryRespDto.Data> response = comPayClient.paymentApplicationQuery(request, partnerId);
            if (response != null && response.getData() != null && Objects.equals(response.getCode(), MULITI_RESPONSE)) {
                List<MultiPaymentRespDto> multiPaymentRespDtoArrayList = response.getData().getQueryList();
                if (null != multiPaymentRespDtoArrayList && multiPaymentRespDtoArrayList.size() > 0) {
                    int successData = 0;
                    for (MultiPaymentRespDto multiPaymentRespDto : multiPaymentRespDtoArrayList) {
                        if (Objects.equals(multiPaymentRespDto.getStatus(), SUCCESS)) {
                            successData++;
                        }
                    }
                    if (successData >= multiPaymentRespDtoArrayList.size()) {
                        paySuccess = true;
                    }
                }
            }
        } else {
            //判断当前订单是否存在预支付订单
            if (extInfo != null && StringUtils.isNotEmpty(extInfo.getFmId())) {
                //订单状态未支付且存在预支付订单：
                // 1.查询预支付订单支付状态
                PaymentQueryRequest paymentQueryRequest = new PaymentQueryRequest();
                paymentQueryRequest.setPartnerId(orderBean.getCompanyId());
                paymentQueryRequest.setStoreId(orderBean.getShopId());
                paymentQueryRequest.setFmId(extInfo.getFmId());
                paymentQueryRequest.setVer("2");
                com.freemud.application.sdk.api.base.BaseResponse<PaymentQueryResponse> queryResponseBaseResponse = paymentNewService.query(paymentQueryRequest, LogThreadLocal.getTrackingNo());
                //判断预支付订单状态
                if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), queryResponseBaseResponse.getCode())) {
                    throw new ServiceException(ResponseResult.ORDER_PAY_GETPRE_MESSAGE_ERROR);
                }
                //判断当前预支付订单是否已经支付成功
                if (queryResponseBaseResponse.getData() != null && ObjectUtils.equals(TradeState.SUCCESS.getCode(), queryResponseBaseResponse.getData().getTradeState())) {
                    paySuccess = true;
                }
            }
        }

        if (!paySuccess && extInfo != null && StringUtils.isNotEmpty(extInfo.getFmId())) {
            PaymentCloseUnifiedOrderRequest closeUnifiedOrderRequest = new PaymentCloseUnifiedOrderRequest();
            closeUnifiedOrderRequest.setFmId(extInfo.getFmId());
            closeUnifiedOrderRequest.setVer("2");
            closeUnifiedOrderRequest.setPartnerId(orderBean.getCompanyId());
            closeUnifiedOrderRequest.setStoreId(orderBean.getShopId());
            com.freemud.application.sdk.api.base.BaseResponse<PaymentCloseUnifiedOrderResponse> cancelNewUnifiedOrder = paymentNewService.cancelNewUnifiedOrder(closeUnifiedOrderRequest, LogThreadLocal.getTrackingNo());
            if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), cancelNewUnifiedOrder.getCode())) {
                throw new ServiceException(ResponseResult.ORDER_PRE_PAYMENT_CLOSE_FAILED);
            }
        }
        return paySuccess;
    }

    /**
     * 与　closePrePay 待合并
     */
    public void closeHistoryPrePay(OrderBeanV1 orderBean) {

        OrderExtInfoDto extInfo = JSONObject.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
        //判断当前订单是否存在预支付订单
        if (extInfo != null && StringUtils.isNotEmpty(extInfo.getFmId())) {
            //订单状态未支付且存在预支付订单：
            // 1.查询预支付订单支付状态
            PaymentQueryRequest paymentQueryRequest = new PaymentQueryRequest();
            paymentQueryRequest.setPartnerId(orderBean.getCompanyId());
            paymentQueryRequest.setStoreId(orderBean.getShopId());
            paymentQueryRequest.setFmId(extInfo.getFmId());
            paymentQueryRequest.setVer("2");
            com.freemud.application.sdk.api.base.BaseResponse<PaymentQueryResponse> queryResponseBaseResponse = paymentNewService.query(paymentQueryRequest, LogThreadLocal.getTrackingNo());
            //判断预支付订单状态
            if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), queryResponseBaseResponse.getCode())) {
                throw new ServiceException(ResponseResult.ORDER_PAY_GETPRE_MESSAGE_ERROR);
            }
            //判断当前预支付订单是否已经支付成功
            if (ObjectUtils.equals(TradeState.SUCCESS.getCode(), queryResponseBaseResponse.getData().getTradeState())) {
                throw new ServiceException(ResponseResult.ORDER_HAS_PAID);
            }
            // 3.取消前一个预支付订单  调用支付取消预支付订单,如果预支付订单已经取消了再调用取消预支付订单接口会报错的
            if (ObjectUtils.equals(TradeState.NOTPAY.getCode(), queryResponseBaseResponse.getData().getTradeState())) {
                PaymentCloseUnifiedOrderRequest closeUnifiedOrderRequest = new PaymentCloseUnifiedOrderRequest();
                closeUnifiedOrderRequest.setFmId(extInfo.getFmId());
                closeUnifiedOrderRequest.setVer("2");
                closeUnifiedOrderRequest.setPartnerId(orderBean.getCompanyId());
                closeUnifiedOrderRequest.setStoreId(orderBean.getShopId());
                com.freemud.application.sdk.api.base.BaseResponse<PaymentCloseUnifiedOrderResponse> cancelNewUnifiedOrder = paymentNewService.cancelNewUnifiedOrder(closeUnifiedOrderRequest, LogThreadLocal.getTrackingNo());
                if (ObjectUtils.notEqual(ResponseResult.SUCCESS.getCode(), cancelNewUnifiedOrder.getCode())) {
                    throw new ServiceException(ResponseResult.ORDER_PRE_PAYMENT_CLOSE_FAILED);
                }
            }
        }
    }

    /**
     * 编辑订单，保持预支付信息
     */
    public BaseResponse updateOrderInfo(OrderPayResponse orderPayResponse, OrderExtInfoDto orderExtInfo
            , OrderBeanV1 orderBean, String trackingNo) {
        orderExtInfo.setOpenid(orderPayResponse.getOpenId());
        orderExtInfo.setFmId(orderPayResponse.getFmId());
        orderExtInfo.setAppid(orderPayResponse.getWxAppid());
        String prepayId = "";
        OrderPayResponse.PayOrderBean payOrder = orderPayResponse.getPayOrder();
        if (payOrder != null && !StringUtils.isEmpty(payOrder.getPackageX())) {
            String[] prepayIds = payOrder.getPackageX().split("=");
            prepayId = prepayIds.length > 1 ? prepayIds[1] : "";
        }
        //支付宝保存交易流水号发送支付宝模板消息
        if (payOrder != null && !StringUtils.isEmpty(payOrder.getAliPayOrder())) {
            prepayId = payOrder.getAliPayOrder();
        }
        orderExtInfo.setPrepayId(prepayId);

        OrderEditRequest orderEditRequest = new OrderEditRequest(orderPayResponse.getPayTransId(),
                JSONObject.toJSONString(orderExtInfo));
        orderEditRequest.setOrderId(orderBean.getOid());
        orderEditRequest.setTrackingNo(trackingNo);
        if (orderPayResponse.getPayChannelType() != null) {
            orderEditRequest.setPayChannel(orderPayResponse.getPayChannelType().getEbcode());
            orderEditRequest.setPayChannelName(orderPayResponse.getPayChannelType().getName());
            orderEditRequest.setPayChannelType(orderPayResponse.getPayChannelType().getIndex());
        }
        //混合支付项
        if (CollectionUtils.isNotEmpty(orderPayResponse.getPayItem())) {
            orderEditRequest.setOrderPayItem(orderPayResponse.getPayItem());
            if (orderPayResponse.getPayItem().size() == 2) {
                orderEditRequest.setPayChannel(PayChannelType.COMB.getEbcode());
                orderEditRequest.setPayChannelName(PayChannelType.COMB.getName());
                orderEditRequest.setPayChannelType(PayChannelType.COMB.getIndex());
            }
        }

        UpdateOrderReq updateOrderReq = new UpdateOrderReq();
        updateOrderReq.setOrderCode(orderEditRequest.getOrderId());
        updateOrderReq.setExtInfo(orderEditRequest.getExtInfo());
        updateOrderReq.setOrderClient(OrderClientType.SAAS.getIndex());
        updateOrderReq.setOrderPayItem(orderEditRequest.getOrderPayItem());
        updateOrderReq.setPayChannel(orderEditRequest.getPayChannel());
        updateOrderReq.setPayChannelName(orderEditRequest.getPayChannelName());
        updateOrderReq.setPayChannelType(orderEditRequest.getPayChannelType());
        com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp response = orderSdkService.editOrder(updateOrderReq, orderEditRequest.getTrackingNo());
        if (!ObjectUtils.equals(ResponseCodeConstant.RESPONSE_SUCCESS_STR, response.getCode())) {
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, "编辑订单支付信息失败", trackingNo, null);
            OrderCancelReq request = new OrderCancelReq();
            //商户号必传
            request.setPartnerId(cancelOrderRequest.getPartnerId());
            request.setOrderCode(cancelOrderRequest.getOrderId());
            request.setReqRemark(cancelOrderRequest.getReqRemark());
            //售后单类型 1:其他取消 2:用户取消 3:商户取消 4:未支付超时关单 5:商户接单超时取消 6:商家拒单
            // 7:配送用户拒收 8:用户售后退货/售后退款 9:系统取消 10:客服取消 11:用户统一取消，
            request.setAfterSalesType(cancelOrderRequest.getAfterSalesType().getIndex() == null ? 1 : cancelOrderRequest.getAfterSalesType().getIndex());
            request.setOrderClient(cancelOrderRequest.getOrderClient());
            request.setCancelReason(cancelOrderRequest.getReason());
            request.setAfterSalesReason(cancelOrderRequest.getReason());
            //若为4，默认做【创建】+【同意并退款完成】，售后单状态为【完成】
            request.setCreateEvent(cancelOrderRequest.getCreateEvent());
            request.setAfterSerialNo(cancelOrderRequest.getRefundSerialNo());
            request.setOperator(cancelOrderRequest.getOperator());

            // 【华莱士20210510活动】新增加退款方式字段
            if (Objects.nonNull(cancelOrderRequest.getExtInfoReq())) {
                request.setExtInfo(JSON.toJSONString(cancelOrderRequest.getExtInfoReq()));
            }
            request.setRefundDeliveryAmount(cancelOrderRequest.isRefundDeliveryAmount());
            com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp cancelOrderResponse = orderSdkService.cancelOrder(request, cancelOrderRequest.getTrackingNo());

            //如果编辑订单支付信息失败，冲正
            orderQueueService.backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus(), PayStatusEnum.NOT_PAY.getCode());
            return ResponseUtil.error(response.getCode(), response.getMessage());
        }
        return null;
    }


    /**
     * 拼单参数
     */
    private Map<String, String> goodsTagMap() {
        Map<String, String> map = new HashMap<>();
        try {
            for (String pg : collageGoodsTagList.split(",")) {
                map.put(pg.split(":")[0], pg.split(":")[1]);
            }
        } catch (Exception e) {
            AppLogUtil.errorLog("goodsTag解析失败：", "", "", e);
        }
        return map;
    }


    /**
     * 支付失败处理
     */
    private BaseResponse failPreOrderPay(String trackingNo, OrderBeanV1 orderBean, String cardCode, OrderClientType orderClient, String msg) {
        List<OrderClientType> notCancelOrderClientList = Lists.newArrayList(OrderClientType.APP);
        if (!notCancelOrderClientList.contains(orderClient)) {
            //失败冲正库存，冲正活动库存，取消订单
            CancelOrderRequest cancelOrderRequest = orderAdapter.convent2CancelOrderRequest(orderBean.getOid(), orderBean.getCompanyId(),
                    AfterSalesType.SYSTEM_CANCEL, StringUtils.join(new String[]{"获取预支付失败", msg}, '-'), trackingNo, null);
            OrderCancelReq request = new OrderCancelReq();
            //商户号必传
            request.setPartnerId(cancelOrderRequest.getPartnerId());
            request.setOrderCode(cancelOrderRequest.getOrderId());
            request.setReqRemark(cancelOrderRequest.getReqRemark());
            //售后单类型 1:其他取消 2:用户取消 3:商户取消 4:未支付超时关单 5:商户接单超时取消 6:商家拒单
            // 7:配送用户拒收 8:用户售后退货/售后退款 9:系统取消 10:客服取消 11:用户统一取消，
            request.setAfterSalesType(cancelOrderRequest.getAfterSalesType().getIndex() == null ? 1 : cancelOrderRequest.getAfterSalesType().getIndex());
            request.setOrderClient(cancelOrderRequest.getOrderClient());
            request.setCancelReason(cancelOrderRequest.getReason());
            request.setAfterSalesReason(cancelOrderRequest.getReason());
            //若为4，默认做【创建】+【同意并退款完成】，售后单状态为【完成】
            request.setCreateEvent(cancelOrderRequest.getCreateEvent());
            request.setAfterSerialNo(cancelOrderRequest.getRefundSerialNo());
            request.setOperator(cancelOrderRequest.getOperator());

            // 【华莱士20210510活动】新增加退款方式字段
            if (Objects.nonNull(cancelOrderRequest.getExtInfoReq())) {
                request.setExtInfo(JSON.toJSONString(cancelOrderRequest.getExtInfoReq()));
            }
            request.setRefundDeliveryAmount(cancelOrderRequest.isRefundDeliveryAmount());
            com.freemud.application.sdk.api.ordercenter.response.OrderBaseResp cancelOrderResponse = orderSdkService.cancelOrder(request, cancelOrderRequest.getTrackingNo());

            // TODO: 2019/9/10 hubowen mq推送变更
            orderQueueService.backOrdersStatusChange(orderBean.getOid(), orderBean.getStatus(), PayStatusEnum.NOT_PAY.getCode());
        }
        //svc 卡支付失败
        if (StringUtils.isNotBlank(cardCode)) {
            return ResponseUtil.error(ResponseResultEnum.PAY_BACKEND_CONFIG_ERROR.getCode(), StringUtils.isNotBlank(msg) ? msg : ResponseResultEnum.PAY_BACKEND_CONFIG_ERROR.getMessage(), null);
        }
        return ResponseUtil.error(ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getCode(), ResponseResultEnum.PAY_UNIFIED_ORDER_ERROR.getMessage(), null);
    }


    /**
     * 通过payCode ->clientCode
     */
    private String getPayCodeByChanel(String wxAppid, String channel, String storeId) {
        if (StringUtils.isBlank(channel)) return "";

        PayChannelType byIndex = PayChannelType.getByIndex(Byte.parseByte(channel));
        if (byIndex.getEbcode() == null) return "";
        AssortmentOpenPlatformIappWxappStore wxAppStore = assortmentOpenPlatformIappWxappStoreManager.selectWxappStoreByWxAppIdAndStoreId(wxAppid
                , storeId
                , byIndex.getEbcode());
        if (wxAppStore != null && StringUtils.isNotBlank(wxAppStore.getClientCode())) {
            return wxAppStore.getClientCode();
        }
        return "";
    }


    /**
     * 获取混合支付是否开启
     */
    private boolean checkSvcComPay(String partnerId, String storeId) {
        SvcComPayRequestDto requestDto = new SvcComPayRequestDto();
        requestDto.setPartnerId(partnerId);
        requestDto.setStoreId(storeId);
        SvcComPayResponseDto query = null;
        for (int i = 0; i < 3; i++) {
            query = svcComPayClient.query(requestDto);
            if (query != null) break;
        }
        if (query == null || !ResponseResult.SUCCESS.getCode().equals(query.getCode())) {
            return false;
        }
        if (query.getResult() != null && query.getResult().getValue()) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 0元支付参数
     */
    private OrderPayResponse getOrderPayResponse(PaymentRequest paymentRequest, OrderBeanV1 orderBean) {
        OrderPayResponse orderPayResponse;
        String fmId = "SPAY" + ValidationCode.getRandomUuid();
        orderPayResponse = orderAdapter.getOrderPayResponse(orderBean.getCompanyId(), paymentRequest,
                orderBean.getOid(), fmId);
        return orderPayResponse;
    }


    /**
     * 获取预支付成功，将信息放入死心队列，当支付成功没有回掉的时候处理
     */
    public void putDelMq(String partnerId, String storeId, String fmId, String orderId, Integer payChanelType) {
        PaymentMqMessageDto dto = new PaymentMqMessageDto();
        try {
            dto.setFmId(fmId);
            dto.setOrderId(orderId);
            dto.setPartnerId(partnerId);
            dto.setStoreId(storeId);
            dto.setPayChannelType(payChanelType);
            dto.setTrackingNo(LogThreadLocal.getTrackingNo());
            orderQueueService.paymentCallback(dto);
        } catch (Exception e) {
            AppLogUtil.errorLog("paymentQueueService.paymentCallback,orderId:{}", orderId, null, e);
        }
    }


    /**
     * 获取门店支付信息
     *
     * aggregationType 6-会员、7-微商城、8-一键购买 9:积分商城
     */
    public AssortmentOpenPlatformIappWxappStore getIappWxappStoreInfo(String wxAppId, String aggregationType) {
        AssortmentOpenPlatformIappWxappStore wxAppStore = assortmentOpenPlatformIappWxappStoreManager.selectIappWxappStoreByWxAppIdAndAggregationType(wxAppId, aggregationType);
        return wxAppStore;
    }

}
