/// <summary> /// Parsing segment -> UPD, BPD /// </summary> /// <param name="UserID"></param> /// <param name="BLZ"></param> /// <param name="HBCIVersion"></param> /// <param name="Message"></param> /// <returns></returns> public static List <HBCIBankMessage> Parse_Segments(FinTsClient client, string Message) { try { var connDetails = client.ConnectionDetails; List <HBCIBankMessage> result = new List <HBCIBankMessage>(); List <string> rawSegments = SplitEncryptedSegments(Message); List <Segment> segments = new List <Segment>(); foreach (var item in rawSegments) { Segment segment = Parse_Segment(item); if (segment != null) { segments.Add(segment); } } // BPD string bpd = string.Empty; var bpaMatch = Regex.Match(Message, @"(HIBPA.+?)\b(HITAN|HNHBS|HISYN|HIUPA)\b"); if (bpaMatch.Success) { bpd = bpaMatch.Groups[1].Value; } if (bpd.Length > 0) { SaveBPD(connDetails.Blz, bpd); BPD.ParseBpd(bpd); } // UPD string upd = string.Empty; var upaMatch = Regex.Match(Message, @"(HIUPA.+?)\b(HITAN|HNHBS)\b"); if (upaMatch.Success) { upd = upaMatch.Groups[1].Value; } if (upd.Length > 0) { SaveUPD(connDetails.Blz, connDetails.UserId, upd); UPD.ParseUpd(upd); } if (UPD.AccountList != null) { //Add BIC to Account information (Not retrieved bz UPD??) foreach (AccountInformation accInfo in UPD.AccountList) { accInfo.AccountBic = connDetails.Bic; } } foreach (var segment in segments) { if (segment.Name == "HIRMG") { // HIRMG:2:2+9050::Die Nachricht enthält Fehler.+9800::Dialog abgebrochen+9010::Initialisierung fehlgeschlagen, Auftrag nicht bearbeitet. // HIRMG:2:2+9800::Dialogabbruch. string[] HIRMG_messages = segment.Payload.Split('+'); foreach (var HIRMG_message in HIRMG_messages) { var message = Parse_BankCode_Message(HIRMG_message); if (message != null) { result.Add(message); } } } if (segment.Name == "HIRMS") { // HIRMS:3:2:2+9942::PIN falsch. Zugang gesperrt.' string[] HIRMS_messages = segment.Payload.Split('+'); foreach (var HIRMS_message in HIRMS_messages) { var message = Parse_BankCode_Message(HIRMS_message); if (message != null) { result.Add(message); } } var securityMessage = result.FirstOrDefault(m => m.Code == "3920"); if (securityMessage != null) { string message = securityMessage.Message; string TAN = string.Empty; string TANf = string.Empty; string[] procedures = Regex.Split(message, @"\D+"); foreach (string value in procedures) { if (!string.IsNullOrEmpty(value) && int.TryParse(value, out int i)) { if (Convert.ToString(i).StartsWith("9")) { if (string.IsNullOrEmpty(TAN)) { TAN = i.ToString(); } if (string.IsNullOrEmpty(TANf)) { TANf = i.ToString(); } else { TANf += $";{i}"; } } } } if (string.IsNullOrEmpty(client.HIRMS)) { client.HIRMS = TAN; } else { if (!TANf.Contains(client.HIRMS)) { throw new Exception($"Invalid HIRMS/Tan-Mode {client.HIRMS} detected. Please choose one of the allowed modes: {TANf}"); } } client.HIRMSf = TANf; // Parsing TAN processes if (!string.IsNullOrEmpty(client.HIRMS)) { Parse_TANProcesses(client, bpd); } } } if (segment.Name == "HNHBK") { var ID = Parse_String(segment.Payload, "+1+", ":1"); client.HNHBK = ID; } if (segment.Name == "HISYN") { client.SystemId = segment.Payload; Log.Write("Customer System ID: " + client.SystemId); } if (segment.Name == "HNHBS") { if (segment.Payload == null || segment.Payload == "0") { client.HNHBS = 2; } else { client.HNHBS = Convert.ToInt32(segment.Payload) + 1; } } if (segment.Name == "HISALS") { client.HISALS = segment.Version; } if (segment.Name == "HITANS") { if (client.HITANS != 0 && segment.Version == 7) // Torsten: Rücknahme der Freigabe. Sparkassen ausserhalb der // Pilotphase senden in der BPD bereits das Segment, welches in der UPD noch nicht zur Verfügung steht und somit // zu Abbrüchen führt. //if (client.HITANS != 0) // Torsten: Freigabe HKTAN#7 in libfintx { ; // Ignore HKTAN version 7 if other version is available and version 7 isn't implemented in libfintx } else { client.HITANS = segment.Version; } } if (segment.Name == "HITAN") { client.HITAN = Parse_String(segment.Payload.Replace("?+", "??"), "++", "+").Replace("??", "?+"); } if (segment.Name == "HIKAZS") { if (client.HIKAZS == 0) { client.HIKAZS = segment.Version; } else { if (segment.Version > client.HIKAZS) { client.HIKAZS = segment.Version; } } } if (segment.Name == "HISPAS") { if (segment.Payload.Contains("pain.001.001.03")) { client.HISPAS = 1; } else if (segment.Payload.Contains("pain.001.002.03")) { client.HISPAS = 2; } else if (segment.Payload.Contains("pain.001.003.03")) { client.HISPAS = 3; } if (client.HISPAS == 0) { client.HISPAS = 3; // -> Fallback. Most banks accept the newest pain version } } } // Fallback if HIKAZS is not delivered by BPD (eg. Postbank) if (client.HIKAZS == 0) { client.HIKAZS = 0; } return(result); } catch (Exception ex) { Log.Write(ex.ToString()); throw new InvalidOperationException($"Software error.", ex); } }
/// <summary> /// Parsing segment -> UPD, BPD /// </summary> /// <param name="UserID"></param> /// <param name="BLZ"></param> /// <param name="HBCIVersion"></param> /// <param name="Message"></param> /// <returns></returns> public static List <HBCIBankMessage> Parse_Segments(FinTsClient client, string Message) { try { var connDetails = client.ConnectionDetails; List <HBCIBankMessage> result = new List <HBCIBankMessage>(); List <string> rawSegments = SplitEncryptedSegments(Message); List <Segment> segments = new List <Segment>(); foreach (var item in rawSegments) { Segment segment = Parse_Segment(item); if (segment != null) { segments.Add(segment); } } // BPD string bpd = string.Empty; var bpaMatch = Regex.Match(Message, @"(HIBPA.+?)\b(HITAN|HNHBS|HISYN|HIUPA)\b"); if (bpaMatch.Success) { bpd = bpaMatch.Groups[1].Value; } if (bpd.Length > 0) { SaveBPD(connDetails.Blz, bpd); BPD.ParseBpd(bpd); } // UPD string upd = string.Empty; var upaMatch = Regex.Match(Message, @"(HIUPA.+?)\b(HITAN|HNHBS)\b"); if (upaMatch.Success) { upd = upaMatch.Groups[1].Value; } if (upd.Length > 0) { SaveUPD(connDetails.Blz, connDetails.UserId, upd); UPD.ParseUpd(upd); } if (UPD.AccountList != null) { //Add BIC to Account information (Not retrieved bz UPD??) foreach (AccountInformation accInfo in UPD.AccountList) { accInfo.AccountBic = connDetails.Bic; } } foreach (var segment in segments) { if (segment.Name == "HIRMG") { // HIRMG:2:2+9050::Die Nachricht enthält Fehler.+9800::Dialog abgebrochen+9010::Initialisierung fehlgeschlagen, Auftrag nicht bearbeitet. // HIRMG:2:2+9800::Dialogabbruch. string[] HIRMG_messages = segment.Payload.Split('+'); foreach (var HIRMG_message in HIRMG_messages) { var message = Parse_BankCode_Message(HIRMG_message); if (message != null) { result.Add(message); } } } if (segment.Name == "HIRMS") { // HIRMS:3:2:2+9942::PIN falsch. Zugang gesperrt.' string[] HIRMS_messages = segment.Payload.Split('+'); foreach (var HIRMS_message in HIRMS_messages) { var message = Parse_BankCode_Message(HIRMS_message); if (message != null) { result.Add(message); } } var securityMessage = result.FirstOrDefault(m => m.Code == "3920"); if (securityMessage != null) { string message = securityMessage.Message; string TAN = string.Empty; string TANf = string.Empty; string[] procedures = Regex.Split(message, @"\D+"); foreach (string value in procedures) { if (!string.IsNullOrEmpty(value) && int.TryParse(value, out int i)) { if (value.StartsWith("9")) { if (string.IsNullOrEmpty(TAN)) { TAN = i.ToString(); } if (string.IsNullOrEmpty(TANf)) { TANf = i.ToString(); } else { TANf += $";{i}"; } } } } if (string.IsNullOrEmpty(client.HIRMS)) { client.HIRMS = TAN; } else { if (!TANf.Contains(client.HIRMS)) { throw new Exception($"Invalid HIRMS/Tan-Mode {client.HIRMS} detected. Please choose one of the allowed modes: {TANf}"); } } client.HIRMSf = TANf; // Parsing TAN processes if (!string.IsNullOrEmpty(client.HIRMS)) { Parse_TANProcesses(client, bpd); } } } if (segment.Name == "HNHBK") { var ID = Parse_String(segment.Payload, "+1+", ":1"); client.HNHBK = ID; } if (segment.Name == "HISYN") { client.SystemId = segment.Payload; Log.Write("Customer System ID: " + client.SystemId); } if (segment.Name == "HNHBS") { if (segment.Payload == null || segment.Payload == "0") { client.HNHBS = 2; } else { client.HNHBS = Convert.ToInt32(segment.Payload) + 1; } } if (segment.Name == "HISALS") { client.HISALS = segment.Version; } if (segment.Name == "HITANS") { var hitans = (HITANS)segment; if (client.HIRMS == null) { // Die höchste HKTAN-Version auswählen, welche in den erlaubten TAN-Verfahren (3920) enthalten ist. var tanProcessesHirms = client.HIRMSf.Split(';').Select(tp => Convert.ToInt32(tp)); if (hitans.TanProcesses.Select(tp => tp.TanCode).Intersect(tanProcessesHirms).Any()) { client.HITANS = segment.Version; } } else { if (hitans.TanProcesses.Any(tp => tp.TanCode == Convert.ToInt32(client.HIRMS))) { client.HITANS = segment.Version; } } } if (segment.Name == "HITAN") { // HITAN:5:7:3+S++8578-06-23-13.22.43.709351 // HITAN:5:7:4+4++8578-06-23-13.22.43.709351+Bitte Auftrag in Ihrer App freigeben. var match = Regex.Match(segment.Payload, @"\w+\+.*?\+(?<ref>[^\+]+)(\+)?"); if (!match.Success) { throw new ArgumentException($"Could not parse HITAN: {segment}"); } client.HITAN = match.Groups["ref"].Value; } if (segment.Name == "HIKAZS") { if (client.HIKAZS == 0) { client.HIKAZS = segment.Version; } else { if (segment.Version > client.HIKAZS) { client.HIKAZS = segment.Version; } } } if (segment.Name == "HISPAS") { if (segment.Payload.Contains("pain.001.001.03")) { client.HISPAS = 1; } else if (segment.Payload.Contains("pain.001.002.03")) { client.HISPAS = 2; } else if (segment.Payload.Contains("pain.001.003.03")) { client.HISPAS = 3; } if (client.HISPAS == 0) { client.HISPAS = 3; // -> Fallback. Most banks accept the newest pain version } } } // Fallback if HIKAZS is not delivered by BPD (eg. Postbank) if (client.HIKAZS == 0) { client.HIKAZS = 0; } return(result); } catch (Exception ex) { Log.Write(ex.ToString()); throw new InvalidOperationException($"Software error.", ex); } }