
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Cosmos.BaseFrame;
using Cosmos.UserFrame;
using Cosmos.ServiceProvider;
using Cosmos.Common;
using Cosmos.CommonManager;
using System.Threading;
using SPC.Kiosk.Popup.Model;
using SPC.Kiosk.Common;
using System.Collections;

namespace SPC.Kiosk.Payments
{
    /// <summary>
    /// 통신사 할인 승인
    /// </summary>
    public class posLastPayments : IDisposable
    {

        //UserLog.WriteLogFile(UserCom.LOG_ERROR, "SPC.Kiosk.Payments", "posLastPayments.?", "Exception." + ex.Message);
        #region [ Members ]
        public enum ErrorCode
        {
            LastPaymentsCardNumberError,
            LastPaymentsEncrtipError,
            LastPaymentsNotInitailzedError,
            LastPaymentsProcessingTimeOut,
            LastPaymentsUnknownError,
            LastPaymentsCardReadingError
        }
        /// <summary>
        /// ErrorMessage Event
        /// </summary>
        /// <param name="LogString">반환 로그</param>
        public delegate void ErrorMessageEventHandler(string ErrorString);
        /// <summary>
        ///  로그메세지 이벤트 반환용 
        /// </summary>
        public event ErrorMessageEventHandler ErrorMessageEvent;
        /// <summary>
        /// Error 반환 Event
        /// </summary>
        /// <param name="errorCode">반환 Error Code</param>
        public delegate void LogErrorHandler(ErrorCode errorCode);
        /// <summary>
        ///  Error Code 이벤트 반환용 
        /// </summary>
        public event LogErrorHandler ErrorEvent;
        /// <summary>
        /// IcReadStart Event
        /// </summary>
        /// <param name="sender"></param>
        public delegate void IcReadStart(object sender);
        /// <summary>
        /// IcReadStart Event 반환용 
        /// </summary>
        public event IcReadStart ReadStart;
        /// <summary>
        /// IcReadStart Event
        /// </summary>
        /// <param name="sender"></param>
        public delegate void IcReadEnd(object sender);
        /// <summary>
        /// IcReadStart Event 반환용 
        /// </summary>
        public event IcReadEnd ReadEnd;
        /// <summary>
        /// NeedSign Event
        /// </summary>
        /// <param name="sender"></param>
        public delegate void NeedSignStart(object sender);
        /// <summary>
        /// NeedSign Event 반환용 
        /// </summary>
        public event NeedSignStart SignStartEvent;
        /// <summary>
        /// NeedSignEnd Event
        /// </summary>
        /// <param name="sender"></param>
        public delegate void NeedSignEnd(object sender);
        /// <summary>
        /// NeedSignEnd Event 반환용 
        /// </summary>
        public event NeedSignEnd SignEndEvent;

        private SManager sManager = null;                                // 이 객체를 통해 업무 Service 호출
        private StateServer StateObject = null;                          // StateObject : StateServer Object (객체)
        private PosStatus m_cPosStatus = null;                           // 기본정보 참조
        private TranStatus m_cTrnStatus = null;                          // 거래정보 참조        
        private DeviceStatus m_cDevStatus = null;                        // 디바이스 관리
        private PosOLEDevice.CallbackIc delegateReaderCardInfo;                     // IC리더 콜백(CardInfo)
        private IDataProcessUs m_cDataService = null;
        private IICReaderUs m_cDeviceICReader = null;

        private IPaymentUs m_cSmilePay = null;
        private IPaymentExpUs m_cHappyPoint = null;                                 // 해피포인트 적립

        private ICampaignUs m_cCampaingMain = null;                                 // 캠페인 관리

        private string m_sPosMenuKey = string.Empty;
        private string m_sFallDiv;                                                  //FallBack구분
        private string m_sIcChip;                                                   //IC CHIP DATA(EMV)
        private string m_sSign;                                                     //사인 데이터
        private string m_sTax;                                                      //세금
        private double m_dCreditCardDcAtm = 0d;                                          //카드할인금액
        private string m_sCreditCardDcTy=string.Empty;                                           //카드할인타입

        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 start,phj
        private string m_sMobileCode = "";
        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 end,phj
        /// <summary>
        /// 입력구분
        /// </summary>
        private string m_InputType = string.Empty;
        /// <summary>
        /// 입력데이터
        /// </summary>
        private string m_sInPutData = string.Empty;
        /// <summary>
        /// 마스킹데이터
        /// </summary>
        private string m_sInMaskData = string.Empty;
        /// <summary>
        /// 카드데이터(암호화)
        /// </summary>
        private string m_sCardNo = string.Empty;
        /// <summary>
        /// 서비스코드
        /// </summary>
        private string m_sService = string.Empty;
        /// <summary>
        /// 처리 성공 여부
        /// </summary>
        private bool m_bProcessSuccess = false;
        /// <summary>
        /// POS 초기화 필요 유무
        /// </summary>
        public bool NeedInitModule { get; set; } 
        /// <summary>
        /// 승인 수단 
        /// </summary>
        public string CertifyKey { get; set; } = string.Empty;
        public LastPaymentsType PaymentsType { get; set; }

