package cn.pluss.platform.sxf.impl;

import cn.pluss.platform.channel.MchMachineCallbackService;
import cn.pluss.platform.constants.Constant;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchant.MerchantCashPlaceService;
import cn.pluss.platform.merchant.MerchantRateNewService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.merchantOrder.MerchantOrderService;
import cn.pluss.platform.merchantProfit.MerchantProfitService;
import cn.pluss.platform.merchantStore.MerchantStoreService;
import cn.pluss.platform.realFans.RealFansService;
import cn.pluss.platform.refundOrder.MerchantRefundOrderService;
import cn.pluss.platform.suixingfu.SxfConstants;
import cn.pluss.platform.sxf.SxfService;
import cn.pluss.platform.transfer.MerchantTransferService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userAssess.UserAssessService;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.util.SxfConfg;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RequiredArgsConstructor
@Slf4j
@Service("sxfMchMachineCallbackService")
public class SxfMchMachineCallbackServiceImpl implements MchMachineCallbackService {

    private final SxfService sxfService;

    private final MerchantChannelStatusService merchantChannelStatusService;

    private final MerchantBaseInfoService mbiService;

    private final MerchantStoreService merchantStoreService;

    private final MerchantProfitService merchantProfitService;

    private final MerchantOrderService merchantOrderService;

    private final MerchantRefundOrderService merchantRefundOrderService;

    private final RealFansService realFansService;

    private final MerchantTransferService merchantTransferService;

    private final MerchantRateNewService merchantRateNewService;

    private final MerchantCashPlaceService merchantCashPlaceService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Autowired
    private UserAssessService userAssessService;



    @Override
    public String getOperationType(JSONObject param) {
        boolean sign;
        try {
            sign = sxfService.checkSign(param);
        } catch (Exception e) {
            e.printStackTrace();
            throw new MsgException("随行付机具回调数据验签不通过");
        }

        if (!sign) {
            throw new MsgException("随行付机具回调数据验签不通过");
        }
        /** 扫码王回调 **/
        if(StringUtil.isNotEmpty(param.get("tradeType"))){
            if ("01".equals(param.get("tradeType"))) {
                return OPERATION_PAY;
            }
            if ("02".equals(param.get("tradeType"))) {
                return OPERATION_REFUND;
            }
        }else{
            /** 智能pos回调 **/
            return SxfConstants.SXF_POS_OPERATION;
        }
        return null;
    }

