using System; using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Text; using System.Threading.Tasks; using classes; using MySqlConnector; using Newtonsoft.Json; using Model.ResponseModel; using Model; using System.Data; //Summary //Settle Payments with the sources //Summary public class PaymentService { MySqlConnection _con; Logger logger; string baseUrl = string.Empty; public PaymentService(DbUserModel dbUser) { string connectionString = $@"server={dbUser.host};userid={dbUser.username};password={dbUser.password};database={dbUser.dbInstanceIdentifier};convert zero datetime=True"; _con = new MySqlConnection(connectionString); logger = new Logger(dbUser); var secretManager = new SecretsManagerService(); baseUrl = secretManager.GetAPIEndPoint().IFORCE_ENATIS_API_BASE_URL; } public bool LoadInfringements(string statement, List iForceInfridgments, List eNatisInfridgments) { if (_con.State == ConnectionState.Closed) _con.Open(); var cmd = new MySqlCommand(); cmd.Connection = _con; cmd.CommandText = statement; cmd.ExecuteNonQuery(); MySqlDataReader reader = cmd.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) { if (string.Equals(reader["strInfringementSource"].ToString().ToUpper(), "IFORCE"))//name for our iforce source { iForceInfridgments.Add(new InfringementPayment { InfringementID = Convert.ToInt32(reader["InfringementID"]), TransactionId = Convert.ToInt32(reader["TransactionID"]), NoticeNumber = reader["strInfringementNumber"].ToString(), strStatus = reader["strStatus"].ToString(), PaymentAmount = Convert.ToDouble(reader["strAmount"]), PaymentDate = reader["dtPaid"].ToString(), IssuingAuthority = reader["strIssuingAuthority"].ToString(), ReceiptNumber = reader["strRecieptNumber"].ToString(), PaymentProvider = 13,//iveri only for now IntSettlementTries = Convert.ToInt32(reader["intSettlementTries"]), }); } else { eNatisInfridgments.Add(new InfringementPayment { InfringementID = Convert.ToInt32(reader["InfringementID"]), TransactionId = Convert.ToInt32(reader["TransactionID"]), NoticeNumber = reader["strInfringementNumber"].ToString(), strStatus = reader["strStatus"].ToString(), PaymentAmount = Convert.ToDouble(reader["strAmount"]), PaymentDate = reader["dtPaid"].ToString(), IssuingAuthority = reader["strIssuingAuthority"].ToString(), ReceiptNumber = reader["strRecieptNumber"].ToString(), PaymentProvider = 13,// reader["strProviderName"].ToString(), IntSettlementTries = Convert.ToInt32(reader["intSettlementTries"]), }); } } reader.Close(); return true; } reader.Close(); return false; } public async Task ProcessENatisPayments(List infridgments, List problemInfridgments) { string statement = ""; var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = Helper.ServerCertificateCustomValidation }; var client = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) }; string jsonInfringement = ""; StringContent content; HttpResponseMessage eNatisResponse = null; ; string body = ""; if (_con.State == ConnectionState.Closed) _con.Open(); var cmd = new MySqlCommand(); cmd.Connection = _con; foreach (var row in infridgments) { jsonInfringement = JsonConvert.SerializeObject(new PayEnatisInfringement { infringementNoticeNumber = row.NoticeNumber, amount = row.PaymentAmount }); content = new StringContent(jsonInfringement, Encoding.UTF8, "application/json"); try { eNatisResponse = await client.PostAsync("infringement/payinfringement", content); body = await eNatisResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { logger.WriteLog("Cronjob Payment To Enatis", ex.Message, $"Transaction: {row.TransactionId}", "TMT"); continue; } logger.WriteLog("Cronjob Payment To Enatis", jsonInfringement, $"Transaction: {row.TransactionId}", "TMT"); if (eNatisResponse.StatusCode == HttpStatusCode.OK) { //statement = $"Update transaction SET intPaid = 'SETTLED', strStatus = 'Source Approved Payment' ,dtLastEdit = NOW() WHERE TransactionID = '{row.TransactionId}'"; // cmd.CommandText = statement; //cmd.ExecuteNonQuery(); var response = JsonConvert.DeserializeObject(body); statement = $"UPDATE infringement set strStatus = 'Source Approved Payment', strSourceResponse = 'PayResult: {response.payResult}. InvoiceNumber: {response.invoiceNumber} ReceiptNumber: {response.receiptNumber}' WHERE InfringementID = {row.InfringementID}"; } else { int settlementTries = row.IntSettlementTries + 1; var response = JsonConvert.DeserializeObject(body); string errorDescription = Helper.CleanInput(response.message); logger.WriteLog("Cronjob Payment To Enatis", $"StatusCode: {response.statusCode}. Description: {errorDescription}", $"Transaction: {row.TransactionId}", "TMT"); //status already failed here statement = $"UPDATE infringement set intSettlementTries = {settlementTries}, strSourceResponse = 'StatusCode: {response.statusCode}. Description: {errorDescription}' WHERE InfringementID = {row.InfringementID}"; if (settlementTries > 3) { problemInfridgments.Add(row); } } cmd.CommandText = statement; cmd.ExecuteNonQuery(); } return true; } public async Task ProcessENatisPayments(List infridgments) { string statement = ""; var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = Helper.ServerCertificateCustomValidation }; var client = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) }; string jsonInfringement = ""; StringContent content; HttpResponseMessage eNatisResponse = null; string body = ""; if (_con.State == ConnectionState.Closed) _con.Open(); var cmd = new MySqlCommand(); cmd.Connection = _con; foreach (var row in infridgments) { jsonInfringement = JsonConvert.SerializeObject(new PayEnatisInfringement { infringementNoticeNumber = row.NoticeNumber, amount = row.PaymentAmount }); content = new StringContent(jsonInfringement, Encoding.UTF8, "application/json"); try { eNatisResponse = await client.PostAsync("infringement/payinfringement", content); body = await eNatisResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { logger.WriteLog("Cronjob Payment To Enatis", ex.Message, $"Transaction: {row.TransactionId}", "TMT"); continue; } if (eNatisResponse.StatusCode == HttpStatusCode.OK) { //commented out on Loyed's recommendation after call with SO //statement = $"Update transaction SET intPaid = 'SETTLED', strStatus = 'Source Approved Payment', dtLastEdit = NOW() WHERE TransactionID = '{row.TransactionId}'"; //cmd.CommandText = statement; //cmd.ExecuteNonQuery(); var response = JsonConvert.DeserializeObject(body); statement = $"UPDATE infringement set strStatus = 'Source Approved Payment', strSourceResponse = 'PayResult: {response.payResult}. InvoiceNumber: {response.invoiceNumber} ReceiptNumber: {response.receiptNumber}' WHERE InfringementID = {row.InfringementID}"; } else { var response = JsonConvert.DeserializeObject(body); string errorDescription = Helper.CleanInput(response.message); logger.WriteLog("Cronjob Payment To Enatis", $"StatusCode: {response.statusCode}. Description: {errorDescription}", $"Transaction: {row.TransactionId}", "TMT"); //Removed premature status update // statement = $"Update transaction SET strStatus = 'Source Failed Payment', dtLastEdit = NOW() WHERE TransactionID = '{row.TransactionId}'"; // cmd.CommandText = statement; // cmd.ExecuteNonQuery(); //infringement details can be followed down using the Transaction statement = $"UPDATE infringement set intSettlementTries = 1, strStatus = 'Source Failed Payment', strSourceResponse = 'StatusCode: {response.statusCode}. Description: {errorDescription}' WHERE InfringementID = {row.InfringementID}"; } cmd.CommandText = statement; cmd.ExecuteNonQuery(); } return true; } public async Task ProcessIForcePayments(List infridgments, List problemInfridgments) { string statement = ""; var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = Helper.ServerCertificateCustomValidation }; var client = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) }; StringContent content; HttpResponseMessage iForceResponse = null; string body = ""; if (_con.State == ConnectionState.Closed) _con.Open(); var cmd = new MySqlCommand(); cmd.Connection = _con; foreach (var row in infridgments) { var jsonInfringement = JsonConvert.SerializeObject(new PayIForceInfringement { freshFine = false, issuingAuthorityCode = row.IssuingAuthority, noticeNumber = row.NoticeNumber, paymentAmount = row.PaymentAmount, paymentDate = DateTime.Parse(row.PaymentDate).ToString("o"), paymentProvider = 13, terminalId = 0, //what goes here?? receiptNumber = row.ReceiptNumber }); content = new StringContent(jsonInfringement, Encoding.UTF8, "application/json"); try { iForceResponse = await client.PostAsync("IForce/registerpayment", content); body = await iForceResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { logger.WriteLog("Cronjob Payment To iForce", ex.Message, $"Transaction: {row.TransactionId}", "TMT"); continue; } logger.WriteLog("Cronjob Payment To iForce", jsonInfringement, $"Transaction: {row.TransactionId}", "TMT"); if (iForceResponse.StatusCode == HttpStatusCode.OK) { //removed update to setteled var response = JsonConvert.DeserializeObject(body); logger.WriteLog("Cronjob Payment To iForce", $"TransactionID: {response.transactionId}. ResultDescription: {response.resultDescription}", $"Transaction: {row.TransactionId}", "TMT"); statement = $"UPDATE infringement set strStatus = 'Source Approved Payment', strSourceResponse = 'TransactionID: {response.transactionId}. ResultDescription: {response.resultDescription}' WHERE InfringementID = {row.InfringementID}"; } else { int settlementTries = row.IntSettlementTries + 1; var response = JsonConvert.DeserializeObject(body); logger.WriteLog("Cronjob Payment To iForce", $"StatusCode: {response.statusCode}. Description: {response.message}", $"Transaction: {row.TransactionId}", "TMT"); // statement = $"Update transaction SET strStatus = 'Source Failed Payment', dtLastEdit = NOW() WHERE TransactionID = '{row.TransactionId}'"; // cmd.CommandText = statement; // cmd.ExecuteNonQuery(); statement = $"UPDATE infringement set intSettlementTries = {settlementTries}, strStatus = 'Source Failed Payment', strSourceResponse = 'StatusCode: {response.statusCode}. Description: {response.message}' WHERE InfringementID = {row.InfringementID}"; if (settlementTries > 3) { problemInfridgments.Add(row); } } cmd.CommandText = statement; cmd.ExecuteNonQuery(); } return true; } public async Task ProcessIForcePayments(List infridgments) { string statement = ""; var handler = new HttpClientHandler { ServerCertificateCustomValidationCallback = Helper.ServerCertificateCustomValidation }; var client = new HttpClient(handler) { BaseAddress = new Uri(baseUrl) }; string jsonInfringement = ""; StringContent content; HttpResponseMessage iForceResponse = null; string body = ""; if (_con.State == ConnectionState.Closed) _con.Open(); var cmd = new MySqlCommand(); cmd.Connection = _con; foreach (var row in infridgments) { jsonInfringement = JsonConvert.SerializeObject(new PayIForceInfringement { freshFine = true, issuingAuthorityCode = row.IssuingAuthority, noticeNumber = row.NoticeNumber, paymentAmount = row.PaymentAmount, paymentDate = DateTime.Parse(row.PaymentDate).ToString("o"), paymentProvider = 13, //row.PaymentProvider, terminalId = 0, //what goes here?? receiptNumber = row.ReceiptNumber }); content = new StringContent(jsonInfringement, Encoding.UTF8, "application/json"); try { iForceResponse = await client.PostAsync("IForce/registerpayment", content); body = await iForceResponse.Content.ReadAsStringAsync(); } catch (Exception ex) { logger.WriteLog("Cronjob Payment To iForce", ex.Message, $"Transaction: {row.TransactionId}", "TMT"); continue; } if (iForceResponse.StatusCode == HttpStatusCode.OK) { //statement = $"Update transaction SET intPaid = 'SETTLED', strStatus = 'Source Approved Payment', dtLastEdit = NOW() WHERE TransactionID = '{row.TransactionId}'"; //cmd.CommandText = statement; // cmd.ExecuteNonQuery(); var response = JsonConvert.DeserializeObject(body); // TODO check for response type eg 1 = Vehicle registration does not exists, 6 = Payment processed successfully logger.WriteLog("Cronjob Payment To iForce", $"TransactionID: {response.transactionId}. ResultDescription: {response.resultDescription}", $"Transaction: {row.TransactionId}", "TMT"); statement = $"UPDATE infringement set strStatus = 'Source Approved Payment', strSourceResponse = 'TransactionID: {response.transactionId}. ResultDescription: {response.resultDescription}' WHERE InfringementID = {row.InfringementID}"; } else { var response = JsonConvert.DeserializeObject(body); // TODO check for response type eg 1 = Vehicle registration does not exists, 6 = Payment processed successfully logger.WriteLog("Cronjob Payment To iForce", $"StatusCode: {response.statusCode}. Description: {response.message}", $"Transaction: {row.TransactionId}", "TMT"); statement = $"UPDATE infringement set intSettlementTries = 1, strStatus = 'Source Failed Payment', strSourceResponse = 'StatusCode: {response.statusCode}. Description: {response.message}' WHERE InfringementID = {row.InfringementID}"; cmd.CommandText = statement; cmd.ExecuteNonQuery(); //statement = $"UPDATE transaction set strStatus = 'Source Failed Payment' WHERE TransactionID = {row.TransactionId}"; } cmd.CommandText = statement; cmd.ExecuteNonQuery(); } return true; } }