        public double Payment { get; set; } = 0d;
        private bool ReadProcessEnd { get; set; } = false;

        private bool icCallBack = false;


        /// <summary>
        /// Ic Reader CallBack  Switch
        /// </summary>
        public bool IcCallBack
        {
            get { return icCallBack; }
            set
            {
                if (value)
                {
                    //m_cDeviceICReader.RegIcCallback(delegateReader);

                    try
                    {
                        string sApprID = PosMstManager.GetMstVan(ItemConst.TR_ITEM_ID.CREDITCARD_ITEM, ItemConst.TR_ITEM_ID.CREDITCARD.CREDIT_CARD, PosMst.MST_VAN.DATA.APPR_ID);
                        bool icR = m_cDeviceICReader.RegIcCallbackCardInfo(sApprID, m_cDataService.IntParse(Payment.ToString()), delegateReaderCardInfo);
                        icCallBack = value;
                        CommonLog.DebugLogWrite(this,"IcCallBack","RegIcCallbackCardInfo Success !!");
                    }
                    catch (Exception ex)
                    {
                        CommonLog.ErrorLogWrite(this,"IcCallBack","RegIcCallbackCardInfo Fail !!", string.Format("{0}\n{1}",ex.Message,ex.StackTrace));
                    }
                }
            }
        }
        public double PaymentsValue { get; protected set; } = 0d;
        /// <summary>
        /// Point 사용시 비번 필요 유무
        /// </summary>
        public bool NeedPassword { get; protected set; }
        public long PaySEQ { get; protected set; }
        /// <summary>
        /// 인증 처리 성공 유무
        /// </summary>
        public bool ProcessOK
        {
            get { return m_bProcessSuccess; }
        }
        public bool IsTimeout
        {
            set
            {
                if (value)
                {
                    ErrorEvent(ErrorCode.LastPaymentsProcessingTimeOut);
                }
            }
        }
        public bool SignEndStatus { get; set; }
        public string SignData
        {
            get { return m_sSign; }
            set { m_sSign = value; }
        }
        public double NoSignLimitAmount { get; set; } = 0d;

        public string ReadBarcordNumber { get; set; } = string.Empty;

        public bool SelfCashBill { get; protected set; } = false;
        #endregion

