package cn.pluss.platform.ys.pay;


import cn.pluss.platform.api.ResultCode;
import cn.pluss.platform.constants.Constant;
import cn.pluss.platform.device.MercOrderNewService;
import cn.pluss.platform.dto.MerChantOrderDTO;
import cn.pluss.platform.entitiy.SettleTypeEnum;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.jft.JftReceiptOrderService;
import cn.pluss.platform.mapper.SubMercCodeYsMapper;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantOrder.MerchantOrderService;
import cn.pluss.platform.merchantOrderSplit.MerchantOrderSplitService;
import cn.pluss.platform.notify.NotifyMessageService;
import cn.pluss.platform.refundOrder.MerchantRefundOrderService;
import cn.pluss.platform.util.*;
import cn.pluss.platform.yinsheng.YsOldSrcMerchantNo;
import cn.pluss.platform.ys.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

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

/**
 * 银盛老版支付接口实现类
 */
@Service("ysPayOldService")
@Slf4j
public class YsPayOldServiceImpl extends YsPayServiceImpl{


    @Resource
    private YsService ysService;

    @Resource
    private YsConfig ysConfig;

    @Resource
    private YsOldConfig ysOldConfig;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantOrderService merchantOrderService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantRefundOrderService merchantRefundOrderService;

    @Setter(onMethod_ = {@Autowired, @Lazy})
    private MerchantChannelStatusService merchantChannelStatusService;

    @Resource
    private ExecutorService executorService;

    @Resource
    private MercOrderNewService mercOrderNewService;

    @Resource
    private SubMercCodeYsMapper subMercCodeYsMapper;

    @Resource
    private JftReceiptOrderService jftReceiptOrderService;

    @Resource
    private MerchantOrderSplitService merchantOrderSplitService;

    @Resource
    private NotifyMessageService notifyMessageService;

    public static final String TIMEOUT_EXPRESS = "15m";

