/// <summary> /// Response物件建立MAC並依據規格書轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就使用來源的mac</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, POL_Domain response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.PCHR_RC, rspResult, "ReturnCode"); msgUtility.SetStr(response.PCHR_SN, rspResult, "CenterSeqNo"); msgUtility.SetStr(this.amount, rspResult, "Amount"); msgUtility.SetStr(this.transDateTime, rspResult, "TransDateTime"); //是否產生mac if (doMAC) { // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data this.SetPadding(msgUtility, rspResult); return(rspResult); }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">使用的Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual Txlog_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { /* * {"COM_TYPE":"0341","MERCHANT_NO":null,"MERC_FLG":"SET","M_KIND":null,"POS_FLG":"01","POS_SEQNO":"471756","READER_ID":"8604241F6A9F2980 ","REG_ID":"01","SN":"02922396","STORE_NO":"113584","TRANS_TYPE":null,"TXLOG":"52201411031908470000000073111400240070060000020004241F6A9F2980000005000000420000001500009100000000270000880604241F6A9F298000000000000000000000000100000200000000006520C0FBSET00100113584100118604241F6A9F2980 00000294000000000000000000000000000000000000000000000000000000000000000000000A2","TXLOG_RC":null} */ log.Debug("1.開始轉換一般加值TxLog Request物件"); Txlog_Domain oLDomain = new Txlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換一般加值TxLog Request物件"); return(oLDomain); }
/// <summary> /// Request依據規格書截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Request Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual POL_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("3.開始轉換購貨取消Request物件"); POL_Domain oLDomain = new POL_Domain(); //ComType:0332 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = this.readerId;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); // modify StoreNo and RegId if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.PCHR_AMT = Convert.ToInt32(this.amount); // oLDomain.ICC_NO = msgUtility.GetStr(msgBytes, "CardNo"); log.Debug("4.結束轉換購貨取消Request物件"); return(oLDomain); }
/// <summary> /// Response物件建立MAC並依據規格書轉轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就不產了</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, AL2POS_Domain response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); //return code msgUtility.SetStr(response.AL2POS_RC, rspResult, "ReturnCode"); //承認編號 msgUtility.SetStr(response.AL2POS_SN, rspResult, "CenterSeqNo"); //Answer msgUtility.SetBytes(this.cardFormatMemberId, rspResult, "CardFormatMemberId"); msgUtility.SetStr(this.cardNo, rspResult, "CardNo"); msgUtility.SetStr(this.cardExpireDate1, rspResult, "CardExpireDate1"); msgUtility.SetStr(this.cardExpireDate2, rspResult, "CardExpireDate2"); //交易時間 msgUtility.SetStr(this.transDateTime, rspResult, "TransDateTime"); //是否產生mac if (doMAC) { // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime);//CheckMacContainer.Mac2Manager.GetAuthMac(response.READER_ID, response.AL_TRANSTIME, sha1Result); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data this.SetPadding(msgUtility, rspResult); return(rspResult); }
/// <summary> /// 檢驗Request的MAC /// </summary> /// <param name="msgUtility">Request Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>true:success/false:failed</returns> protected virtual bool CheckMac(IMsgUtility msgUtility, byte[] msgBytes) { bool result = false; try { log.Debug(m => m("1.開始驗證MAC")); //reader id 取前面16個字串 this.readerId = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); //取交易時間 this.transDateTime = msgUtility.GetStr(msgBytes, "TransDateTime");; //取後面的mac:要用來檢查data部分是否有被串改 this.mac = msgUtility.GetStr(msgBytes, "Mac"); //錢 this.amount = msgUtility.GetStr(msgBytes, "Amount"); //將data的部分取出作SHA1 byte[] hashData = msgUtility.GetBytes(msgBytes, "HeaderVersion", "Mac"); byte[] hashResult = CheckMacContainer.HashWorker.ComputeHash(hashData); //開始檢查hash過的data部分是否與mac値一致 result = CheckMacContainer.Mac2Manager.ChkInitMac(this.readerId, this.transDateTime, hashResult, this.mac); log.Debug(m => m("2.結束驗證MAC:{0}", result.ToString())); return(result); } catch (Exception ex) { log.Error(m => m("[State_PurchaseReturn][CheckMac] Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); return(false); } }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgBytes">Origin Request byte array</param> /// <param name="msgUtility">Request Msg Parser</param> /// <returns>POCO</returns> protected virtual AL2POS_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("3.開始轉換自動加值查詢Request物件"); AL2POS_Domain oLDomain = new AL2POS_Domain(); //ComType:0531 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); //端末Maker種別 oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); //端末製造編號 oLDomain.READER_ID = this.readerId;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); //客戶識別符號 ex:SET oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); // modify StoreNo and RegId if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.AL_AMT = 0; // oLDomain.ICC_NO = msgUtility.GetStr(msgBytes, "CardNo"); oLDomain.AL_TRANSTIME = this.transDateTime;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "TransDateTime"); log.Debug("4.結束轉換自動加值查詢Request物件"); return(oLDomain); }
/// <summary> /// Response物件建立MAC並依據規格書轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就使用來源的mac</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, AL2POS_Domain response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; string rrn = (" ").PadLeft(12); Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.AL2POS_RC, rspResult, "ReturnCode"); msgUtility.SetStr(response.AL2POS_SN, rspResult, "CenterSeqNo"); msgUtility.SetStr(this.amount, rspResult, "Amount"); if (!String.IsNullOrEmpty(response.AL_RRN)) { rrn = response.AL_RRN; } msgUtility.SetStr(rrn, rspResult, "Rrn"); msgUtility.SetStr(this.transDateTime, rspResult, "TransDateTime"); //是否產生mac if (doMAC) { // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime);//CheckMacContainer.Mac2Manager.GetAuthMac(response.READER_ID, response.AL_TRANSTIME, sha1Result); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data this.SetPadding(msgUtility, rspResult); return(rspResult); }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual ALTxlog_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("1.開始轉換自動加值TxLog Request物件"); ALTxlog_Domain oLDomain = new ALTxlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換自動加值TxLog Request物件"); return(oLDomain); }
/// <summary> /// 依據Request設定card情報屬性値 /// </summary> /// <param name="msgBytes">Origin Request byte array</param> /// <param name="msgUtility">Request Msg Parser</param> protected virtual void SetCardInfo(IMsgUtility msgUtility, byte[] msgBytes) { //Response要用的資料部分 this.cardFormatMemberId = msgUtility.GetBytes(msgBytes, "CardFormatMemberId"); this.cardNo = msgUtility.GetStr(msgBytes, "CardNo"); this.cardExpireDate1 = msgUtility.GetStr(msgBytes, "CardExpireDate1"); this.cardExpireDate2 = msgUtility.GetStr(msgBytes, "CardExpireDate2"); }
/// <summary> /// 設定Response的Padding部分 /// </summary> /// <param name="resMsgUility">Response Msg Parser</param> /// <param name="response">要寫入的response byte array</param> protected virtual void SetPadding(IMsgUtility resMsgUility, byte[] response) { // padding data byte[] spacePadding = CheckMacContainer.ByteWorker.Fill(resMsgUility.GetTag("DataPadding").Length, 0x20); resMsgUility.SetBytes(spacePadding, response, "DataPadding"); int length = response.Length; log.Debug(m => m("9.Response Padding End (array length:{0})", length)); }
/// <summary> /// Response寫入MAC /// </summary> /// <param name="resMsgUility">Response Parser</param> /// <param name="response">response byte array</param> /// <param name="reader_id">卡機裝置ID(length:16)</param> /// <param name="transTime">交易時間(length:14)</param> protected virtual void SetMAC(IMsgUtility resMsgUility, byte[] response, string reader_id, string transTime) { // fetch sha1 data byte[] hashDataBytes = resMsgUility.GetBytes(response, "HeaderVersion", "Mac"); byte[] sha1Result = CheckMacContainer.HashWorker.ComputeHash(hashDataBytes); string mac = CheckMacContainer.Mac2Manager.GetAuthMac(reader_id, transTime, sha1Result); resMsgUility.SetStr(mac, response, "Mac"); log.Debug(m => m("8.Response mac: {0}", mac)); }
private string GenMac(IMsgUtility msgUtility, string data, int macLength = 8) { byte[] result = Encoding.ASCII.GetBytes(data); result = result.Concat(new byte[macLength]).ToArray();//insert a byte[ mac length ] string readerId = msgUtility.GetStr(result, "ReaderId").Substring(0, 16); string transDatetime = msgUtility.GetStr(result, "TransDateTime"); // fetch sha1 data byte[] hashDataBytes = msgUtility.GetBytes(result, "HeaderVersion", "Mac"); byte[] sha1Result = MsgContainer.HashWorker.ComputeHash(hashDataBytes); string macStr = MsgContainer.Mac2Manager.GetAuthMac(readerId, transDatetime, sha1Result); return(macStr); }
//測試Dennis的dll(Spring.net) static void Main1(string[] args) { //app.config要先加入設定的object,目前已在Assembly file內loading,要改成可變更需拿出來變resource file IApplicationContext ctx = ContextRegistry.GetContext(); IHexConverter hexConverter = ctx["hexConverter"] as IHexConverter; IByteWorker byteWorker = ctx["byteWorker"] as IByteWorker; IMac2Manager mac2Manager = ctx["mac2Manager"] as IMac2Manager; IHashWorker hashWorker = ctx["hashWorker"] as IHashWorker; IMsgUtility msgUtility = ctx["icash2AOLReqMsgUtility"] as IMsgUtility; IMsgUtility PAMReqMsgUtility = ctx["icash2PAMReqMsgUtility"] as IMsgUtility; IMsgUtility PAMRespMsgUtility = ctx["icash2PAMRespMsgUtility"] as IMsgUtility; Console.ReadKey(); }
/// <summary> /// Request依據規格書截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Request Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual CTGB_Soc_Request ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("3.開始轉換取PAM額度Request物件"); CTGB_Soc_Request oLDomain = new CTGB_Soc_Request(); //ComType:0322 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.READER_TYPE = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId"); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); //RW 機種Code oLDomain.RW_TYPE = msgUtility.GetStr(msgBytes, "RwType"); //端末區分 oLDomain.READER_FLG = msgUtility.GetStr(msgBytes, "ReaderFlg"); //Service Code: 總部Code 001 oLDomain.SVC_FLG = msgUtility.GetStr(msgBytes, "SvcFlg"); //機器種別 oLDomain.MACHINE_TYPE = msgUtility.GetStr(msgBytes, "MachineType"); //RW編號 oLDomain.RW_NO = msgUtility.GetStr(msgBytes, "RwNo"); //Data部分 //特約機構代號 oLDomain.MERCHANT_ID = msgUtility.GetStr(msgBytes, "MerchantID"); //POS交易序號 oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); //收銀員編號 oLDomain.CASHIER_NO = msgUtility.GetStr(msgBytes, "CashierNo"); //端末ID oLDomain.Terminal_ID = msgUtility.GetStr(msgBytes, "TerminalID"); //前次加值日的加值水位餘額 oLDomain.LOADING_BAL = msgUtility.GetStr(msgBytes, "LoadingBalance"); //前次加值日的加值交易累計次數 oLDomain.LOADING_SEQ = msgUtility.GetStr(msgBytes, "LoadingSequence"); //電文產出日時 oLDomain.DATETIME = msgUtility.GetStr(msgBytes, "DateTime"); //request mac oLDomain.MAC = this.mac; log.Debug("4.結束轉換取PAM額度Request物件"); return(oLDomain); }
/// <summary> /// Response物件轉換成byte[] /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, ALTxlog_Domain response, byte[] request) { log.Debug(m => m("5.轉換後台自動加值TxLog Response物件 => Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.TXLOG_RC, rspResult, "ReturnCode"); //取得資料部分的大小並設定 string sizeStr = CheckMacContainer.StrHelper.LeftPad(msgUtility.GetSize("DataVersion", "EndOfData"), msgUtility.GetTag("DecryptSize").Length, '0'); msgUtility.SetStr(sizeStr, rspResult, "DecryptSize"); msgUtility.SetStr(sizeStr, rspResult, "EncryptSize"); //寫入空白 msgUtility.SetBytes(CheckMacContainer.ByteWorker.Fill(msgUtility.GetTag("DataPadding").Length, 0x20), rspResult, "DataPadding"); //依據定義改變Response大小(因Request資料部分長度與Response資料部分長度不一樣) rspResult = CheckMacContainer.ByteWorker.SubArray(rspResult, 0, msgUtility.GetSize("HeaderVersion", "EndOfData")); log.Debug(m => m("6.轉換後台自動加值TxLog Response物件完畢")); return(rspResult); }
/// <summary> /// Response物件建立MAC並依據規格書轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就使用來源的mac</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, CTGB_Soc_Request response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response(必定回傳資訊) msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.RETURN_CODE, rspResult, "ReturnCode"); msgUtility.SetStr(response.SN, rspResult, "CenterSeqNo"); msgUtility.SetStr(this.transDateTime, rspResult, "DateTime"); //是否產生mac(request的mac驗證成功就會還一個response,不論後台response正常或異常) if (doMAC) { msgUtility.SetStr(response.MERCHANT_ID, rspResult, "MerchantID"); msgUtility.SetStr(response.STORE_NO, rspResult, "StoreID"); msgUtility.SetStr(response.REG_ID, rspResult, "POSNO"); msgUtility.SetStr(response.POS_SEQNO, rspResult, "PosSeqNo"); msgUtility.SetStr(response.CASHIER_NO, rspResult, "CashierNo"); msgUtility.SetStr(response.READER_ID, rspResult, "TerminalID"); msgUtility.SetStr(response.LOADING_BAL, rspResult, "LoadingBalance"); msgUtility.SetStr(response.LOADING_SEQ, rspResult, "LoadingSequence"); // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data : SPEC length 0 //this.SetPadding(msgUtility, rspResult); return(rspResult); }
/// <summary> /// 設定Response的Padding部分 /// </summary> /// <param name="resMsgUility">Response Msg Parser</param> /// <param name="response">要寫入的response byte array</param> protected virtual void SetPadding(IMsgUtility resMsgUility, byte[] response) { // padding data byte[] spacePadding = CheckMacContainer.ByteWorker.Fill(resMsgUility.GetTag("DataPadding").Length, 0x20); resMsgUility.SetBytes(spacePadding, response, "DataPadding"); //log.Debug(m => m("9.Response Byte[]轉換完成, length:{0}", response.Length)); int length = response.Length; log.Debug(m => m("9.Response Padding End (array length:{0})", length)); }
/// <summary> /// Response寫入MAC /// </summary> /// <param name="resMsgUility">Response Msg Parser</param> /// <param name="response">response byte array</param> /// <param name="reader_id">卡機裝置ID(length:16)</param> /// <param name="transTime">交易時間(length:14)</param> /// <returns></returns> protected virtual void SetMAC(IMsgUtility resMsgUility, byte[] response, string reader_id, string transTime) { // fetch sha1 data byte[] hashDataBytes = resMsgUility.GetBytes(response, "HeaderVersion", "Mac"); byte[] sha1Result = CheckMacContainer.HashWorker.ComputeHash(hashDataBytes); string mac = CheckMacContainer.Mac2Manager.GetAuthMac(reader_id, transTime, sha1Result); resMsgUility.SetStr(mac, response, "Mac"); log.Debug(m => m("8.Response mac: {0}", mac)); }
/// <summary> /// 依據Request設定card情報屬性値 /// </summary> /// <param name="msgBytes">Origin Request byte array</param> /// <param name="msgUtility">Request Msg Parser</param> protected virtual void SetCardInfo(IMsgUtility msgUtility,byte[] msgBytes) { //Response要用的資料部分 this.cardFormatMemberId = msgUtility.GetBytes(msgBytes, "CardFormatMemberId"); this.cardNo = msgUtility.GetStr(msgBytes, "CardNo"); this.cardExpireDate1 = msgUtility.GetStr(msgBytes, "CardExpireDate1"); this.cardExpireDate2 = msgUtility.GetStr(msgBytes, "CardExpireDate2"); }
/// <summary> /// Response物件建立MAC並依據規格書轉轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就不產了</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, AL2POS_Domain response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); //return code msgUtility.SetStr(response.AL2POS_RC, rspResult, "ReturnCode"); //承認編號 msgUtility.SetStr(response.AL2POS_SN, rspResult, "CenterSeqNo"); //Answer msgUtility.SetBytes(this.cardFormatMemberId, rspResult, "CardFormatMemberId"); msgUtility.SetStr(this.cardNo, rspResult, "CardNo"); msgUtility.SetStr(this.cardExpireDate1, rspResult, "CardExpireDate1"); msgUtility.SetStr(this.cardExpireDate2, rspResult, "CardExpireDate2"); //交易時間 msgUtility.SetStr(this.transDateTime, rspResult, "TransDateTime"); //是否產生mac if (doMAC) { // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime);//CheckMacContainer.Mac2Manager.GetAuthMac(response.READER_ID, response.AL_TRANSTIME, sha1Result); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data this.SetPadding(msgUtility, rspResult); return rspResult; }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgBytes">Origin Request byte array</param> /// <param name="msgUtility">Request Msg Parser</param> /// <returns>POCO</returns> protected virtual AL2POS_Domain ParseRequest(IMsgUtility msgUtility,byte[] msgBytes) { log.Debug("3.開始轉換自動加值查詢Request物件"); AL2POS_Domain oLDomain = new AL2POS_Domain(); //ComType:0531 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); //端末Maker種別 oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); //端末製造編號 oLDomain.READER_ID = this.readerId;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); //客戶識別符號 ex:SET oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); // modify StoreNo and RegId if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.AL_AMT = 0; // oLDomain.ICC_NO = msgUtility.GetStr(msgBytes, "CardNo"); oLDomain.AL_TRANSTIME = this.transDateTime;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "TransDateTime"); log.Debug("4.結束轉換自動加值查詢Request物件"); return oLDomain; }
/// <summary> /// 檢驗Request的MAC /// </summary> /// <param name="msgBytes">Origin Request byte array</param> /// <param name="msgUtility">Request Msg Parser</param> /// <returns>true:success/false:failed</returns> protected virtual bool CheckMac(IMsgUtility msgUtility,byte[] msgBytes) { bool result = false; try { log.Debug(m => m("1.開始驗證MAC")); //設定Card情報:驗證失敗的時候用 this.SetCardInfo(msgUtility, msgBytes); //reader id 取前面16個字串 this.readerId = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); //取交易時間 this.transDateTime = msgUtility.GetStr(msgBytes, "TransDateTime"); ; //取後面的mac:要用來檢查data部分是否有被串改 this.mac = msgUtility.GetStr(msgBytes, "Mac"); //將data的部分取出作SHA1 byte[] hashData = msgUtility.GetBytes(msgBytes, "HeaderVersion", "Mac"); byte[] hashResult = CheckMacContainer.HashWorker.ComputeHash(hashData); //開始檢查hash過的data部分是否與mac値一致 result = CheckMacContainer.Mac2Manager.ChkInitMac(this.readerId, this.transDateTime, hashResult, this.mac); log.Debug(m => m("2.結束驗證MAC:{0}", result.ToString())); return result; } catch (Exception ex) { log.Error(m => m("[State_AutoLoadQuery][CheckMac] Error: {0} \r\n{1}", ex.Message, ex.StackTrace)); return false; } }
/// <summary> /// Response物件轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, Txlog_Domain response, byte[] request) { log.Debug(m => m("5.轉換後台購貨取消TxLog Response物件 => Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.TXLOG_RC, rspResult, "ReturnCode"); //取得資料部分的大小並設定 string sizeStr = CheckMacContainer.StrHelper.LeftPad(msgUtility.GetSize("DataVersion", "EndOfData"), msgUtility.GetTag("DecryptSize").Length, '0'); msgUtility.SetStr(sizeStr, rspResult, "DecryptSize"); msgUtility.SetStr(sizeStr, rspResult, "EncryptSize"); //寫入空白 msgUtility.SetBytes(CheckMacContainer.ByteWorker.Fill(msgUtility.GetTag("DataPadding").Length, 0x20), rspResult, "DataPadding"); //依據定義改變Response大小(因Request資料部分長度與Response資料部分長度不一樣) rspResult = CheckMacContainer.ByteWorker.SubArray(rspResult, 0, msgUtility.GetSize("HeaderVersion", "EndOfData")); log.Debug(m => m("6.轉換後台購貨取消TxLog Response物件完畢")); return rspResult; }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual Txlog_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { /* {"COM_TYPE":"0341","MERCHANT_NO":null,"MERC_FLG":"SET","M_KIND":null,"POS_FLG":"01","POS_SEQNO":"471756","READER_ID":"8604241F6A9F2980 ","REG_ID":"01","SN":"02922396","STORE_NO":"113584","TRANS_TYPE":null,"TXLOG":"52201411031908470000000073111400240070060000020004241F6A9F2980000005000000420000001500009100000000270000880604241F6A9F298000000000000000000000000100000200000000006520C0FBSET00100113584100118604241F6A9F2980 00000294000000000000000000000000000000000000000000000000000000000000000000000A2","TXLOG_RC":null} */ log.Debug("1.開始轉換購貨取消TxLog Request物件"); Txlog_Domain oLDomain = new Txlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換購貨取消TxLog Request物件"); return oLDomain; }
/// <summary> /// Response物件建立MAC並依據規格書轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就使用來源的mac</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, CTGB_Soc_Request response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response(必定回傳資訊) msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.RETURN_CODE, rspResult, "ReturnCode"); msgUtility.SetStr(response.SN, rspResult, "CenterSeqNo"); msgUtility.SetStr(this.transDateTime, rspResult, "DateTime"); //是否產生mac(request的mac驗證成功就會還一個response,不論後台response正常或異常) if (doMAC) { msgUtility.SetStr(response.MERCHANT_ID, rspResult, "MerchantID"); msgUtility.SetStr(response.STORE_NO, rspResult, "StoreID"); msgUtility.SetStr(response.REG_ID, rspResult, "POSNO"); msgUtility.SetStr(response.POS_SEQNO, rspResult, "PosSeqNo"); msgUtility.SetStr(response.CASHIER_NO, rspResult, "CashierNo"); msgUtility.SetStr(response.READER_ID, rspResult, "TerminalID"); msgUtility.SetStr(response.LOADING_BAL, rspResult, "LoadingBalance"); msgUtility.SetStr(response.LOADING_SEQ, rspResult, "LoadingSequence"); // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data : SPEC length 0 //this.SetPadding(msgUtility, rspResult); return rspResult; }
/// <summary> /// Request依據規格書截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Request Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual CTGB_Soc_Request ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("3.開始轉換取PAM額度Request物件"); CTGB_Soc_Request oLDomain = new CTGB_Soc_Request(); //ComType:0322 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.READER_TYPE = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId"); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); //RW 機種Code oLDomain.RW_TYPE = msgUtility.GetStr(msgBytes, "RwType"); //端末區分 oLDomain.READER_FLG = msgUtility.GetStr(msgBytes, "ReaderFlg"); //Service Code: 總部Code 001 oLDomain.SVC_FLG = msgUtility.GetStr(msgBytes, "SvcFlg"); //機器種別 oLDomain.MACHINE_TYPE = msgUtility.GetStr(msgBytes, "MachineType"); //RW編號 oLDomain.RW_NO = msgUtility.GetStr(msgBytes, "RwNo"); //Data部分 //特約機構代號 oLDomain.MERCHANT_ID = msgUtility.GetStr(msgBytes, "MerchantID"); //POS交易序號 oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); //收銀員編號 oLDomain.CASHIER_NO = msgUtility.GetStr(msgBytes, "CashierNo"); //端末ID oLDomain.Terminal_ID = msgUtility.GetStr(msgBytes, "TerminalID"); //前次加值日的加值水位餘額 oLDomain.LOADING_BAL = msgUtility.GetStr(msgBytes, "LoadingBalance"); //前次加值日的加值交易累計次數 oLDomain.LOADING_SEQ = msgUtility.GetStr(msgBytes, "LoadingSequence"); //電文產出日時 oLDomain.DATETIME = msgUtility.GetStr(msgBytes, "DateTime"); //request mac oLDomain.MAC = this.mac; log.Debug("4.結束轉換取PAM額度Request物件"); return oLDomain; }
/// <summary> /// Request依據規格書截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Request Msg Parser</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual POL_Domain ParseRequest(IMsgUtility msgUtility, byte[] msgBytes) { log.Debug("3.開始轉換購貨取消Request物件"); POL_Domain oLDomain = new POL_Domain(); //ComType:0332 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = this.readerId;//CheckMacContainer.AOLReqMsgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); // modify StoreNo and RegId if ("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO = oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.PCHR_AMT = Convert.ToInt32(this.amount); // oLDomain.ICC_NO = msgUtility.GetStr(msgBytes, "CardNo"); log.Debug("4.結束轉換購貨取消Request物件"); return oLDomain; }
/// <summary> /// Response物件建立MAC並依據規格書轉換成byte[] /// </summary> /// <param name="msgUtility">Response Msg Parser</param> /// <param name="response">後端給的POCO</param> /// <param name="request">Origin Request byte array</param> /// <param name="doMAC">是否產生MAC:驗證失敗就使用來源的mac</param> /// <returns>response byte array</returns> protected virtual byte[] ParseResponse(IMsgUtility msgUtility, POL_Domain response, byte[] request, bool doMAC = true) { log.Debug(m => m("7.轉換後台Response物件並建立MAC並轉成Response Byte[]")); byte[] rspResult = new byte[request.Length]; Buffer.BlockCopy(request, 0, rspResult, 0, request.Length);// // modify request to response msgUtility.SetStr("02", rspResult, "Communicate"); msgUtility.SetStr(response.PCHR_RC, rspResult, "ReturnCode"); msgUtility.SetStr(response.PCHR_SN, rspResult, "CenterSeqNo"); msgUtility.SetStr(this.amount, rspResult, "Amount"); msgUtility.SetStr(this.transDateTime, rspResult, "TransDateTime"); //是否產生mac if (doMAC) { // fetch sha1 data this.SetMAC(msgUtility, rspResult, this.readerId, this.transDateTime); } else { //若Mac驗證失敗,則使用來源mac簡易回傳 msgUtility.SetStr(this.mac, rspResult, "Mac"); } // padding data this.SetPadding(msgUtility, rspResult); return rspResult; }
private string GenMac(IMsgUtility msgUtility,string data,int macLength = 8) { byte[] result = Encoding.ASCII.GetBytes(data); result = result.Concat(new byte[macLength]).ToArray();//insert a byte[ mac length ] string readerId = msgUtility.GetStr(result, "ReaderId").Substring(0, 16); string transDatetime = msgUtility.GetStr(result, "TransDateTime"); // fetch sha1 data byte[] hashDataBytes = msgUtility.GetBytes(result, "HeaderVersion", "Mac"); byte[] sha1Result = MsgContainer.HashWorker.ComputeHash(hashDataBytes); string macStr = MsgContainer.Mac2Manager.GetAuthMac(readerId, transDatetime, sha1Result); return macStr; }
/// <summary> /// Request截取需要的資料轉成POCO /// </summary> /// <param name="msgUtility">Msg Parser Object</param> /// <param name="msgBytes">Origin Request byte array</param> /// <returns>POCO</returns> protected virtual ALTxlog_Domain ParseRequest(IMsgUtility msgUtility,byte[] msgBytes) { log.Debug("1.開始轉換自動加值TxLog Request物件"); ALTxlog_Domain oLDomain = new ALTxlog_Domain(); //ComType:0333 oLDomain.COM_TYPE = msgUtility.GetStr(msgBytes, "ReqType"); oLDomain.POS_FLG = msgUtility.GetStr(msgBytes, "ReaderType"); oLDomain.READER_ID = msgUtility.GetStr(msgBytes, "ReaderId").Substring(0, 16); oLDomain.MERC_FLG = msgUtility.GetStr(msgBytes, "MercFlg"); oLDomain.STORE_NO = msgUtility.GetStr(msgBytes, "StoreNo"); oLDomain.REG_ID = msgUtility.GetStr(msgBytes, "RegId"); if("SET".Equals(oLDomain.MERC_FLG)) { oLDomain.STORE_NO =oLDomain.STORE_NO.Substring(2, 6); oLDomain.REG_ID = oLDomain.REG_ID.Substring(1, 2); } // oLDomain.SN = msgUtility.GetStr(msgBytes, "CenterSeqNo"); // oLDomain.POS_SEQNO = msgUtility.GetStr(msgBytes, "PosSeqNo"); // oLDomain.TXLOG = msgUtility.GetStr(msgBytes, "CadLog"); log.Debug("2.結束轉換自動加值TxLog Request物件"); return oLDomain; }