        #region [ Ctor  && Dispose ]
        /// <summary>
        /// Ctor
        /// </summary>
        public posLastPayments()
        {
            try
            {
                sManager = new SManager();
                StateObject = (StateServer)StateServer.GetInstance();
                NeedInitModule = StateObject.POS == null
                               || StateObject.TRAN == null
                               || StateObject.DEVICE == null;
                if (!NeedInitModule)
                {
                    m_cPosStatus = (PosStatus)StateObject.POS;      // POS 기본정보
                    m_cTrnStatus = (TranStatus)StateObject.TRAN;    // POS 거래정보 
                    m_cDevStatus = (DeviceStatus)StateObject.DEVICE;
                    m_cDeviceICReader = (IICReaderUs)sManager.InitServiceInstance(ServiceLists.AGENT_OLEDEVICE.DLL, ServiceLists.AGENT_OLEDEVICE.DEVICE_ICREADER);
                    delegateReaderCardInfo = new PosOLEDevice.CallbackIc(OnIcReaderCallBackCardInfo);     // IC리더 콜백(CardInfo)
                    m_cDataService = (IDataProcessUs)sManager.InitServiceInstance(ServiceLists.ASV_DATA_PROCESS.DLL, ServiceLists.ASV_DATA_PROCESS.DATA_SERVICE);
                    
                    m_cCampaingMain = (ICampaignUs)sManager.InitServiceInstance(ServiceLists.ASV_CAMPAIGN.DLL, ServiceLists.ASV_CAMPAIGN.CAMPAIGN_MAIN);
                    m_cSmilePay = (IPaymentUs)sManager.InitServiceInstance(ServiceLists.BSV_PAYMENT.DLL, ServiceLists.BSV_PAYMENT.SMAILPAY);
                    m_cHappyPoint = (IPaymentExpUs)sManager.InitServiceInstance(ServiceLists.BSV_PAYMENT.DLL, ServiceLists.BSV_PAYMENT.POINTHAPPYPOINT);
                }

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "Ctor" ,"Fail", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {

            try
            {
                ReadProcessEnd = true;
                if (IcCallBack ) 
                {
                    //m_cDeviceICReader.UnRegIcCallback();
                    m_cDeviceICReader.UnRegIcCallbackCardInfo();
                    IcCallBack = false;
                }
                InDataToZeroFill();

                sManager = null;
                StateObject = null;
                m_cPosStatus = null;      // POS 기본정보
                m_cTrnStatus = null;    // POS 거래정보 
                m_cDevStatus = null;

                m_cDeviceICReader = null;
                delegateReaderCardInfo = null;
                m_cDataService = null;
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this,"Dispose", "Fail", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        #endregion

        #region [ Methods ]
        public void StartCashBill(string _inputString, string _divType, double _cashAmount, double _taxAmount)
        {
            CommonLog.InfoLogWrite(this, "StartCashBill()", "Start");

            try
            {
                m_bProcessSuccess = false;
                SendReadStart();
                //사업자인 경우 길10자리가 아니면 자진 발급을 위해 입력번호 삭제
                if (_divType.Equals("1") && !_inputString.Length.Equals(10)) _inputString = string.Empty;
                //개인(소극공제) 인 경우 6자리 이하면 자진 발급처리
                if (_divType.Equals("0") && _inputString.Length < 6) _inputString = string.Empty;
                if (string.IsNullOrEmpty(_inputString))
                {
                    SelfCashBill = true;
                    _divType = "0"; //자진 발급은 개인(소득공제용만)
                    _inputString = CommonValue.CashReceiptDefaultNo;
                }
                m_sInPutData = EncryptedCashInputNo(_inputString, _divType);
                if (string.IsNullOrEmpty(m_sInPutData))
                {
                    SelfCashBill = true;
                    _divType = "0"; //자진 발급은 개인(소득공제용만)
                    _inputString = CommonValue.CashReceiptDefaultNo;
                    m_sInPutData = EncryptedCashInputNo(_inputString, _divType);
                }
                if (!string.IsNullOrEmpty(m_sInPutData))
                {
                    int retry = 0;
                    do
                    {
                        CompleteTxtCashBilll(_inputString, _divType, _cashAmount, _taxAmount);
                        retry++;
                        if (!SelfCashBill)
                        {
                            if (retry.Equals(1))
                            {
                                //승인 실패시 자진 발급 재승인
                                SelfCashBill = true;
                                _divType = "0"; //자진 발급은 개인(소득공제용만)
                                _inputString = CommonValue.CashReceiptDefaultNo;
                                m_sInPutData = EncryptedCashInputNo(_inputString, _divType);
                                if (string.IsNullOrEmpty(m_sInPutData)) break;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }


                    } while (!m_bProcessSuccess && retry < 2);//1회만 재승인
                }
                SendReadEnd();
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "StartCashBill()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            CommonLog.InfoLogWrite(this, "StartCashBill()", string.Format("End : Result={0}", ProcessOK ? "OK" : "Fail"));
        }

        private void CompleteTxtCashBilll(string inputString, string divType, double cashAmount, double taxAmount)
        {
            CommonLog.DebugLogWrite(this, "StartCashBill()", "Start");
            var m_cCashBill = (IPaymentUs)sManager.InitServiceInstance(ServiceLists.BSV_PAYMENT.DLL, ServiceLists.BSV_PAYMENT.CASHBILL);
            try
            {
                double dNetAmt = CmUtil.DoubleSubtraction(cashAmount, taxAmount);
                string sIssueType = "0";
                var sRet = m_cCashBill.SetPayment(new string[] { PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_KEYIN, m_sInPutData, dNetAmt.ToString(), taxAmount.ToString(), "0", cashAmount.ToString(), divType, sIssueType, "", "", "", "", "", "", m_sInMaskData, SelfCashBill ? "1" : "0" });
                if (sRet != UserCom.RST_OK)
                {
                    InDataToZeroFill();
                    m_bProcessSuccess = false;
                    if (sRet == null || sRet.Equals(UserCom.RST_ERR))
                    {
                        SendErrLogEvent(ErrorCode.LastPaymentsUnknownError);
                    }
                    else
                    {
                        SendErrorMessageEvent(sRet);
                    }
                }
                else
                {
                    m_bProcessSuccess = true;
                }
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "CompleteTxtCashBilll()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            finally
            {
                m_cCashBill = null;
            }
            CommonLog.DebugLogWrite(this, "StartCashBill()", "End");
        }
        private string EncryptedCashInputNo(string sIndata,string divType)
        {
            string tmpEnc = "";

            try
            {

                if (sIndata.Length == 18 && sIndata.StartsWith("15442020") == true)
                {
                    sIndata = sIndata + "=";
                }

                //#20171024 START, PHJ
                //DeviceICReader.cs로 결제코드,상세코드를 넘기기 위해서.
                //해피포인트로 현금영수증 승인하는지 구분하기 위해서.

                m_cDeviceICReader.PAY_WAY_CD = ItemConst.TR_ITEM_ID.ETC_INFO_ITEM;
                m_cDeviceICReader.PAY_DTL_CD = ItemConst.TR_ITEM_ID.ETC_INFO.CASHBILL;
                //#20171024 END, PHJ

                //카드번호 처리 부분 임시 주석 2016-06-15
                //#20170913 현금영수증, 포인트카드 마스킹 미적용 start
                // "0"인 경우 마스킹 미처리
                //기존
                //tmpEnc = m_cDeviceICReader.GetEncryptedCardNo(sIndata).Trim();
                //변경
                tmpEnc = m_cDeviceICReader.GetEncryptedCardNo(sIndata, "0").Trim();
                //#20170913 현금영수증, 포인트카드 마스킹 미적용 end

                if (CmUtil.MidH(tmpEnc, 0, 2) == "00")
                {
                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 start
                    //기존
                    /*
                    // Mod, 2017.09.05, 전화번호 마스킹 변경 처리 
                    //m_sMaskingCardNo = CmUtil.MidH(tmpEnc, 514, 37).Trim();
                    if (sIndata.Length == 10 || sIndata.Length == 11)
                    {
                        m_sMaskingCardNo = CmUtil.LeftH(sIndata, sIndata.Length - 4) + new string('*', 4);
                    }
                    else
                    {
                        m_sMaskingCardNo = CmUtil.MidH(tmpEnc, 514, 37).Trim();
                    }
                    */
                    //변경
                    m_sInMaskData = CmUtil.MidH(tmpEnc, 514, 37).Trim();
                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 end

                    m_sInPutData = m_sInMaskData;

                    //#20180426 현금영수증 마스킹 변경 및 영수증 문구 변경 start
                    //기존
                    /*
                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 start
                    
                    if (sIndata.Length == 10 || sIndata.Length == 11)
                    {
                        //#20171121 전화번호 길이와 마스킹 된 값의 길이와 다름. start, phj
                        //기존
                        //m_sMaskingCardNo = CmUtil.LeftH(m_sMaskingCardNo, m_sMaskingCardNo.Length - 4) + new string('*', 4);

                        //변경
                        m_sMaskingCardNo = CmUtil.LeftH(sIndata, 6) + new string('*', sIndata.Length - 6);
                        //#20171121 전화번호 길이와 마스킹 된 값의 길이와 다름. end, phj
                    }
                    else
                    {
                        m_sMaskingCardNo = CmUtil.MidH(m_sMaskingCardNo, 0, 6) + "********";
                    }
                    
                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 end
                    */
                    //#20180426 현금영수증 마스킹 변경 및 영수증 문구 변경 end

                    //#20171024 지출증빙으로 발행시 입력한 자리수까지만 영수증상에 표시 되도록 수정 start
                    //10자리 입력시 spcnpos.dll로 암호화 처리시 6자리+'******' 로 변환이 되어 11자리 입력 한 것으로 보임
                    if (divType == "1")
                    {
                        m_sInMaskData = CmUtil.MidH(m_sInMaskData, 0, sIndata.Length);
                    }
                    //#20171024 지출증빙으로 발행시 입력한 자리수까지만 영수증상에 표시 되도록 수정 end

                    tmpEnc = CmUtil.MidH(tmpEnc, 2, 512).Trim();
                }
                else
                {
                    tmpEnc = "";


                    //암호화 처리 실패!
                    CommonLog.ErrorLogWrite(this, "EncryptedCashInputNo()", "Fail !!");
                }
            }
            catch (Exception ex)
            {
                tmpEnc = "";
                CommonLog.ErrorLogWrite(this, "EncryptedCashInputNo()", "Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }

            return tmpEnc;

        }
        /// <summary>
        /// 최종 결제 처리
        /// </summary>
        /// <param name="_inputString"></param>
        public void StartCertifyProcessing(LastPaymentsType _paymentsType, string _inputString, double _payments)
        {
            try
            {
                CommonLog.InfoLogWrite(this,"StartCertifyProcessing()","Start");
                m_bProcessSuccess = false;
                ReadBarcordNumber = string.Empty;
                if (NeedInitModule)
                {
                    SendReadStart();
                    Thread.Sleep(1000); //진행창 보이기 위한 딜레이
                    ErrorEvent(ErrorCode.LastPaymentsNotInitailzedError);
                }
                else
                {
                    PaymentsType = _paymentsType;
                    Payment = _payments;
                    m_cTrnStatus.Head.TradeDiv = ItemConst.TRAN_DIV.NORMAL;
                    switch(PaymentsType)
                    {
                        case LastPaymentsType.IcCard:
                        case LastPaymentsType.SsLgPay:
                            ReadProcessEnd = false;
                            IcCallBack = true;
                            while (!ReadProcessEnd) ;


                            


                            if (!string.IsNullOrEmpty(m_sInPutData))
                            {



                                CompleteTxtInPut();
                            }
                            else
                            {
                                SendErrLogEvent(ErrorCode.LastPaymentsCardReadingError);
                            }
                            break;
                        case LastPaymentsType.HappyGift:
                            ReadProcessEnd = false;
                            IcCallBack = true;
                            while (!ReadProcessEnd && string.IsNullOrEmpty(ReadBarcordNumber)) ;
                            if (!ReadProcessEnd)
                            {
                                if (IcCallBack)
                                {
                                    m_cDeviceICReader.UnRegIcCallbackCardInfo();
                                    IcCallBack = false;
                                }
                                ReadProcessEnd = true;
                            }
                            else
                            {
                                ReadBarcordNumber = string.Empty;
                            }
                            if (!string.IsNullOrEmpty(ReadBarcordNumber))
                            {
                                m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_SWIP;
                                m_sInMaskData = _inputString;
                                m_sInPutData = _inputString + "=";
                                if (EncryptedCardNo(m_sInPutData, ref m_sInMaskData, ref m_sCardNo))
                                {
                                    CompleteTxtInPut();
                                }
                                else
                                {
                                    SendErrLogEvent(ErrorCode.LastPaymentsEncrtipError);
                                }
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(m_sInPutData))
                                {
                                    CompleteTxtInPut();
                                }
                                else
                                {
                                    SendErrLogEvent(ErrorCode.LastPaymentsCardReadingError);
                                }
                            }
                            break;
                        case LastPaymentsType.CashBee:
                        case LastPaymentsType.Tmoney:
                        case LastPaymentsType.SpcEmployee:
                            SendReadStart();
                            SendErrLogEvent(ErrorCode.LastPaymentsUnknownError);
                            break;
                        case LastPaymentsType.SmilePay:
                        case LastPaymentsType.AliPay:
                        case LastPaymentsType.ZeroPay:
                            //SendReadStart();
                            if (_inputString.Replace("=", "").Replace("@", "").Length.Equals(16))
                            {
                                m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_SWIP;
                                m_sInMaskData = _inputString;
                                m_sInPutData = _inputString + "=";
                                if (EncryptedCardNo(m_sInPutData, ref m_sInMaskData, ref m_sCardNo))
                                {
                                    CompleteTxtInPut();
                                }
                                else
                                {
                                    SendErrLogEvent(ErrorCode.LastPaymentsEncrtipError);
                                }
                            }
                            else
                            {
                                SendErrLogEvent(ErrorCode.LastPaymentsCardNumberError);
                            }
                            break;
                    }
                }
                CommonLog.DebugLogWrite(this,"StartCertifyProcessing()","m_cDeviceICReader.Init_ICReader Before");
                m_cDeviceICReader.Init_ICReader(" ");
                CommonLog.DebugLogWrite(this, "StartCertifyProcessing()", "m_cDeviceICReader.Init_ICReader After");
                SendReadEnd();
                CommonLog.InfoLogWrite(this, "StartCertifyProcessing()", string.Format("End : Result={0}", ProcessOK ? "OK" : "Fail"));
                
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "StartCertifyProcessing()","Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
        }
        /// <summary>
        /// 휴대폰 번호 형식 확인
        /// </summary>
        /// <param name="sInputData"></param>
        /// <returns></returns>
        private bool IsCellularPhoneNumber(string sInputData)
        {
            bool bRet = false;
            try
            {
                if (sInputData.Length == 10 || sInputData.Length == 11)
                {
                    if (sInputData.StartsWith("010") == true || sInputData.StartsWith("011") == true || sInputData.StartsWith("017") == true ||
                       sInputData.StartsWith("016") == true || sInputData.StartsWith("018") == true || sInputData.StartsWith("019") == true)
                    {
                        bRet = true;
                    }
                }
            }
            catch 
            {
                bRet = false;
            }
            return bRet;
        }
        /// <summary>
        /// 승인 전문 처리
        /// </summary>
        private void CompleteTxtInPut()
        {
            CommonLog.DebugLogWrite(this, "CompleteTxtInPut()", "Start");
            string sRet = UserCom.RST_ERR;
            object m_cPayments = null;
            object m_cPaymentsGift = null;
            try
            {
                m_bProcessSuccess = false;
                switch (PaymentsType)
                {
                    case LastPaymentsType.IcCard:
                    case LastPaymentsType.SsLgPay:
                        //0:마스킹 카드번호 1:입력구분 2:카드번호 3:할부개월 4:총금액 5:봉사료
                        //6:세금 7:비밀번호 8:신용카드종류 9:칩데이터 10:사인
                        //11:Fallback구분 12:제휴할인금액(캠페인) 13:원승인번호 14:원승인일자 15:아이템코드
                        //16:매입사코드 17:매입사명 18:할인카드구분 19:할인금액 
                        //20:승인구분 21:매체구분 22:서비스코드

                        // 캠페인 처리 => 키값(취소시사용),카드번호,캠페인대상,지불구분,지불금액
                        ArrayList alPayItem = (ArrayList)StateObject.GetItemObject(Column.TR_PAYMENT.ITEM);
                        double nDisAmt = m_cCampaingMain.ExecuteCampaignPayment(alPayItem.Count.ToString(), m_sCardNo + "0", ItemConst.CPI_CUST_PAY_TYPE.CREDTCARD, Payment);
                        var lastPayment = CmUtil.DoubleSubtraction(Payment, nDisAmt);

                        m_sSign = string.Empty;
                        if (NoSignLimitAmount > 0 && lastPayment > NoSignLimitAmount)
                        {
                            SignEndStatus = false;
                            SignStart();
                            while (!SignEndStatus) ;
                            SignEnd();

                        }
                        m_sTax = m_cDataService.GetPaymentAmtVAT(lastPayment).ToString();
                        m_cPayments = sManager.InitServiceInstance(ServiceLists.BSV_PAYMENT.DLL, ServiceLists.BSV_PAYMENT.CREDITCARD);
                        m_cPaymentsGift = sManager.InitServiceInstance(ServiceLists.BSV_PAYMENT.DLL, ServiceLists.BSV_PAYMENT.HPGIFTCARD);


                        if (m_cPayments is IPaymentUs paymentUs)
                        {

                            // 해피기프트카드 체크 2019.04.25
                            //string[] aRet = new string[4];
                            //string m_sCardDiv = "";
                            //sRet = paymentUs.SearchPayment(new string[] { PosConst.CREDITCARD_SEARCH_TYPE.PREFIX, CmUtil.MidH(m_sInMaskData, 0, 6).ToString() }, ref aRet);
                            //if (sRet == UserCom.RST_OK)
                            //{
                            //    m_sCardDiv = aRet[0].Trim();
                            //}
                            //else
                            //{
                            //    InDataToZeroFill();
                            //    m_bProcessSuccess = false;
                            //    if (!sRet.Equals(UserCom.RST_ERR)) SendErrorMessageEvent(sRet);
                            //}
                            ////해피기프트카드 체크 끝
                            //sRet = UserCom.RST_ERR;

                            //if (aRet[0].Trim() == "C" )//&& aRet[2] == "98")
                            //{
                            //    // 해피기프트(신)
                            //    if (m_cPaymentsGift is IPaymentUs paymentUsGift)
                            //    {
                            //        sRet = paymentUsGift.SetPayment(new string[] {
                            //    /*0*/m_sInMaskData, /*1*/m_InputType, /*2*/m_sCardNo, /*3*/"00", /*4*/Payment.ToString(), /*5*/"0"
                            //  , /*6*/m_sTax, /*7*/"", /*8*/"", /*9*/m_sIcChip, /*10*/""
                            //  , /*11*/m_sFallDiv,  /*12*/"0",/*13*/"",/*14*/"",/*15*/""
                            //  , /*16*/"",/*17*/"",/*18*/"", /*19*/m_dCreditCardDcAtm.ToString()
                            //  , /*20*/ItemConst.PAY_APP_DIV.NORMAL, /*21*/"", /*22*/m_sService });

                            //    }
                            //}
                            //else
                            //{
                            sRet = paymentUs.SetPayment(new string[] {
                                /*0*/m_sInMaskData, /*1*/m_InputType, /*2*/m_sCardNo, /*3*/"00", /*4*/lastPayment.ToString(), /*5*/"0"
                              , /*6*/m_sTax, /*7*/"", /*8*/"", /*9*/m_sIcChip, /*10*/m_sSign
                              , /*11*/m_sFallDiv,  /*12*/"0",/*13*/"",/*14*/"",/*15*/""
                              , /*16*/"",/*17*/"",/*18*/"", /*19*/m_dCreditCardDcAtm.ToString()
                              , /*20*/ItemConst.PAY_APP_DIV.NORMAL, /*21*/"", /*22*/m_sService });
                            //}


                            if (sRet != UserCom.RST_OK)
                            {
                                InDataToZeroFill();
                                m_bProcessSuccess = false;
                                if (sRet == null || sRet.Equals(UserCom.RST_ERR))
                                {
                                    SendErrLogEvent(ErrorCode.LastPaymentsUnknownError);
                                }
                                else
                                {
                                    SendErrorMessageEvent(sRet);
                                }
                            }
                            else
                            {
                                PaymentsValue = lastPayment;
                                m_bProcessSuccess = true;
                            }
                        }
                        break;
                    
                    case LastPaymentsType.SmilePay:

                        #region :: Smile Pay 결제로직                        

                        // 승인금액 또는 결제 금액을 확인 하세요.
                        //if (m_cDataService.DoubleParse(txtPayAmt.Text) <= 0)
                        //{
                        //    MessageManager.GetErrorMessage(POS_MESSAGE.ERROR.MSG_0597);
                        //    return false;
                        //}

                        string sInPutType = m_InputType;
                        string sInPutData = m_sInPutData;
                        string sInEncData = m_sCardNo;
                        string sInOrgData = m_sInPutData;
                        //if (m_sInEncData == "")
                        //{
                        //    if (m_sInPutData == "")
                        //    {
                        //        ///sInPutType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_KEYIN;
                        //        sInPutType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_MOBILE_SWIP;
                        //        sInOrgData = txtCardNo.Value;
                        //        //sInPutData = txtCardNo.Value;
                        //    }

                        //    EncryptedCardNo(sInOrgData, ref sInPutData, ref sInEncData);
                        //}

                        //#17169 스마일페이 변경요청 건 start, 20181113
                        //기존소스
                        /*
                        //#17169 스마일페이 변경요청 건 start
                        string sSmilepayCampaingCode = "";
                        string sSmilepayPromotionCode = "";
                        double dSmileCashTargetAmt = 0;
                        if (m_cDataService.DoubleParse(txtDCAmt.Text) > 0)
                        {
                            m_cCampaingMain.GetSmilepayPromotionCode(out sSmilepayCampaingCode, out sSmilepayPromotionCode);
                            if (sSmilepayCampaingCode != "" && sSmilepayPromotionCode != "") { dSmileCashTargetAmt = m_cCampaingMain.GetSmileCashTargetAmt(sSmilepayCampaingCode); }
                        }
                        //#17169 스마일페이 변경요청 건 end
                        */

                        //변경소스
                        string sSmilepayPromotionCode = ""; //스마일페이로모션코드          
                        double dSmileCashTargetAmt = 0; //스마일캐시금액
                        bool bApplyCampaign = false; // 적용된캠페인유무

                        m_cCampaingMain.GetSmailePayCampaignCheck(Payment, out sSmilepayPromotionCode, out dSmileCashTargetAmt, out bApplyCampaign);
                        //#17169 스마일페이 변경요청 건 end, 20181113

                        //#17169 스마일페이 변경요청 건 start
                        //기존
                        //포인트 사용 승인 처리
                        //sRet = m_cSmilePay.SetPayment(new string[] { m_sPosMenuKey, sInPutType, sInPutData, sInEncData, m_cDataService.DoubleParse(txtPayAmt.Text).ToString(), "", sInOrgData });
                        //변경
                        //포인트 사용 승인 처리
                        m_sPosMenuKey = PosKey.MENU_KEY.SMILE_PAY;
                        sRet = m_cSmilePay.SetPayment(new string[] { m_sPosMenuKey, sInPutType, sInPutData, sInEncData, Payment.ToString(), "", sInOrgData, sSmilepayPromotionCode, m_cPosStatus.Global.NumericTOCurrency(dSmileCashTargetAmt) });
                        //#17169 스마일페이 변경요청 건 end

                        if (sRet != UserCom.RST_OK)
                        {
                            m_bProcessSuccess = false;
                            SendErrLogEvent(ErrorCode.LastPaymentsUnknownError);
                            return;
                        }
                        else
                        {   // 자동적립사용이면 스마일페이 자동적립 처리
                            if (PosMstManager.GetPosOption(POS_OPTION.OPT030) == "1")
                            {
                                sRet = m_cHappyPoint.SetSmilePayment(new string[] { sInPutType, sInPutData, sInEncData, "0", "", sInOrgData });
                            }
                            if (!sRet.Equals(UserCom.RST_OK))
                            {

                            }

                        }

                        // 캠페인 처리 => 키값(취소시사용),카드번호,캠페인대상,지불구분,지불금액
                        ArrayList alPayItem2 = (ArrayList)StateObject.GetItemObject(Column.TR_PAYMENT.ITEM);                        
                        m_cCampaingMain.CompleteCampaignPayment((alPayItem2.Count - 1).ToString());
                        //#14538 스마일페이 캠페인 확인창 중복 팝업 확인요청 start,phj
                        //double nDisAmt2 = m_cCampaingMain.ExecuteCampaignPayment(alPayItem2.Count.ToString(), m_sCardNo, ItemConst.CPI_CUST_PAY_TYPE.SMILEPAY, Payment, false);

                        PaymentsValue = Payment;
                        m_bProcessSuccess = true;

                        #endregion

                        break;
                }

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this,"CompleteTxtInPut()","Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            finally
            {
              if (m_cPayments != null) m_cPayments = null;
            }
            CommonLog.DebugLogWrite(this, "CompleteTxtInPut()", "End");
        }
        /// <summary>
        /// 카드 번호 암호화
        /// </summary>
        /// <param name="sInData"></param>
        /// <param name="sInMaskData"></param>
        /// <param name="sInEncData"></param>
        /// <returns></returns>
        private bool EncryptedCardNo(string sInData, ref string sInMaskData, ref string sInEncData)
        {
            string sEncData = sInData;
            bool bRet = false;
            try
            {

                //#20170913 현금영수증, 포인트카드 마스킹 미적용 start
                // "0"인 경우 마스킹 미처리
                //기존
                //sEncData = m_cDeviceICReader.GetEncryptedCardNo(sInData).Trim();
                //변경
                sEncData = m_cDeviceICReader.GetEncryptedCardNo(sInData, "0").Trim();
                //#20170913 현금영수증, 포인트카드 마스킹 미적용 end

                if (CmUtil.MidH(sEncData, 0, 2) == "00")
                {
                    sInEncData = CmUtil.MidH(sEncData, 2, 512).Trim();                          // 암호화 데이터
                    sInMaskData = CmUtil.MidH(sEncData, 514, sEncData.Length - 514).Trim();     // 마스킹 데이터

                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 start
                    sInMaskData = CmUtil.MidH(sInMaskData, 0, 6) + "********";
                    //#20170913 현금영수증, 포인트카드 마스킹 미적용 end

                    bRet = true;
                }
                else
                {
                    CommonLog.ErrorLogWrite(this,"EncryptedCardNo()","Fail !!");
                }

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this,"EncryptedCardNo()","Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            return bRet;
        }

        #region 여전법 대응
        /// <summary>
        /// ZeroFill 초기화
        /// </summary>
        private void InDataToZeroFill()
        {
            try
            {
                
                //여전법 대응!
                //////////////////////////////////////////////////////////////////////////////////
                CmUtil.ZeroFillClear(ref m_sInPutData);
                CmUtil.ZeroFillClear(ref m_sCardNo);
                CmUtil.ZeroFillClear(ref m_sInMaskData);
                //////////////////////////////////////////////////////////////////////////////////
            }
            catch
            {
            }

        }
        #endregion 여전법 대응

        #region IC리더 콜백

        /// <summary>
        /// IC리더 콜백 함수(CardInfo)
        /// </summary>
        /// <param name="returnValue"></param>
        /// <param name="returnData"></param>
        public void OnIcReaderCallBackCardInfo(int num, StringBuilder str)
        {
            try
            {
                IcCallBack = false;
                switch (PaymentsType)
                {
                    case LastPaymentsType.IcCard:
                    case LastPaymentsType.SsLgPay:
                    case LastPaymentsType.HappyGift:
                        SendReadStart();
                        break;
                }
                ClearCardInfo();        // 카드 입력 정보 클리어
                if (num > 0)
                {
                    string sRsvStr = str.ToString();
                    if (CmUtil.MidH(sRsvStr, 0, 2) == "00")
                    {
                        m_sCardNo = CmUtil.MidH(sRsvStr, 6, 512).Trim();
                        m_sInMaskData = CmUtil.MidH(sRsvStr, 1030, 37).Trim();
                        m_sService = CmUtil.MidH(sRsvStr, 1067, 5).Trim();
                        m_sFallDiv = CmUtil.MidH(sRsvStr, 3, 1).Trim();
                        m_sIcChip = CmUtil.MidH(sRsvStr, 518, 512).Trim();
                        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 start,phj
                        m_sMobileCode = CmUtil.MidH(sRsvStr, 1072, 7).Trim();
                        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 end,phj
                        if (CmUtil.MidH(sRsvStr, 4, 2).Trim() == "02")
                        //if (CmUtil.MidH(sRsvStr, 6, 2).Trim() == "EN") //모터드리븐 처리 (2019.04.23)
                        {
                            m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_SWIP;
                            m_sIcChip  = m_sFallDiv.Equals("3") ? m_sIcChip : string.Empty;
                        }
                        else
                        {
                            m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_IC;
                        }
                        m_sInPutData = m_sInMaskData;
                    }
                }

                
            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this,"OnIcReaderCallBackCardInfo()","Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            ReadProcessEnd = true;
        }

        private bool GetIcCardData()
        {
            string sRsvStr = "";
            try
            {
                //IcCallBack = false;     // IC리더 콜백 해지


                if (m_cDeviceICReader.GetCardInfo_ICReader(PosConst.IC_READER_TRAN_TYPE.CREDIT, CmUtil.IntParse(Payment.ToString()), ref sRsvStr) == true)
                {
                    if (CmUtil.MidH(sRsvStr, 0, 2) == "00")
                    {
                        m_sCardNo = CmUtil.MidH(sRsvStr, 6, 512).Trim();
                        m_sInMaskData = CmUtil.MidH(sRsvStr, 1030, 37).Trim();
                        m_sIcChip = CmUtil.MidH(sRsvStr, 518, 512).Trim();
                        if (CmUtil.MidH(sRsvStr, 4, 2).Trim() == "02")
                        {
                            m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_SWIP;
                        }
                        else
                        {
                            m_InputType = PosConst.POS_VAN_MASTER.INPUT_TYPE.VAN_IC;
                        }
                        m_sService = CmUtil.MidH(sRsvStr, 1067, 5).Trim();
                        m_sFallDiv = CmUtil.MidH(sRsvStr, 3, 1); // == "3" ? "0" : "1";
                        m_sInPutData = m_sInMaskData;
                        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 start,phj
                        m_sMobileCode = CmUtil.MidH(sRsvStr, 1072, 7).Trim();
                        //#15183 보안리더기 삼성페이 해피포인트 자동적립 기능 수정 end,phj
                        return true;
                    }
                }

            }
            catch (Exception ex)
            {
                CommonLog.ErrorLogWrite(this, "GetIcCardData()","Fail !!", string.Format("{0}\n{1}", ex.Message, ex.StackTrace));
            }
            finally
            {
                // 여전법 대응////////////////////////////////////////////////////////////////////
                CmUtil.ZeroFillClear(ref sRsvStr);
                //////////////////////////////////////////////////////////////////////////////////
            }
            return false;
        }
        #endregion
        private void SendErrorMessageEvent(string _errorMessageString)
        {
            try
            {
                CommonLog.ErrorLogWrite(this, "SendErrorMessageEvent()", _errorMessageString);
                ErrorMessageEvent(_errorMessageString);
            }
            catch
            {
            }
        }
        private void SendErrLogEvent(ErrorCode _errorCode)
        {
            try
            {
                CommonLog.DebugLogWrite(this, "SendErrLogEvent()", _errorCode.ToString());
                ErrorEvent(_errorCode);
            }
            catch
            {

            }
        }
        private void SendReadStart()
        {
            try
            {
                CommonLog.DebugLogWrite(this, "SendReadStart()");
                ReadStart(this);
            }
            catch
            {

            }
        }
        private void SendReadEnd()
        {
            try
            {
                CommonLog.DebugLogWrite(this, "SendReadEnd()");
                ReadEnd(this);
            }
            catch
            {

            }
        }

        private void SignStart()
        {
            try
            {
                CommonLog.DebugLogWrite(this, "SignStart()");
                SignStartEvent(this);
            }
            catch
            {

            }
            
        }
        private void SignEnd()
        {
            try
            {
                CommonLog.DebugLogWrite(this, "SignEnd()");
                SignEndEvent(this);
            }
            catch
            {

            }

        }


        private void ClearCardInfo()
        {
            try
            {
                m_sSign = "";
                m_InputType = "";      // 입력구분
                m_sInPutData = "";      // 입력데이터
                m_sInMaskData = "";     // 마스킹
                m_sCardNo = "";      // 카드데이터인카드번호


                m_bProcessSuccess = false;
            }
            catch 
            {
            }
        }
        #endregion




    }
}