    /**
     * @param param
     * {
     * 	"pointAmount": "0.00",                      // 代金券金额
     * 	"payTime": "20200904114847",        // 支付时间
     * 	"openid": "2088912149418434",       // 微信openid
     * 	"sign": "ROZ2UFvc36Vzqvtofv6Wz0kw5EG73jsEDwI+T5llhjJdTCkQxCTNJlvvIIqAFNoK1KG+YHFk/ouASXYMtSb5KaTRD0JbhscTDvS9fjds25gR/Aop7Ri73YSJ3nHVXbmPIxw4/uaLPgoOde3xT4vGUHOmH3W0izuudyFHnP4GNwiwQfdj0iB9CZI7SELSzIaT6c6ONz8BOkxltV9vZ+ztjcg0Yp6NY9MvdRXGS52oOYxyB5Ju+s3HYTP8SlBnyXGETVXYgycHNkS3vSSO5FmxzS9yWX4cpq5u7E2K4EnUW6n7f4oxSKv8x2D3jQj3vDzVfRsm2ARXFRpuYIFROz5Row==",
     * 	"payWay": "01",                                     // 	交易方式
     * 	"amt": "0.10",                                          //  交易金额
     * 	"terminalId": "000002P61510411183",     //  终端编号
     * 	"sxfUuid": "836200904394114910",            // 落单号，供退款和退款查询使用
     * 	"deviceNo": "10017314",                               // 设备号
     * 	"buyerId": "2088912149418434",                 //  	买家用户号
     * 	"uuid": "28a6170a70a1433a86b84f8873107371",     // 	流水号
     * 	"orgId": "56964586",                                                        //  机构号
     * 	"transactionId": "2020090422001418431453254768",    // 交易流水
     * 	"scene": "1",                                                                               // 支付场景
     * 	"mno": "399200827954886",                                                 // 随行付商户id
     * 	"timeStamp": "20200904114848",                                        // 响应时间
     * 	"ordNo": "15104111832020090411483384476170",        // 商户订单号
     * 	"payType": "ALIPAY",                                                                // 交易渠道，支付宝&微信&银联
     * 	"buyerAccount": "173******68",                                             // 顾客帐号，加密
     * 	"subMechId": "2088900529374371",                                    // 子商户号
     * 	"drType": "1",                                                                              //	借贷标识
     * 	"tradeType": "01",                                                                      // 交易类型
     * 	"channelId": "2088531229750653"                                        // 渠道商户号
     * }
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void payCallback(JSONObject param) {
        String mno = param.getString("mno");
        String buyerId = param.getString("buyerId");
        QueryWrapper<MerchantChannelStatus> queryWrapper = new QueryWrapper<MerchantChannelStatus>().eq("merchantId", mno);
        MerchantChannelStatus merchantChannelStatus = merchantChannelStatusService.getOne(queryWrapper);
        if (merchantChannelStatus == null) {
            throw new RuntimeException("未知商户");
        }
        MerchantBaseInfo merchantBaseInfo = mbiService.getMerchantBaseInfoByMerchantCode(merchantChannelStatus.getMerchantCode());
        MerchantStore merchantStore = new MerchantStore().setMerchantCode(merchantChannelStatus.getMerchantCode());
        merchantStore = merchantStoreService.queryMerchantStore(merchantStore);

        MerchantOrder existData = new MerchantOrder();
        existData.setOrderNumber(param.getString("ordNo"));
        existData = merchantOrderService.queryMerchantOrder(existData);
        if (existData != null) {
            return;
        }

        MerchantOrder merchantOrder = new MerchantOrder();
        merchantOrder.setStaffCode(merchantStore.getStoreId());
        merchantOrder.setStaffName(merchantBaseInfo.getAlias());
        merchantOrder.setStatus("1");

        String payType = param.getString("payType");
        if (payType != null) {
            merchantOrder.setThirdTransNo(param.getString("transactionId"));
            switch (payType) {
                case "WECHAT":
                    merchantOrder.setPayTypeCode("sxfPay1");
                    merchantOrder.setPayTypeName("随行微信支付");
                    break;
                case "ALIPAY":
                    merchantOrder.setPayTypeCode("sxfPay0");
                    merchantOrder.setPayTypeName("随行支付宝支付");
                    break;
                case "UNIONPAY":
                    merchantOrder.setPayTypeCode("sxfPay2");
                    merchantOrder.setPayTypeName("随行云闪付支付");
                    break;
                default:
                    break;
            }
        }
        merchantOrder.setOrderNumber(param.getString("ordNo"));
        merchantOrder.setOrderType("6");
        merchantOrder.setMerchantCode(merchantChannelStatus.getMerchantCode());
        merchantOrder.setMerchantName(merchantBaseInfo.getAlias());
        merchantOrder.setStoreId(merchantStore.getStoreId());
        merchantOrder.setStoreName(merchantBaseInfo.getAlias());
        merchantOrder.setConsumeFee(Double.valueOf(param.getString("amt")));
        merchantOrder.setTransNo(param.getString("uuid"));
        //借贷标识
        merchantOrder.setDrType(param.getString("drType"));

        //插入通道费率 已经通道成本手续费
        merchantOrder.setChannelRate(SxfConstants.CHANNEL_WECHAT_ALIPAY_BANK_COST_RATE.multiply(new BigDecimal(10000)));
        BigDecimal channelFee = new BigDecimal(merchantOrder.getConsumeFee().toString()).multiply(SxfConstants.CHANNEL_WECHAT_ALIPAY_BANK_COST_RATE).setScale(2,BigDecimal.ROUND_HALF_UP);
        merchantOrder.setChannelFee(channelFee);

        try {
            Date date = DateUtils.parseDate(param.getString("payTime"), "yyyyMMddHHmmss");
            merchantOrder.setCreateDt(date);
            merchantOrder.setTransDt(date);
            merchantOrder.setUpdateTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        BigDecimal rate = merchantRateNewService.getMchRate(merchantBaseInfo.getMerchantCode(),merchantOrder.getPayTypeCode(), merchantOrder.getConsumeFee());
        merchantOrder.calcRateAndFee(rate);
        merchantOrder.setAisleSwitch("2");
        merchantOrder.setMercUserId(buyerId);

        //获取设备号
        String deviceNo = param.getString("terminalId");
        merchantOrder.setSnNo(deviceNo);
        merchantCashPlaceService.setOrderPlaceInfo(merchantOrder,deviceNo);
        //设置活动积分
        merchantOrderService.setActivityMarketAmt(merchantOrder,merchantStore);

        boolean flag = merchantOrderService.save(merchantOrder);
        //扫码王收款成功 app推送
        if(flag){
            List<String> alias = new ArrayList<>();
            alias.add(merchantBaseInfo.getUserId());
            String msgCountent = "收银呗到账" + merchantOrder.getConsumeFee().toString() + "元";
            sendAppNotify(alias,"收银呗到账通知",msgCountent,"3");

            try {
                MerchantBaseInfo.setFirstAndLastTradeTime(merchantBaseInfo, merchantOrder.getUpdateTime());
//                userAssessService.checkUserValid(merchantBaseInfo);
                mbiService.updateById(merchantBaseInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {
            //创建推广分润
            merchantProfitService.createOrderProfitV2(merchantOrder,"1");
            MerchantOrder update = new MerchantOrder();
            if(flag){
                update.setId(merchantOrder.getId());
                update.setProfitShareMoney(merchantOrder.getProfitShareMoney());
                merchantOrderService.updateById(update);
            }
        }catch (RuntimeException e){
            log.info("扫码王收款,创建分润失败,异常信息:{}",e.getMessage());
        }
    }

    /**
     * 扫码王收款成功 app推送
     * @param alias
     * @param title
     * @param msgContent
     * @param extrasParams
     */
    private void sendAppNotify(List<String> alias,String title,String msgContent,String extrasParams) {
        generalPushUtil.sendAllPlatByAlias(alias, title, msgContent, extrasParams);
    }