    /**
     * 缴费通支付
     * @param order
     * @param jftMerc
     * @param jftChannel
     * @return
     */
    @Override
    public JSONObject jftPay(JftReceiptOrder order, JftMercBaseInfo jftMerc, JftMercPaymentChannel jftChannel) {
        JSONObject reqData = new JSONObject(10);
        reqData.put("out_trade_no",order.getOrderNumber());
        reqData.put("shopdate",DateUtils.toString(DateUtils.currentDate(),"yyyyMMdd"));
        reqData.put("total_amount",order.getAmount());
        reqData.put("seller_id",jftChannel.getMerchantId());
        reqData.put("seller_name",jftChannel.getMercName());
        reqData.put("timeout_express",TIMEOUT_EXPRESS);
        if(StringUtil.isNotEmpty(order.getSubject())){
            reqData.put("subject",order.getSubject());
        }else{
            reqData.put("subject",jftMerc.getAlias());
        }
        reqData.put("business_code",YsBusinessCodeEnum.D0.getCode());
        reqData.put("buyer_id",order.getPayUserId());
        reqData.put("fail_notify_url",ParametersUtil.domain + "/wap/notify/old/ysCallBack");
        if(StringUtil.isNotEmpty(order.getPayUserCity())){
            SubMercCodeYs ysCodeCity = subMercCodeYsMapper.getSubMercCodeYsByCity(order.getPayUserCity());
            if(ysCodeCity != null){
                reqData.put("province",ysCodeCity.getPCode());
                reqData.put("city",ysCodeCity.getCode());
            }
        }
        YsEnum ysEnum = YsEnum.ALI_JS_PAY;
        if(Constant.PAY_TYPE_ALIPAY.equals(order.getPayType())){
            reqData.put("buyer_id", order.getPayUserId());
        }else{
            MsgException.throwException("暂未开通当前支付方式，请使用支付宝支付！");
        }
        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getPayDomain(), reqData, YsService.TYPE_PAY, ysEnum, YsOldSrcMerchantNo.RSCY.getValue());
        if(!YSConstants.SUCCESS_CODE.equals(respData.getString("code"))){
            String sub_code = respData.getString("sub_code");
            String sub_msg = respData.getString("sub_msg");
            if("4335".equals(sub_code) && StringUtil.isNotEmpty(sub_msg) && sub_msg.contains("金额超限")){
                MsgException.throwException("单笔交易金额超限");
            }else{
                MsgException.throwException(StringUtil.isNotEmpty(sub_msg) ? respData.getString("sub_msg") : respData.getString("msg"));
            }
        }
        JSONObject result = new JSONObject();
        result.put("code",ResultCode.SUCCESS.code());
        JSONObject payData = new JSONObject();
        JSONObject pData = respData.getJSONObject("jsapi_pay_info");
        payData.put("source",pData.get("tradeNO"));
        order.setTransNo(StringUtil.isEmpty(respData.getString("trade_no")) ? "" : respData.getString("trade_no"));
        result.put("payData",payData);
        return result;
    }

    /**
     * 正扫
     * @param order
     * @param channel
     * @return
     */
    @Override
    public JSONObject tradePay(MerchantOrder order, MerchantChannelStatus channel,MerchantBaseInfo merchant) {

        if(Constant.PAY_TYPE_YSFPAY.equals(order.getPayTypeCode())){
            MsgException.throwException("实时到账通道暂不支持银联支付，请修改次日到账交易");
        }
        if(StringUtil.isEmpty(channel.getSettlementType()) || YsBusinessCodeEnum.D0.getName().equals(channel.getSettlementType())){
            MsgException.check(order.getConsumeFee() < 0.2,"当前通道最少支付金额为0.2元！");
        }
        JSONObject reqData = setPayCommonParams(order,channel.getMerchantId());
        if(StringUtil.isNotEmpty(channel.getMercName())){
            reqData.put("seller_name",channel.getMercName());
        }
        reqData.put("business_code",YsBusinessCodeEnum.getCodeValue(channel.getSettlementType()));
        merchant.setChannelLimitPay(reqData,channel.getChannel());
        YsEnum ysEnum = null;
        if(StringUtil.isNotEmpty(order.getScanType()) && "01".equals(order.getScanType())){
            ysEnum = YsEnum.ACTIVE_QR_CODE_PAY;
            String bank_type = Constant.PAY_TYPE_WECHAT.equals(order.getPayTypeCode()) ? "1902000" : Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode()) ? "1903000" : "9001002";
            reqData.put("bank_type",bank_type);
        }else{
            reqData.put("sub_openid", ParametersUtil.APPID);
            if(Constant.PAY_TYPE_WECHAT.equals(order.getPayTypeCode())){
                ysEnum = YsEnum.WECHART_JS_PAY;
                // 会员充值主扫小程序  小程序当面付 10 小程序线上店
                if("3".equals(order.getOrderType()) || "9".equals(order.getOrderType()) || "10".equals(order.getOrderType())){
                    reqData.put("is_minipg", 1);
                    String defaultAppId = ParametersUtil.APPLETS_APPID;
                    if(order.getOrderNumber().contains("WAP") || order.getOrderNumber().contains("APP")){
                        defaultAppId = YsOldSrcMerchantNo.getSubAppIdByValue(channel.getSrcMerchantNo());
                    }else{
                        if(StringUtil.isNotEmpty(merchant.getSubAppId())){
                            defaultAppId = merchant.getSubAppId();
                        }
                    }
                    reqData.put("appid", defaultAppId);
                }else{
                    String appid = ParametersUtil.APPID;
                    if(StringUtil.isNotEmpty(merchant.getAppid())){
                        appid = merchant.getAppid();
                    }
                    reqData.put("appid", appid);
                    reqData.put("is_minipg", 2);
                }
                reqData.put("sub_openid",order.getMercUserId());
            }else if(Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode())){
                ysEnum = YsEnum.ALI_JS_PAY;
                reqData.put("buyer_id", order.getMercUserId());
            }else if(Constant.PAY_TYPE_YSFPAY.equals(order.getPayTypeCode())){
                ysEnum = YsEnum.YL_JS_PAY;
                reqData.put("spbill_create_ip", order.getIp());
                reqData.put("bank_type",YSConstants.YL_BANK_TYPE);
                reqData.put("device_info",StringUtil.genRandomNum(8));
                reqData.put("userId",order.getMercUserId());
            }
        }
        //支付失败通知地址
        reqData.put("fail_notify_url",ParametersUtil.domain + "/wap/notify/old/ysCallBack");
        if(StringUtil.isNotEmpty(order.getMercReturnUrl())){
            reqData.put("returnUrl",order.getMercReturnUrl());
        }
        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getPayDomain(), reqData, YsService.TYPE_PAY, ysEnum,channel.getSrcMerchantNo());

        if(!YSConstants.SUCCESS_CODE.equals(respData.getString("code"))){
            String sub_code = respData.getString("sub_code");
            String sub_msg = respData.getString("sub_msg");
            if("4335".equals(sub_code) && StringUtil.isNotEmpty(sub_msg) && sub_msg.contains("商户需补齐相关资料")){
                MsgException.throwException("D0实时到账：商户未在收银呗APP-商户认证-微信认证内完成授权，暂时无法微信收款");
            }else if("4335".equals(sub_code) && StringUtil.isNotEmpty(sub_msg) && sub_msg.contains("金额超限")){
                MsgException.throwException("单笔交易金额超限");
            }else{
                MsgException.throwException(StringUtil.isNotEmpty(sub_msg) ? respData.getString("sub_msg") : respData.getString("msg"));
            }
        }
        String tradeStatus = respData.getString("trade_status");

        if(!YsOldConstants.PAY_WAIT_BUYER_PAY.equals(tradeStatus)){
            MsgException.throwException("未知状态异常:"+tradeStatus);
        }

        JSONObject object = new JSONObject(3);

        object.put("code",ResultCode.SUCCESS.code());

        JSONObject payData = new JSONObject();
        if(StringUtil.isNotEmpty(order.getScanType()) && "01".equals(order.getScanType())){
            payData.put("payUrl",respData.getString("source_qr_code_url"));
            payData.put("mercOrderNo",order.getMercOrderNo());
            payData.put("orderNumber",order.getOrderNumber());
        }else{
            JSONObject pData = respData.getJSONObject("jsapi_pay_info");
            if(Constant.PAY_TYPE_WECHAT.equals(order.getPayTypeCode())) {
                payData.put("payAppId",pData.get("appId"));
                payData.put("payTimeStamp",pData.get("timeStamp"));
                payData.put("paynonceStr",pData.get("nonceStr"));
                payData.put("payPackage",pData.get("package"));
                payData.put("paySignType",pData.get("signType"));
                payData.put("paySign",pData.get("paySign"));
            }else if(Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode())){
                payData.put("source",pData.get("tradeNO"));
            }else{
                payData.put("redirectUrl",respData.get("web_url"));
            }
        }
        payData.put("channel",channel.getChannel());
        order.setTransNo(StringUtil.isEmpty(respData.getString("trade_no")) ? "" : respData.getString("trade_no"));
        object.put("payData",payData);
        return object;
    }

    /**
     * 反扫
     * @param merchantOrderDTO
     * @param order
     * @return
     */
    @Override
    public JSONObject tradePay(MerChantOrderDTO merchantOrderDTO, MerchantOrder order) {

        JSONObject reqData = setPayCommonParams(order, merchantOrderDTO.getChannelNo());
        if(StringUtil.isEmpty(merchantOrderDTO.getChannelStatus().getSettlementType()) || YsBusinessCodeEnum.D0.getName().equals(merchantOrderDTO.getChannelStatus().getSettlementType())){
            MsgException.throwException("实时到账通道暂不支持反扫收款，请切换次日自动到账通道！");
//            reqData.put("business_code",YsBusinessCodeEnum.FS_D0.getCode());
        }else{
            reqData.put("business_code",YsBusinessCodeEnum.getCodeValue(merchantOrderDTO.getChannelStatus().getSettlementType()));
        }
        if(StringUtil.isNotEmpty(merchantOrderDTO.getChannelStatus().getMercName())){
            reqData.put("seller_name",merchantOrderDTO.getChannelStatus().getMercName());
        }
        if(merchantOrderDTO.getMerchantBaseInfo() != null){
            merchantOrderDTO.getMerchantBaseInfo().setChannelLimitPay(reqData,Integer.valueOf(order.getAisleSwitch()));
        }
        if(Constant.PAY_TYPE_WECHAT.equals(order.getPayTypeCode())){
            reqData.put("bank_type",YSConstants.WX_BANK_TYPE);
        }else if(Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode())){
            reqData.put("bank_type",YSConstants.ALI_BANK_TYPE);
            reqData.put("scene","bar_code");
        }else if(Constant.PAY_TYPE_YSFPAY.equals(order.getPayTypeCode())){
            reqData.put("bank_type",YSConstants.YL_BANK_TYPE);
            reqData.put("device_info", StringUtil.genRandomNum(8));
        }else{
            //苏宁
            reqData.put("bank_type",YSConstants.SN_BANK_TYPE);
        }
        reqData.put("auth_code",merchantOrderDTO.getAuthCode());
        //是否限制信用卡 0和空表示不限制 1表示禁用信用卡
        reqData.put("limit_credit_pay","0");

        //交易失败通知地址
        reqData.put("fail_notify_url",ParametersUtil.domain + "/wap/notify/old/ysCallBack");
        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getPayDomain(), reqData, YsService.TYPE_PAY, YsEnum.BAR_CODE_PAY,merchantOrderDTO.getChannelStatus().getSrcMerchantNo());
        JSONObject result = new JSONObject();
        if(!YSConstants.SUCCESS_CODE.equals(respData.getString("code"))){
            MsgException.throwException(respData.getString("msg"));
        }
        if(YsOldConstants.PAY_TRADE_SUCCESS.equals(respData.getString("trade_status"))){

            order.setThirdTransNo(respData.getString("out_trade_no"));
            order.setTransNo(respData.getString("trade_no"));
            order.setMercUserId(respData.get("buyer_user_id") == null ? respData.getString("openid") : respData.getString("buyerId"));
            String card_type = respData.getString("card_type");
            if(StringUtil.isNotEmpty(card_type)){
                String drType = card_type.equals("debit") ? "1" : card_type.equals("credit") ? "2" : "3";
                order.setDrType(drType);
            }
            result.put("code",ResultCode.SUCCESS.code());
            result.put("payStatus","1");
            result.put("msg","请求成功！");
            result.put("payTime",new Date());
            result.put("channelOrderNo",respData.getString("out_trade_no"));
            result.put("transNo",respData.getString("trade_no"));
        }else if(YsOldConstants.PAY_TRADE_PROCESS.equals(respData.getString("trade_status"))){
            result.put("code", ResultCode.TRANSUNKNOW.code());
            result.put("msg","等待支付中...");
            result.put("payStatus","7");
        }else{
            result.put("code", ResultCode.FAIL.code());
            result.put("msg",respData.getString("sub_msg"));
            result.put("payStatus","0");
        }
        return result;
    }

    /**
     * 退款
     * @param order
     * @param mchNo
     * @return
     */
    @Override
    public Map<String, Object> refundPay(MerchantOrder order, String mchNo) {
        if(SettleTypeEnum.D0.getValue() == order.getSettlementType()){
            MsgException.throwException("当前订单不支持退款！");
        }
        MerchantChannelStatus channel = merchantChannelStatusService.getByMerchantId(mchNo);
        Map<String,Object> result = new HashMap<>(4);
        JSONObject reqData = new JSONObject(6);
        String refundNo = "YSR"+StringUtil.getBillno();
        reqData.put("out_trade_no",order.getOrderNumber());
        reqData.put("shopdate",DateUtils.formatDateDefault(new Date(),"yyyyMMdd"));
        reqData.put("trade_no",order.getTransNo());
        reqData.put("refund_amount",StringUtil.isNotEmpty(order.getRefundType()) && order.getRefundType() == 2 ? order.getRefundAmt() : order.getConsumeFee());
        reqData.put("refund_reason",StringUtil.isEmpty(order.getRemark()) ? "申请退款" : order.getRemark());
        reqData.put("out_request_no",refundNo);

        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getCommonDomain(), reqData, YsService.TYPE_PAY, YsEnum.REFUND_PAY,channel.getSrcMerchantNo());

        MsgException.check(!YSConstants.SUCCESS_CODE.equals(respData.getString("code")),respData.getString("sub_msg"));

        result.put("refundNo",refundNo);
        result.put("msg","退款成功！");
        result.put("data",respData);
        result.put("status","1");
        result.put("code",ResultCode.SUCCESS.code());
        return result;
    }

    /**
     * 交易查询
     * @param order
     * @param mchId
     * @return
     */
    @Override
    public JSONObject tradeQuery(MerchantOrder order, String mchId) {
        JSONObject result = new JSONObject();
        JSONObject reqData = new JSONObject(8);
        reqData.put("out_trade_no",order.getOrderNumber());
        reqData.put("shopdate",DateUtils.formatDateDefault(order.getCreateDt(),"yyyyMMdd"));
        MerchantChannelStatus channel = merchantChannelStatusService.getByMerchantId(mchId);
        try {
            JSONObject respones = ysService.requestOldApiCommon(ysConfig.getSearchDomain(), reqData, YsService.TYPE_OTHER, YsEnum.QRDER_QUERY,channel.getSrcMerchantNo());
            String code = respones.getString("code");
            if(!YSConstants.SUCCESS_CODE.equals(code)){
                MsgException.throwException(respones.getString("msg"));
            }
            String trade_status = respones.getString("trade_status");
            result.put("code", ResultCode.SUCCESS.code());
            result.put("msg", "查询成功！");
            if(YsOldConstants.PAY_TRADE_SUCCESS.equals(trade_status)){
                String trade_no = respones.getString("trade_no");
                JSONArray payList = respones.getJSONArray("pay_detail_list");
                JSONArray quickList = respones.getJSONArray("quick_pay_detail_list");
                if(quickList != null && quickList.size() > 0){
                    JSONObject quickObj = quickList.getJSONObject(0);
                    String quickFee = quickObj.getString("payee_fee");
                    result.put("cashFee",quickFee);
                }
                if(payList.size() > 0){
                    JSONObject payObj = payList.getJSONObject(0);
                    String payTime = payObj.getString("pay_success_time");
                    if(StringUtil.isNotEmpty(payTime)){
                        result.put("payTime",DateUtils.parse(payTime,"yyyy-MM-dd HH:mm:ss"));
                    }else{
                        result.put("payTime",new Date());
                    }
                    String fee = payObj.getString("payee_fee");
                    result.put("fee",fee);
                }else{
                    result.put("payTime",new Date());
                }
                result.put("transNo",trade_no);
                String transactionId = respones.getString("channelRecvNo");//支付渠道单号
//                if(StringUtil.isNotEmpty(transactionId)){
//                    transactionId = transactionId.substring(2);
//                }
                result.put("channelOrderNo",transactionId);
                result.put("payStatus", "1");
//                result.put("buyerId", buyerId);
            }else if(YsOldConstants.PAY_WAIT_BUYER_PAY.equals(trade_status) || YsOldConstants.PAY_TRADE_PROCESS.equals(trade_status)){
                result.put("payStatus", "5");
            }else if(YsOldConstants.PAY_TRADE_PART_REFUND.equals(trade_status)){
                //部分退款
                result.put("payStatus", "6");
            }else if(YsOldConstants.PAY_TRADE_ALL_REFUND.equals(trade_status)){
                //全部退款
                result.put("payStatus", "9");
            }else {
                result.put("payStatus", "0");
            }
            return result;
        }catch (RuntimeException e){
            result.put("code", ResultCode.FAIL.code());
            result.put("msg", e.getMessage());
            return result;
        }
    }

    /**
     * 退款查询
     * @param refundOrder
     * @return
     */
    @Override
    public JSONObject refundQuery(MerchantRefundOrder refundOrder) {
        JSONObject reqData = new JSONObject(2);
        reqData.put("out_trade_no",refundOrder.getOrderNumber());
        reqData.put("out_request_no",refundOrder.getRefundNo());
        MerchantChannelStatus channel = merchantChannelStatusService.getByMerchantCode(refundOrder.getMerchantCode(),4);
        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getCommonDomain(), reqData, YsService.TYPE_OTHER, YsEnum.REFUND_PAY_QUERY,channel.getSrcMerchantNo());
        JSONObject result = new JSONObject();
        if(!YSConstants.SUCCESS_CODE.equals(respData.getString("code"))){
            MsgException.throwException(respData.getString("msg"));
        }
        if("success".equals(respData.getString("refund_state"))){
            result.put("code",ResultCode.SUCCESS.code());
            result.put("status","1");
            result.put("msg","退款成功！");
        }else if("in_process".equals(respData.getString("refund_state"))){
            result.put("code", ResultCode.TRANSUNKNOW.code());
            result.put("msg","退款中");
            result.put("status","2");
        }else{
            result.put("code", ResultCode.FAIL.code());
            result.put("payStatus","3");
            result.put("msg","退款失败");
        }
        return result;
    }

    /**
     * 获取银联用户标识
     * @param userAuthCode
     * @param paymentApp
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getUnionInfo(String userAuthCode, String paymentApp,String merchantId) throws Exception {

        if(StringUtil.isEmpty(userAuthCode)){
            throw new MsgException("授权码不能为空！");
        }
        if(StringUtil.isEmpty(paymentApp)){
            throw new MsgException("银联标识不能为空！");
        }
        MerchantChannelStatus channel = merchantChannelStatusService.getByMerchantId(merchantId);
        JSONObject reqData = new JSONObject(2);
        reqData.put("userAuthCode",userAuthCode);
        reqData.put("appUpIdentifier",paymentApp);
        JSONObject respones = ysService.requestOldApiCommon(ysConfig.getPayDomain(), reqData, YsService.TYPE_OTHER, YsEnum.YS_USERID_AUTH,channel.getSrcMerchantNo());
        if(YSConstants.FAILED.equalsIgnoreCase(respones.getString("trade_status"))){
            throw new MsgException(respones.getString("sub_msg"));
        }
        JSONObject result = new JSONObject();
        reqData.put("data",respones.getString("userId"));
        result.put("data",reqData);
        result.put("code","1");
        result.put("msg","获取成功");
        return result;
    }
    /**
     * @description:
     * @date: 2021/8/20 10:04
     * @param params:
     * @return java.lang.String
     */
    @Override
    public String payNotifyCallBack(Map<String,String> params){
        if(!checkSign(params)) return YsConfig.YS_RESULT_FAIL_CODE;
        //商户单号
        String ordNo = params.get("out_trade_no");
        //银盛交易流水号，32位
        String ysTradeNo = params.get("trade_no");
        String notify_type = params.get("notify_type");
        //交易时间 yyyy-MM-dd HH:mm:ss
        String payTime = params.get("notify_time");
        //交易状态
        String tradeStatus = params.get("trade_status");
        //借贷标识
        String card_type = params.get("card_type");
        //发送渠道流水号
        String channel_send_sn = params.get("channel_send_sn");
        //openid
        String openid = params.get("openid");
        Date payDate = DateUtils.parse(payTime, "yyyy-MM-dd HH:mm:ss");
        if(YsNotifyTypeEnum.DIVISION.getCode().equals(notify_type)){
            String division_status_code = params.get("division_status_code");
            String note = StringUtil.isEmpty(params.get("note")) ? "" : params.get("note");
            String division_status = StringUtil.isEmpty(params.get("division_status")) ? "" : params.get("division_status");
            MerchantOrderSplit orderSplit = merchantOrderSplitService.getByOrderNumber(ordNo);
            if(orderSplit != null){
                if("00".equals(division_status_code)){
                    orderSplit.setDivStatus(2);
                }else if("01".equals(division_status_code)){
                    orderSplit.setDivStatus(1);
                }else if("02".equals(division_status_code)){
                    orderSplit.setDivStatus(3);
                }else if("03".equals(division_status_code)){
                    orderSplit.setDivStatus(4);
                }else{
                    orderSplit.setDivStatus(-1);
                }
                orderSplit.setDivStatusCode(division_status_code);
                orderSplit.setRemark(note + "-"+division_status);
                merchantOrderSplitService.updateById(orderSplit);
                // 推送分账通知
                executorService.execute(() -> notifyMessageService.sendLowerSplitNotify(orderSplit));
            }
        }else{
            MercOrderNew newOrder = mercOrderNewService.getOrderByNo(ordNo);
            if(newOrder != null){
                log.info("====================>【银盛】新版设备订单回调,订单号:{}<====================",newOrder.getOrderNo());
                if(YsOldConstants.PAY_TRADE_SUCCESS.equals(tradeStatus)){
                    String channelRecvNo = params.get("channel_recv_sn");
                    if(Constant.PAY_TYPE_ALIPAY.equals(newOrder.getPayType())){
                        channelRecvNo = channelRecvNo.substring(2);
                    }
                    mercOrderNewService.devicePaySuccessNotifyV2(newOrder.getOrderNo(),ysTradeNo,channelRecvNo,payDate,newOrder);
                }
                return YsConfig.RESULT_SUCCESS_CODE;
            }
            JftReceiptOrder jftOrder = jftReceiptOrderService.getOrderByNo(ordNo);
            if(jftOrder != null){
                log.info("====================>【银盛】缴费通订单回调,订单号:{}<====================",jftOrder.getOrderNumber());
                if(YsOldConstants.PAY_TRADE_SUCCESS.equals(tradeStatus)){
                    String channelRecvNo = params.get("channel_recv_sn");
                    if(Constant.PAY_TYPE_ALIPAY.equals(jftOrder.getPayType())){
                        channelRecvNo = channelRecvNo.substring(2);
                    }
                    jftOrder.setTransNo(ysTradeNo);
                    jftOrder.setTransTime(payDate);
                    jftOrder.setChannelTransNo(channelRecvNo);
                    executorService.execute(() -> jftReceiptOrderService.updatePaySuccessNotify(jftOrder));
                }
                return YsConfig.RESULT_SUCCESS_CODE;
            }
            //支付通知
            QueryWrapper<MerchantOrder> orderWrapper = new QueryWrapper<MerchantOrder>()
                    .eq("orderNumber",ordNo).in("status","5","7");
            MerchantOrder order = merchantOrderService.getOne(orderWrapper);
            if(order == null){
                log.error("====================>【银盛】支付成功回调根据订单号查询带支付的订单，查询的订单为空：订单号：{}<====================",ordNo);
                return YsConfig.RESULT_SUCCESS_CODE;
            }
            if(YSConstants.REFUND_PAY_NOTIFY_CODE.equals(notify_type)){
                log.info("====================>【银盛】退款成功回调，我方原订单号：{}<====================",ordNo);
                QueryWrapper<MerchantRefundOrder> queryWrapper = new QueryWrapper<MerchantRefundOrder>()
                        .eq("orderNumber",ordNo).eq("channelNo",ysTradeNo).eq("status","2");
                MerchantRefundOrder refundOrder = merchantRefundOrderService.getOne(queryWrapper);
                if(refundOrder == null){
                    log.error("====================>【银盛】退款成功回调，我方原订单号：{}，银盛原订单号：{}，查询出的退款订单为空！<====================",ordNo,ysTradeNo);
                }else{
                    if("2".equals(refundOrder.getStatus())){
                        refundOrder.setRefundTime(payDate);
                        refundOrder.setStatus("1");
                        refundOrder.setFailMsg("退款成功");
                        executorService.execute(() -> merchantRefundOrderService.updateOrderAndSendNotify(refundOrder));
                    }else{
                        log.error("====================>【银盛】退款订单状态有误，当前退款订单状态为：{}！<====================",refundOrder.getStatus());
                    }
                }
            }else if(YSConstants.FAIL_PAY_NOTIFY_CODE.equals(notify_type)){
                log.info("====================>【银盛】支付失败回调通知,notify_type参数：{}<====================",notify_type);
                merchantOrderService.updateFailOrder(order,tradeStatus,params.get("result_note"));
            }else{
                if("TRADE_SUCCESS".equals(tradeStatus)){
                    String channelRecvNo = params.get("channel_recv_sn");
                    if(Constant.PAY_TYPE_ALIPAY.equals(order.getPayTypeCode())){
                        channelRecvNo = channelRecvNo.substring(2);
                    }
                    //交易金额
                    String total_amount = params.get("total_amount");
                    BigDecimal tradeAmt = new BigDecimal(total_amount);
                    //收款方手续费
                    String payee_fee = StringUtil.isEmpty(params.get("payee_fee")) ? "0" : params.get("payee_fee");
                    BigDecimal enterFee = tradeAmt.subtract(new BigDecimal(payee_fee)).setScale(2,BigDecimal.ROUND_UP);
                    if(SettleTypeEnum.D0.getValue().intValue() == order.getSettlementType().intValue()){
                        //提现手续费
                        MerchantChannelStatus channel = merchantChannelStatusService.getByMerchantCode(order.getMerchantCode(), 4);
                        try{
                            JSONObject result = tradeQuery(order, channel.getMerchantId());
                            String cashFee = result.getString("cashFee");
                            if(StringUtil.isNotEmpty(cashFee) && BigDecimal.ZERO.compareTo(new BigDecimal(cashFee)) != 0){
                                order.setCashFee(new BigDecimal(cashFee).setScale(2,BigDecimal.ROUND_HALF_UP));
                                enterFee = enterFee.subtract(new BigDecimal(cashFee));
                            }else{
                                BigDecimal defaultFee = BigDecimal.valueOf(0.1);
                                Date createTime = channel.getCreateTime();
                                Date defaultTime = DateUtils.parse("2022-01-15");
                                if(createTime.compareTo(defaultTime) > 0){
                                    defaultFee  = BigDecimal.valueOf(0.01);
                                }
                                BigDecimal wFee = tradeAmt.multiply(new BigDecimal("0.001"));
                                if(wFee.doubleValue() < defaultFee.doubleValue()){
                                    order.setCashFee(defaultFee);
                                    enterFee = enterFee.subtract(defaultFee).setScale(2,BigDecimal.ROUND_DOWN);
                                }else{
                                    order.setCashFee(wFee);
                                    enterFee = enterFee.subtract(wFee).setScale(2,BigDecimal.ROUND_DOWN);
                                }
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    order.setEnterFee(enterFee.doubleValue());
                    order.setTransDt(payDate);
                    order.setTransNo(ysTradeNo);
                    order.setStatus("1");
                    if(StringUtil.isNotEmpty(card_type)){
                        if(YsCardTypeEnum.DEBIT_TYPE.getCode().equals(card_type)){
                            order.setDrType(YsCardTypeEnum.DEBIT_TYPE.getValue());
                        }else if(YsCardTypeEnum.CREDIT_TYPE.getCode().equals(card_type)){
                            order.setDrType(YsCardTypeEnum.CREDIT_TYPE.getValue());
                        }else{
                            order.setDrType(YsCardTypeEnum.OTHER_TYPE.getValue());
                        }
                    }else{
                        order.setDrType(YsCardTypeEnum.OTHER_TYPE.getValue());
                    }
                    order.setThirdTransNo(channelRecvNo);
                    if(StringUtil.isEmpty(order.getMercUserId())){
                        order.setMercUserId(openid);
                    }
                    order.setRemark(channel_send_sn);
                    executorService.execute(() -> merchantOrderService.updateOrderAndCreateProfit(order));
                }else{
                    merchantOrderService.updateFailOrder(order,tradeStatus,"");
                }
            }
        }
        return YsConfig.RESULT_SUCCESS_CODE;
    }

    /**
     * @description:校验签名
     * @date: 2021/8/23 10:06
     * @param params:
     * @return boolean
     */
    private boolean checkSign(Map<String, String> params) {
        String sign = params.get("sign");
        params.remove("sign");
        JSONObject paramsData = JSONObject.parseObject(JSONObject.toJSONString(params));
        String signContent = SignUtils.getYSSignContent(paramsData);
        boolean flag = false;
        try {
            flag = RSAUtils.checkSign(ysOldConfig.getOldPubKey(),signContent,sign);
        } catch (Exception e) {
            log.info("=========================>【银盛】校验签名异常，异常信息:{}<=====================",e.getMessage());
            e.printStackTrace();
        }
        return flag;
    }
    /**
     * @description:组装支付公共参数
     * @date: 2021/9/29 11:54
     * @param order:
     * @param merchantId:
     * @return com.alibaba.fastjson.JSONObject
     */
    private JSONObject setPayCommonParams(MerchantOrder order,String merchantId) {
        JSONObject reqData = new JSONObject(8);
        reqData.put("out_trade_no",order.getOrderNumber());
        reqData.put("shopdate",DateUtils.formatDateDefault(new Date(),"yyyyMMdd"));
        if(StringUtil.isNotEmpty(order.getSubject())){
            reqData.put("subject",order.getSubject());
        }else if(StringUtil.isNotEmpty(order.getMercRemark())){
            reqData.put("subject",order.getMercRemark());
        }else{
            reqData.put("subject",order.getMerchantName());
        }
        reqData.put("total_amount",order.getConsumeFee().toString());
        reqData.put("seller_id",merchantId);
        reqData.put("seller_name",StringUtil.isNotEmpty(order.getAlias()) ? order.getAlias() : order.getMerchantName());
        reqData.put("timeout_express",TIMEOUT_EXPRESS);
        reqData.put("submer_ip","127.0.0.1");
        if(StringUtil.isNotEmpty(order.getExtendParam())){
            reqData.put(Constant.YS_PAY_ECHO_KEY_NAME,order.getExtendParam());
        }
        if(StringUtil.isNotEmpty(order.getCity())){
            reqData.put("province",order.getProvince());
            reqData.put("city",order.getCity());
        }
        else{
            String ipAddress = order.getIpAddress();
            if(StringUtil.isNotEmpty(ipAddress)){
                String[] area = ipAddress.split("-");
                if(area.length == 2 && StringUtil.isNotEmpty(area[1])){
                    String city = area[1];
                    SubMercCodeYs areaInfo = subMercCodeYsMapper.getSubMercCodeYsByCity(city);
                    if(areaInfo != null){
                        reqData.put("province",areaInfo.getPCode());
                        reqData.put("city",areaInfo.getCode());
                    }
                }
            }
        }

        return reqData;
    }

    @Override
    public String tradePayWap(MerchantOrder order, MerchantChannelStatus channel) {
        JSONObject reqData = bulidWapParams(order,channel);
        String signContent = SignUtils.getYSSignContent(reqData);
        try {
            reqData.put("sign",RSAUtils.sign(ysConfig.getPriKey(), signContent));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return StringUtil.buildPostForm(ysConfig.getCommonDomain(), reqData.toJavaObject(Map.class));
    }


    private JSONObject bulidWapParams(MerchantOrder order,MerchantChannelStatus channel) {
        JSONObject request = new JSONObject();
        request.put("method",YsEnum.YS_WAP_PAY.getApiName());
        request.put("partner_id",ysConfig.getSrcMerchantNo());
        request.put("timestamp",DateUtils.currentYourDate("yyyy-MM-dd HH:mm:ss"));
        request.put("charset","utf-8");
        request.put("sign_type","RSA");
        request.put("version","3.0");
        request.put("notify_url",ParametersUtil.domain + "/wap/notify/old/ysCallBack");
        request.put("return_url",ParametersUtil.domain + "/wap/activity/good?token="+order.getToken());

        request.put("out_trade_no",order.getOrderNumber());
        request.put("subject",order.getMerchantName());
        request.put("total_amount",order.getConsumeFee().toString());
        request.put("seller_id",channel.getMerchantId());
        if(StringUtil.isNotEmpty(channel.getMercName())){
            request.put("seller_name",channel.getMercName());
        }else{
            request.put("seller_name",StringUtil.isNotEmpty(order.getAlias()) ? order.getAlias() : order.getMerchantName());
        }
        request.put("timeout_express",TIMEOUT_EXPRESS);
        request.put("business_code",YsBusinessCodeEnum.D1.getCode());
        request.put("pay_mode","native");
        request.put("bank_type","1903000");
        request.put("tran_type","1");
        request.put("shopdate",DateUtils.currentYourDate("yyyyMMdd"));
        return request;
    }
    /**
     * @description:获取分账参数
     * @date: 2021/11/26 11:03
     * @param divParans:
     * @param settingList:
     */
    private JSONObject setDivMerchantParams(JSONObject divParans, List<MerchantSplitSetting> settingList) {
        MsgException.checkNull(divParans.getString("merchantCode"),"分账商户号有误！");
        JSONObject result = new JSONObject();
        boolean flag = false;
        for (MerchantSplitSetting setting:settingList) {
            if(divParans.getString("merchantCode").equals(setting.getDiviMerchantCode())){
                flag = true;
                result.put("division_mer_usercode",setting.getDiviMerchantId());
                break;
            }
        }
        if(!flag){
            MsgException.throwException("分账商户号有误！");
        }
        return result;
    }

    @Override
    public JSONObject getUnionAccountUrl(JSONObject reqData) {
        JSONObject respData = ysService.requestOldApiCommon(ysConfig.getCommonDomain(), reqData, YsService.TYPE_OTHER, YsEnum.YS_UNION_ACCOUNT,null);
        if(!YSConstants.SUCCESS_CODE.equals(respData.getString("code"))){
            MsgException.throwException(respData.getString("msg"));
        }
        String state = respData.getString("state");
        if(!Constant.RESULT_CODE_SUCCESS.equals(state)){
            MsgException.throwException(respData.getString("desc"));
        }
        JSONObject result = new JSONObject(1);
        result.put("url",respData.getString("bill_download_url"));
        return result;
    }
}