    /**
     * @param param
     * {
     * 	"origOrderNo": "15104111832020090411483384476170",
     * 	"pointAmount": "",
     * 	"payTime": "20200904155120",
     * 	"sign": "afJkmTiOhh5NcznVUB6PWNpjXDhn5BXDnpI3Wzdy9ukbOTl2PictFugusTbACHob+j/n6poNyOqE+mpnIHujUa1gLDX9iiBKIM4uyx+trdgXCXPaAt0RCOkxfAD0hksDdPQ++nvTO8JuvFPIUv3JbSrR1wtp8m06eIzmOi06uDQHrlXRkD+HFbHYJ/2hL2FtUL3GydPJVEV+6ORRWBSr5BfymJv369K6sd6vQTgje2EkuhnzgPjlV+QpzW8y7JU6RyTwA6fYDXqS1Vb8ZJdy4yXLUEKMTzCZEwOkZwtU7DO2ZbxiJf01E3V+Unk4xSeYt7Ssa6dh41qSvrseacyd6g==",
     * 	"amt": "0.10",
     * 	"payWay": "05",
     * 	"terminalId": "000002P61510411183",
     * 	"deviceNo": "10017314",
     * 	"uuid": "a04aee5c6e7b47929d0818a61e690aa5",
     * 	"transactionId": "2020090422001418431453254768",
     * 	"orgId": "56964586",
     * 	"mno": "399200827954886",
     * 	"timeStamp": "20200904155126",
     * 	"ordNo": "15104111832020090415505766488690",
     * 	"payType": "ALIPAY",
     * 	"origOrdNo": "15104111832020090411483384476170",
     * 	"origAmt": "0.10",
     * 	"origUuid": "28a6170a70a1433a86b84f8873107371",
     * 	"totalOffstAmt": "0.10",
     * 	"recFeeAmt": "0",
     * 	"drType": "",
     * 	"realRefundAmount": "0.1",
     * 	"tradeType": "02"
     * }
     */
    @Override
    public void refundCallback(JSONObject param) {
        String origOrderNo = param.getString("origOrderNo");
        MerchantOrder merchantOrder = new MerchantOrder().setOrderNumber(origOrderNo).setStatus("1");
        merchantOrder = merchantOrderService.queryMerchantOrder(merchantOrder);

        String mno = param.getString("mno");
        QueryWrapper<MerchantChannelStatus> queryWrapper = new QueryWrapper<MerchantChannelStatus>().eq("merchantId", mno);
        MerchantChannelStatus merchantChannelStatus = merchantChannelStatusService.getOne(queryWrapper);

        if (merchantOrder == null) {
            throw new MsgException("未找到对应订单");
        }

        MerchantOrder existData = new MerchantOrder();
        existData.setOrderNumber(param.getString("origOrderNo")).setStatus("2");
        existData = merchantOrderService.queryMerchantOrder(existData);
        if (existData != null) {
            return;
        }

        MerchantRefundOrder merchantRefundOrder = new MerchantRefundOrder();
        try {
            merchantOrder.setUpdateTime(DateUtils.parseDate(param.getString("payTime"), "yyyyMMddHHmmss"));
            merchantOrder.setStatus("2");
            merchantOrder.setId(null);
            String realRefundAmount = StringUtil.isEmpty(param.getString("realRefundAmount")) ? merchantOrder.getConsumeFee().toString() : param.getString("realRefundAmount");
            merchantOrder.setConsumeFee(new BigDecimal(realRefundAmount).setScale(2,BigDecimal.ROUND_UP).doubleValue());
            merchantRefundOrder.setPayTime(merchantOrder.getTransDt());
            merchantOrderService.save(merchantOrder);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        String refundOrderNumber = param.getString("ordNo");
        merchantRefundOrder.setMerchantCode(merchantOrder.getMerchantCode());
        merchantRefundOrder.setRefundTime(merchantOrder.getUpdateTime());
        merchantRefundOrder.setStatus("1");
        merchantRefundOrder.setAisleSwitch("2");
        merchantRefundOrder.setAlias(merchantOrder.getMerchantName());
        merchantRefundOrder.setChannelNo(merchantOrder.getOrderNumber());
        merchantRefundOrder.setChannelMercNo(param.getString("mno"));
        merchantRefundOrder.setCreateTime(merchantOrder.getUpdateTime());
        merchantRefundOrder.setMerchantCode(merchantChannelStatus.getMerchantCode());
        merchantRefundOrder.setOrderType("6");
        merchantRefundOrder.setPayTypeCode(merchantOrder.getPayTypeCode());
        merchantRefundOrder.setPayTypeName(merchantOrder.getPayTypeName());
        merchantRefundOrder.setPayAmt(new BigDecimal(param.getString("realRefundAmount")));
        merchantRefundOrder.setOrderNumber(merchantOrder.getOrderNumber());
        merchantRefundOrder.setRefundNo(refundOrderNumber);
        merchantRefundOrderService.save(merchantRefundOrder);
        // 退款去分润操作
        realFansService.removeProfit(merchantOrder.getOrderNumber());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized void posCallback(JSONObject param) {
        log.info("===========>随行付pos回调操作<============");
        String bizCode = param.getString("bizCode");
        MsgException.check(!SxfConfg.SXF_SUCCESS_CODE.equals(bizCode),param.getString("bizMsg"));

        String mno = param.getString("mno");
        MerchantChannelStatus channelStatus = merchantChannelStatusService.getByMerchantId(mno);
        MsgException.checkNull(channelStatus,"未知商编");
        MerchantBaseInfo merchant = mbiService.getMerchantBaseInfoByMerchantCode(channelStatus.getMerchantCode());
        MsgException.checkNull(merchant,"未知商户");

        MerchantStore store = merchantStoreService.getStoreByMerchantCode(channelStatus.getMerchantCode());
        MsgException.checkNull(store,"门店信息异常");

        String tranType = param.getString("tranType");
        //刷卡交易回调
        if(StringUtil.isNotEmpty(tranType)){
            posCardCallback(param,merchant,store);
        }else{
            posScanPay(param,merchant,store);
        }
    }

    /**
     * @description:POS扫码交易回调
     * {
     *     "payTime":"20211027161421",
     *     "bizCode":"0000",
     *     "creTm":"161420",
     *     "sign":"hRPtD6tzlnrqLSCDkxtlR0QqwxdEjYtd+7Lu9k4MEFggc8ARmrwS3SnAq+ly0Hav8PsRQtlhVJC1anCXv1E+OJ3a9xdSkA7StWN9MqWTshfKkTmjZDQk5+8lptDT727cthv3xEbMgM2VtyB8B8RrW35n10jY6NDcZS9OG7sHFGtjyc3TDuXdJMPjJ3JC48FMENmI/2deXFkiVO4LQ3PY8kn9py61fYJcYsMkgfbSZNuwyYk2081NhNKmKw+gpDmRXfFbducxOVqnB7ps7m2EE5tzTX0nZlT8SGt5RH1h09WEYuDDY9qG3qApbR0dLeoigZpnrXzX5qRddiSnBICgMA==",
     *     "amt":"0.01",
     *     "payWay":"01",
     *     "terminalId":"10747825",
     *     "buyerId":"2088502904759300",
     *     "batchId":"000001",
     *     "uuid":"77b5fb07ac96488ea78b7cbde8d13600",
     *     "orgId":"56964586",
     *     "tranTime":"20211027161420",
     *     "ordNo":"2021102710747825000001000054",
     *     "payType":"ALIPAY",
     *     "bizMsg":"交易成功",
     *     "posSeqNo":"000054",
     *     "tradeSource":"10",
     *     "finishTime":"20211027161421",
     *     "orgName":"武汉融商创银科技有限公司",
     *     "cardType":"1",
     *     "transactionId":"2021102722001459301413881452",
     *     "creDt":"20211027",
     *     "mno":"399200827349050",
     *     "timeStamp":"20211027161422",
     *     "buyerAccount":"135******00",
     *     "drType":"1",
     *     "businessType":"2"
     * }
     */
    private void posScanPay(JSONObject param, MerchantBaseInfo merchant, MerchantStore store) {
        String payTime = param.getString("payTime");
        String amt = param.getString("amt");
        String buyerId = param.getString("buyerId");
        String uuid = param.getString("uuid");
        String payType = param.getString("payType");
        String transactionId = param.getString("transactionId");
        String drType = param.getString("drType");

        String ordNo = param.getString("ordNo");
        MerchantOrder existData = new MerchantOrder();
        existData.setOrderNumber(ordNo);
        existData = merchantOrderService.queryMerchantOrder(existData);
        if (existData != null) {
            return;
        }
        operationOrder(merchant,store,payType,uuid,transactionId,drType,amt,payTime,ordNo,buyerId);
    }

    private void operationOrder(MerchantBaseInfo merchant,
                                      MerchantStore store,
                                      String payType, String uuid,
                                      String transactionId, String drType,
                                      String amt, String payTime,String ordNo,String buyerId) {
        MerchantOrder merchantOrder = new MerchantOrder();
        merchantOrder.setStaffCode(store.getStoreId());
        merchantOrder.setStaffName(store.getAlias());
        merchantOrder.setStatus("1");

        if (payType != null) {
            merchantOrder.setThirdTransNo(transactionId);
            switch (payType) {
                case "WECHAT":
                    merchantOrder.setPayTypeCode("sxfPay1");
                    merchantOrder.setPayTypeName("随行微信支付");
                    break;
                case "ALIPAY":
                    merchantOrder.setPayTypeCode("sxfPay0");
                    merchantOrder.setPayTypeName("随行支付宝支付");
                    break;
                case "UNIONPAY":
                    merchantOrder.setPayTypeCode("sxfPay2");
                    merchantOrder.setPayTypeName("随行云闪付支付");
                    break;
                default:
                    break;
            }
        }
        merchantOrder.setOrderNumber(ordNo);
        merchantOrder.setOrderType("4");
        merchantOrder.setMerchantCode(merchant.getMerchantCode());
        merchantOrder.setMerchantName(merchant.getAlias());
        merchantOrder.setStoreId(store.getStoreId());
        merchantOrder.setStoreName(merchant.getAlias());
        merchantOrder.setConsumeFee(Double.valueOf(amt));
        merchantOrder.setTransNo(uuid);
        //借贷标识
        merchantOrder.setDrType(drType);
        //插入通道费率 已经通道成本手续费
        merchantOrder.setChannelRate(SxfConstants.CHANNEL_WECHAT_ALIPAY_BANK_COST_RATE.multiply(new BigDecimal(10000)));
        BigDecimal channelFee = new BigDecimal(merchantOrder.getConsumeFee().toString()).multiply(SxfConstants.CHANNEL_WECHAT_ALIPAY_BANK_COST_RATE).setScale(2,BigDecimal.ROUND_HALF_UP);
        merchantOrder.setChannelFee(channelFee);
        try {
            Date date = DateUtils.parseDate(payTime, "yyyyMMddHHmmss");
            merchantOrder.setCreateDt(date);
            merchantOrder.setTransDt(date);
            merchantOrder.setUpdateTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        BigDecimal rate = merchantRateNewService.getMchRate(merchant.getMerchantCode(),merchantOrder.getPayTypeCode(), merchantOrder.getConsumeFee());
        merchantOrder.calcRateAndFee(rate);
        merchantOrder.setAisleSwitch("2");
        merchantOrder.setMercUserId(buyerId);
        boolean flag = merchantOrderService.save(merchantOrder);
        //收款成功 app推送
//        if(flag){
//            List<String> alias = new ArrayList<String>();
//            alias.add(merchant.getUserId());
//            String msgCountent = "收银呗到账" + merchantOrder.getConsumeFee().toString() + "元";
//            sendAppNotify(alias,"收银呗到账通知",msgCountent,"3");
//        }
        if("1".equals(store.getIsMarket())){
            merchantOrder.setMarketAmt(merchantOrder.getMercFee());
            merchantTransferService.saveTransferInfo(merchantOrder, merchantOrder.getMercFee());
        }
        try {
            //创建推广分润
            merchantProfitService.createOrderProfitV2(merchantOrder,"1");
            MerchantOrder update = new MerchantOrder();
            if(flag){
                update.setId(merchantOrder.getId());
                update.setProfitShareMoney(merchantOrder.getProfitShareMoney());
                merchantOrderService.updateById(update);
            }
        }catch (RuntimeException e){
            log.info("创建分润失败,异常信息:{}",e.getMessage());
        }
    }

    /**
     * 刷卡撤销交易
     * {
     *     "bizCode":"0000",
     *     "creTm":"153856",
     *     "trmNo":"10747825",
     *     "sign":"BFsL7oT7l9SMGpJcMSM4A71n5i4O1baVs4wDnI8meRnERj0sVi2IhwUDhGbkmAJLahy3vV3ES3mnmcQ5fNO63iVsCo3ML+7xPK+DBgXPlIXkva8K526vgHAaeK8tRfXGwxN3VV9ISxEM14Of800uPpKzhRGRhKsC97UPBFgI7aYkKfEINv4mBM2PN/IEZiXAML/xfCC8Ng/5SuCSGAteB4vuWtaER3UOof2I6rJiyxUxh+w5xpT+RJqiedVaBUMetsK9uPi6VTDJmuVox9fkSGrEfZp3p9YAJLEADA34yRJCweItkXJB6VGyl/ba8qSexeCmtKysjD76zpZo+TWsBg==",
     *     "isCloudPay":"01",
     *     "mcc":"7375",
     *     "uuid":"3b58e7d833014723a249404b3cd23158",
     *     "cardNo":"625156******6040",
     *     "orgId":"56964586",
     *     "tranType":"0002",
     *     "crdTyp":"01",
     *     "orgNm":"CUP_Z",
     *     "sesDate":"20211027",
     *     "szltFlag":"01",
     *     "bizMsg":"交易成功",
     *     "foreignCardFlg":"00",
     *     "posSeqNo":"000051",
     *     "specialOffer":"",
     *     "szltRecfeeAmt":"0.00",
     *     "sesBatNo":"00",
     *     "exrateMode":"",
     *     "tranSts":"S",
     *     "tranTm":"153855",
     *     "finishTime":"20211027153855",
     *     "authCode":"587675",
     *     "batNo":"000001",
     *     "mecFeeRate":"0",
     *     "consumerId":"",
     *     "inMod":"02",
     *     "cardType":"0",
     *     "paySource":"01",
     *     "payChannals":"",
     *     "tranSeqNo":"b2c77ee222c7460b9cc3907f84942cc5",
     *     "feeAmt":"0.01",
     *     "creDt":"20211027",
     *     "mno":"399200827349050",
     *     "inMno":"836521773750011",
     *     "tranAmt":"1",
     *     "ouuid":"3266c9f2cb354ceda4fd059c0d824787",
     *     "businessType":"0",
     *     "tranDt":"20211027",
     *     "searchNo":"211027878317"
     * }
     */
    private void posCardRevoke(JSONObject param, MerchantBaseInfo merchant,String preAuthStatus) {
        String tranSts = param.getString("tranSts");
        if("S".equals(tranSts)){
            String ouuid = param.getString("ouuid");
            MsgException.checkNull(ouuid,"原订单号为空，交易撤消失败");
            MerchantOrder order = new MerchantOrder().setTransNo(ouuid).setStatus("1");
            order = merchantOrderService.queryMerchantOrder(order);
            MsgException.checkNull(order,"未找到对应订单");

            Double tranAmt = param.getDouble("tranAmt");
            if(BigDecimal.valueOf(tranAmt).compareTo(BigDecimal.valueOf(order.getConsumeFee())) == 0){
                //全额退款
                order.setStatus("2");
            }else{
                order.setConsumeFee(tranAmt);
                order.setStatus("6");
            }
            order.setId(null);
            order.setUpdateTime(new Date());
            if(StringUtil.isNotEmpty(order.setPreAuthStatus(preAuthStatus))){
                order.setPreAuthStatus(preAuthStatus);
            }
            merchantOrderService.save(order);
            MerchantRefundOrder refundOrder = new MerchantRefundOrder();
            refundOrder.setMerchantCode(merchant.getMerchantCode());
            refundOrder.setAlias(merchant.getAlias());
            refundOrder.setOrderNumber(order.getOrderNumber());
            refundOrder.setRefundNo("SXFR"+StringUtil.getBillno());
            refundOrder.setChannelNo(ouuid);
            refundOrder.setPayTime(order.getTransDt());
            refundOrder.setRefundTime(new Date());
            refundOrder.setStatus("1");
            refundOrder.setOrderType(order.getOrderType());
            refundOrder.setPayTypeCode(order.getPayTypeCode());
            refundOrder.setPayTypeName(order.getPayTypeName());
            refundOrder.setPayAmt(BigDecimal.valueOf(order.getConsumeFee()));
            refundOrder.setAisleSwitch("2");
            refundOrder.setCreateTime(new Date());
            refundOrder.setFailMsg(param.getString("bizMsg"));
            merchantRefundOrderService.save(refundOrder);
            //TODO 暂时不加去除分润操作 刷卡费率未完善
        }

    }

    /**
     * 随行付pos刷卡交易
     * {
     *     "bizCode":"0000", 业务状态
     *     "creTm":"153705",
     *     "trmNo":"10747825", 终端编号
     *     "sign":"EMrrw0npknILFUOsEIAGoQ5wIgIWPxRAsh9dfKVMhXYFOqIP7TQ8dlLLhlvR8cOeIKXHHOvD1hhkXht5r8CJCw/+VtAslsaQGiDmtWt+XWEZSVW63NS2V88ECfvwQTp9i6x8sFnXDKb7tK2R1Yc+TnBNgyZ4oNC7vAvwxWD5t1L7TrltdgITVyLGaVHnTKviIO3cjSE60ECyhaqUd07goBFSNz1b2y9iTJTjPMTk3CJCPQQeo5/9tAHim4Tu+bwyP5jcHk/SVH/DM4xM1dz8/LpaK1X+nJRqKICRDWs4JjpP2FeRxthziqR1kBpXe4CVzNt3TPL5y5ItXmppis16Aw==",
     *     "isCloudPay":"01",
     *     "mcc":"7375",
     *     "uuid":"527466ae56f1410aa0c2c5744012b74d", 随行付订单号
     *     "cardNo":"625156******6040", 交易卡号 加密
     *     "orgId":"56964586", 机构号
     *     "tranType":"0001",交易类型，枚举值
     *     "crdTyp":"01", 借贷标识
     *     "orgNm":"CUP_Z", 不知道啥参数
     *     "sesDate":"20211027", 不知道啥参数
     *     "szltFlag":"01", 不知道啥参数
     *     "bizMsg":"交易成功",
     *     "foreignCardFlg":"00", //不知道啥参数
     *     "posSeqNo":"000050", //小票流水号
     *     "specialOffer":"", // 优惠费率标识，枚举值 1 云闪付 说明：手机PAY的支付 1000以下的优惠费率 返回1 云闪付
     *     "szltRecfeeAmt":"0.00", //不知道啥参数
     *     "sesBatNo":"00", //不知道啥参数
     *     "exrateMode":"",
     *     "tranSts":"S", //交易状态，枚举值 S 成功 F 失败 Q 未支付
     *     "tranTm":"153703", 交易时间 HHmmss
     *     "finishTime":"20211027153703", //交易完成时间 大概是 文档没有
     *     "authCode":"587675", //授权code 不知道有啥用
     *     "batNo":"000001", 批次号
     *     "mecFeeRate":"0.6", //费率 0.6%
     *     "consumerId":"", 消费者id
     *     "inMod":"02",
     *     "cardType":"0", //卡类型 应该是 不知道参数是啥意思
     *     "paySource":"01", // 交易来源，枚举值 01 POS 06 外部接入
     *     "payChannals":"",//支付渠道
     *     "tranSeqNo":"3266c9f2cb354ceda4fd059c0d824787", 交易流水号，长度32位
     *     "feeAmt":"0.01", //手续费
     *     "creDt":"20211027", //
     *     "mno":"399200827349050", //商户编号
     *     "inMno":"836521773750011",//不知道是啥参数
     *     "tranAmt":"1", //交易金额
     *     "ouuid":"", //员交易流水号，撤销交易时候用的 应该是 待测试
     *     "businessType":"0",
     *     "tranDt":"20211027",//交易日期
     *     "searchNo":"211027875904" //检索参考号
     * }
     */
    private void posCardCallback(JSONObject param, MerchantBaseInfo merchant, MerchantStore store) {

        String tranType = param.getString("tranType");
        switch (tranType){
            case "0001":
                posCardPay(param,merchant,store,null);
                break;
            case "0003":
                posCardPay(param,merchant,store,"1");
                break;
            case "0005":
                posCardPay(param,merchant,store,"3");
                break;
            case "0002":
                posCardRevoke(param,merchant,null);
                break;
            case "0004":
                posCardRevoke(param,merchant,"2");
                break;
            case "0006":
                posCardRevoke(param,merchant,"4");
                break;
            //冲正
            case "0007":
                posCardRevoke(param,merchant,"5");
                break;
            //退货
            case "0008":
                posCardRevoke(param,merchant,"6");
                break;
            //现金消费
            case "0027":
                log.info("=========>POS机现金没接入==========");
                break;
        }
    }

    /** pos 预授权
     *
     * {
     *     "bizCode":"0000",
     *     "creTm":"161222",
     *     "trmNo":"10748949",
     *     "sign":"StfLz1HyeKP+HMMhehkKYOxcPrm4mg0YtpSO+iWaYm/cet42pTFHQdx2mB8OGt84ESBKbxgif5cvvGCzwPogbChAMzSHBCPHECGAdmOVzWAMvZt875TR9Sl1LQBiPCuH+S3pch3X4wFY/kdfu0ZjyWHFQ+Kmc/93Qp50gSGhZ11MD4WY19PCjb/dhsWKiKC4psiHLbvvQM0DLSwMXsfnt2IGPUVHjwEPBEQNq1ED1DmKwuEbYArrHo27p0CnpiNXRDzYzQIDumUgkM+E8dKWlZQIXKcIuT354GQKPDqStPqrwD/vaMWwPYFAho+M/UMFXPaD+LtclY89i+rl6tZkbg==",
     *     "isCloudPay":"01",
     *     "mcc":"7011",
     *     "uuid":"4d5d66a986a94259a678b0e6c289b30a",
     *     "cardNo":"625156******6040",
     *     "orgId":"56964586",
     *     "tranType":"0003",
     *     "crdTyp":"01",
     *     "orgNm":"CUP_Z",
     *     "sesDate":"20211028",
     *     "szltFlag":"01",
     *     "bizMsg":"交易成功",
     *     "foreignCardFlg":"00",
     *     "posSeqNo":"000084",
     *     "specialOffer":"",
     *     "szltRecfeeAmt":"0.00",
     *     "sesBatNo":"00",
     *     "exrateMode":"",
     *     "tranSts":"S",
     *     "tranTm":"161221",
     *     "finishTime":"20211028161221",
     *     "authCode":"637019",
     *     "batNo":"000001",
     *     "mecFeeRate":"0",
     *     "consumerId":"",
     *     "inMod":"02",
     *     "cardType":"0",
     *     "paySource":"01",
     *     "payChannals":"",
     *     "tranSeqNo":"476d9fbafb984712bd28ee7f4cc69d06",
     *     "feeAmt":"0",
     *     "creDt":"20211028",
     *     "mno":"399211027879843",
     *     "inMno":"836701770110639",
     *     "tranAmt":"0.1",
     *     "ouuid":"",
     *     "businessType":"0",
     *     "tranDt":"20211028",
     *     "searchNo":"211028957213"
     * }
     *
     *
     * **/

    /**
     * @description:刷卡支付回调
     *
     */
    private void posCardPay(JSONObject param, MerchantBaseInfo merchant, MerchantStore store,String preAuthStatus) {
        String tranSeqNo = param.getString("tranSeqNo");
        if("3".equals(preAuthStatus)){
            String ouuid = param.getString("ouuid");
            if(StringUtil.isNotEmpty(ouuid)){
                MerchantOrder existData = new MerchantOrder();
                existData.setTransNo(ouuid).setStatus("1");
                existData = merchantOrderService.queryMerchantOrder(existData);
                if(existData == null){
                    MsgException.throwException("预授权原订单号：{"+ouuid+"}查询异常");
                }
                Double tranAmt = param.getDouble("tranAmt");
                Double feeAmt = param.getDouble("feeAmt");
                existData.setEnterFee(StringUtil.bigDecimal(tranAmt-feeAmt));
                if(StringUtil.isNotEmpty(param.getBigDecimal("mecFeeRate"))){
                    BigDecimal rate = param.getBigDecimal("mecFeeRate").multiply(BigDecimal.valueOf(100));
                    existData.setRate(rate);
                }
                existData.setTransNo(tranSeqNo);
                existData.setPreAuthStatus(preAuthStatus);
                existData.setMercFee(BigDecimal.valueOf(feeAmt));
                existData.setConsumeFee(tranAmt);
                merchantOrderService.updateById(existData);
            }
        }else{
            String orderNumber = "SXF_POS_"+StringUtil.getBillno();
            MerchantOrder order = new MerchantOrder();
            order.setOrderNumber(orderNumber);
            order.setOrderType("4");//Pos
            order.setMerchantCode(merchant.getMerchantCode());
            order.setMerchantName(merchant.getAlias());
            order.setPayTypeCode(Constant.PAY_TYPE_YSFPAY);
            order.setPayTypeName(Constant.PAY_TYPE_NAME_YSFPAY);
            order.setStoreId(store.getStoreId());
            order.setStoreName(store.getStoreName());
            order.setConsumeFee(param.getDouble("tranAmt"));
            order.setTransNo(tranSeqNo);
            Date date = new Date();
            order.setCreateDt(date);
            order.setTransDt(date);
            String tranSts = param.getString("tranSts");
            switch (tranSts){
                case "S":
                    order.setStatus("1");
                    break;
                case "F":
                    order.setStatus("0");
                    break;
                default:
                    order.setStatus("5");
                    break;
            }
            Double tranAmt = param.getDouble("tranAmt");
            Double feeAmt = param.getDouble("feeAmt");
            order.setEnterFee(StringUtil.bigDecimal(tranAmt-feeAmt));
            order.setAisleSwitch("2");
            BigDecimal rate = param.getBigDecimal("mecFeeRate").multiply(BigDecimal.valueOf(100));
            order.setRate(rate);
            order.setSettlementType(1);
            String cardType = param.getString("cardType");
            //贷记卡
            BigDecimal channelRate = BigDecimal.ZERO;
            BigDecimal channelFee = BigDecimal.ZERO;
            if("0".equals(cardType)){
                order.setDrType("2");
                channelRate = SxfConstants.CREDIT_CARD_BANK_RATE_LARGE;
                channelFee = BigDecimal.valueOf(tranAmt).multiply(channelRate).setScale(2,BigDecimal.ROUND_HALF_UP);

            }else {
                order.setDrType("1");
                channelRate = SxfConstants.DEBIT_CARD_BANK_RATE_LARGE;
                channelFee = BigDecimal.valueOf(tranAmt).multiply(channelRate).setScale(2,BigDecimal.ROUND_HALF_UP);
                if(channelFee.compareTo(SxfConstants.DEBIT_CARD_BANK_RATE_LARGE_MAX_FEE) >= 0){
                    channelFee = SxfConstants.DEBIT_CARD_BANK_RATE_LARGE_MAX_FEE;
                }
            }
            order.setChannelFee(channelFee);
            order.setChannelRate(channelRate.multiply(new BigDecimal(10000)));
            order.setMercFee(BigDecimal.valueOf(feeAmt));
            if(StringUtil.isNotEmpty(preAuthStatus)){
                order.setPreAuthStatus(preAuthStatus);
            }
            boolean flag = merchantOrderService.save(order);
            //pos机收款成功 app推送
            if(flag && "1".equals(order.getStatus())){
                List<String> alias = new ArrayList<String>();
                alias.add(merchant.getUserId());
                String msgCountent = "收银呗到账" + order.getConsumeFee().toString() + "元";
                sendAppNotify(alias,"收银呗到账通知",msgCountent,"3");
            }
        }
    }
}
