From 400a41760bcd2f91ed92ac0ae0c5ffa357cb0801 Mon Sep 17 00:00:00 2001 From: Andrey Shabarshov Date: Wed, 30 Mar 2022 12:34:20 +0100 Subject: [PATCH] Payment transaction fixed. --- QRBee.Core/Data/ClientCardData.cs | 18 ++-- QRBee.Core/Data/ClientToMerchantResponse.cs | 36 ++++--- QRBee.Core/Data/MerchantToClientRequest.cs | 30 +++--- QRBee.Core/Data/PaymentResponse.cs | 2 +- QRBee/QRBee/ViewModels/ClientPageViewModel.cs | 44 ++++---- .../QRBee/ViewModels/MerchantPageViewModel.cs | 41 ++++--- QRBeeApi/Services/Database/IStorage.cs | 6 ++ QRBeeApi/Services/Database/Storage.cs | 11 +- QRBeeApi/Services/QRBeeAPIService.cs | 102 +++++++++++------- QRBeeApi/appsettings.json | 4 +- 10 files changed, 167 insertions(+), 127 deletions(-) diff --git a/QRBee.Core/Data/ClientCardData.cs b/QRBee.Core/Data/ClientCardData.cs index f2a0d41..1416b23 100644 --- a/QRBee.Core/Data/ClientCardData.cs +++ b/QRBee.Core/Data/ClientCardData.cs @@ -4,8 +4,8 @@ { public string TransactionId { get; set; } public string CardNumber { get; set; } - public string ExpirationDateMMYY { get; set; } - public string ValidFrom { get; set; } + public string ExpirationDateYYYYMM { get; set; } + public string ValidFromYYYYMM { get; set; } public string CardHolderName { get; set; } public string CVC { get; set; } public int? IssueNo { get; set; } @@ -15,7 +15,7 @@ /// WARNING: this should always be encrypted and never transmitted in clear text form. /// /// Converted string - public string AsString() => $"{TransactionId}|{CardNumber}|{ExpirationDateMMYY}|{ValidFrom}|{CardHolderName}|{CVC}|{IssueNo ?? 0}"; + public string AsString() => $"{TransactionId}|{CardNumber}|{ExpirationDateYYYYMM}|{ValidFromYYYYMM}|{CardHolderName}|{CVC}|{IssueNo ?? 0}"; public static ClientCardData FromString(string input) { @@ -27,12 +27,12 @@ var res = new ClientCardData() { - TransactionId = s[0], - CardNumber = s[1], - ExpirationDateMMYY = s[2], - ValidFrom = s[3], - CardHolderName = s[4], - CVC = s[5] + TransactionId = s[0], + CardNumber = s[1], + ExpirationDateYYYYMM = s[2], + ValidFromYYYYMM = s[3], + CardHolderName = s[4], + CVC = s[5] }; if (!string.IsNullOrWhiteSpace(s[6])) diff --git a/QRBee.Core/Data/ClientToMerchantResponse.cs b/QRBee.Core/Data/ClientToMerchantResponse.cs index 53d0126..5c3a84f 100644 --- a/QRBee.Core/Data/ClientToMerchantResponse.cs +++ b/QRBee.Core/Data/ClientToMerchantResponse.cs @@ -3,22 +3,17 @@ public record ClientToMerchantResponse { public MerchantToClientRequest MerchantRequest { get; set; } - - public string ClientId { get; set; } - - public DateTime TimeStampUTC { get; set; } - - public string ClientSignature { get; set; } - - public string EncryptedClientCardData { get; set; } + public string ClientId { get; set; } + public DateTime TimeStampUTC { get; set; } + public string ClientSignature { get; set; } + public string EncryptedClientCardData { get; set; } /// /// Convert ClientToMerchantResponse to string to be used as QR Code source (along with client signature) /// /// Converted string - public string AsQRCodeString() => $"{ClientId}|{TimeStampUTC:O}|{ClientSignature}"; - - public string AsDataForSignature() => $"{ClientId}|{TimeStampUTC:O}|{MerchantRequest.AsQRCodeString()}"; + public string AsQRCodeString() => $"{ClientId}|{TimeStampUTC:yyyy-MM-dd:HH.mm.ss.ffff}|{ClientSignature}|{EncryptedClientCardData}"; + public string AsDataForSignature() => $"{ClientId}|{TimeStampUTC:yyyy-MM-dd:HH.mm.ss.ffff}|{MerchantRequest.AsQRCodeString()}"; /// /// Convert from string @@ -26,19 +21,26 @@ /// A string representation of ClientToMerchantResponse /// Converted string /// Thrown if the input string is incorrect - public static ClientToMerchantResponse FromString(string input) + public static ClientToMerchantResponse FromString(string input, MerchantToClientRequest merchantRequest) { + if (merchantRequest == null) + throw new ArgumentNullException(nameof(merchantRequest)); + if ( string.IsNullOrWhiteSpace(merchantRequest.MerchantSignature) ) + throw new ApplicationException("Request is not signed by a merchant"); + var s = input.Split('|'); - if (s.Length < 3) + if (s.Length < 4) { - throw new ApplicationException($"Expected 3 or more elements but got {s.Length}"); + throw new ApplicationException($"Expected 4 elements but got {s.Length}"); } var res = new ClientToMerchantResponse() { - ClientId = s[0], - TimeStampUTC = DateTime.ParseExact(s[1], "O", null), - ClientSignature = s[2] + ClientId = s[0], + TimeStampUTC = DateTime.ParseExact(s[1], "yyyy-MM-dd:HH.mm.ss.ffff", null), + ClientSignature = s[2], + EncryptedClientCardData = s[3], + MerchantRequest = merchantRequest }; return res; diff --git a/QRBee.Core/Data/MerchantToClientRequest.cs b/QRBee.Core/Data/MerchantToClientRequest.cs index 68ce3d8..3ce726b 100644 --- a/QRBee.Core/Data/MerchantToClientRequest.cs +++ b/QRBee.Core/Data/MerchantToClientRequest.cs @@ -4,25 +4,19 @@ namespace QRBee.Core.Data { public record MerchantToClientRequest { - public string MerchantId { get; set; } - + public string MerchantId { get; set; } public string MerchantTransactionId { get; set; } - - public string Name { get; set; } - - public decimal Amount { get; set; } - - public DateTime TimeStampUTC { get; set; } - - public string MerchantSignature { get; set; } + public string Name { get; set; } + public decimal Amount { get; set; } + public DateTime TimeStampUTC { get; set; } + public string MerchantSignature { get; set; } /// /// Convert MerchantToClientRequest to string to be used as QR Code source (along with merchant signature) /// /// String conversion - public string AsQRCodeString() => $"{AsDataForSignature()}|{MerchantSignature}"; - - public string AsDataForSignature() => $"{MerchantId}|{MerchantTransactionId}|{Name}|{Amount.ToString("0.00", CultureInfo.InvariantCulture)}|{TimeStampUTC:O}"; + public string AsQRCodeString() => $"{AsDataForSignature()}|{MerchantSignature}"; + public string AsDataForSignature() => $"{MerchantId}|{MerchantTransactionId}|{Name}|{Amount.ToString("0.00", CultureInfo.InvariantCulture)}|{TimeStampUTC:yyyy-MM-dd:HH.mm.ss.ffff}"; /// /// Convert from string @@ -40,12 +34,12 @@ namespace QRBee.Core.Data var res = new MerchantToClientRequest { - MerchantId = s[0], + MerchantId = s[0], MerchantTransactionId = s[1], - Name = s[2], - Amount = Convert.ToDecimal(s[3], CultureInfo.InvariantCulture), - TimeStampUTC = DateTime.ParseExact(s[4],"O",null), - MerchantSignature = s[5] + Name = s[2], + Amount = Convert.ToDecimal(s[3], CultureInfo.InvariantCulture), + TimeStampUTC = DateTime.ParseExact(s[4], "yyyy-MM-dd:HH.mm.ss.ffff", null), + MerchantSignature = s[5] }; diff --git a/QRBee.Core/Data/PaymentResponse.cs b/QRBee.Core/Data/PaymentResponse.cs index c41563c..dae046a 100644 --- a/QRBee.Core/Data/PaymentResponse.cs +++ b/QRBee.Core/Data/PaymentResponse.cs @@ -18,6 +18,6 @@ /// Convert PaymentResponse to string to be encrypted and transmitted back to merchant /// /// Converted string - public string AsDataForSignature() => $"{ServerTransactionId}|{PaymentRequest.AsString()}|{ServerTimeStampUTC:O}|{Success}|{RejectReason}"; + public string AsDataForSignature() => $"{ServerTransactionId}|{PaymentRequest.AsString()}|{ServerTimeStampUTC:yyyy-MM-dd:HH.mm.ss.ffff}|{Success}|{RejectReason}"; } } diff --git a/QRBee/QRBee/ViewModels/ClientPageViewModel.cs b/QRBee/QRBee/ViewModels/ClientPageViewModel.cs index d613e5e..e36f22f 100644 --- a/QRBee/QRBee/ViewModels/ClientPageViewModel.cs +++ b/QRBee/QRBee/ViewModels/ClientPageViewModel.cs @@ -61,10 +61,10 @@ namespace QRBee.ViewModels if (result == null) return; - _merchantToClientRequest = MerchantToClientRequest.FromString(result); - Amount = $"{_merchantToClientRequest.Amount:N2}"; + _merchantToClientRequest = MerchantToClientRequest.FromString(result); + Amount = $"{_merchantToClientRequest.Amount:N2}"; IsAcceptDenyButtonVisible = true; - IsScanButtonVisible = false; + IsScanButtonVisible = false; } catch (Exception) { @@ -148,36 +148,40 @@ namespace QRBee.ViewModels public async void OnAcceptQrCommand(object obj) { - var answer = await Application.Current.MainPage.DisplayAlert("Confirmation", "Would you like to accept the offer?", "Yes", "No"); - if (!answer) return; + var answer = await Application.Current.MainPage.DisplayAlert("Confirmation", "Would you like to accept the offer?", "Yes", "No"); + if (!answer) + return; + var settings = _localSettings.LoadSettings(); + var response = new ClientToMerchantResponse { - ClientId = settings.ClientId, - TimeStampUTC = DateTime.UtcNow, - MerchantRequest = _merchantToClientRequest, + ClientId = settings.ClientId, + TimeStampUTC = DateTime.UtcNow, + MerchantRequest = _merchantToClientRequest, EncryptedClientCardData = EncryptCardData(settings, _merchantToClientRequest.MerchantTransactionId) }; - var clientSignature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature())); - response.ClientSignature = Convert.ToBase64String(clientSignature); - QrCode = response.AsQRCodeString(); - IsQrVisible = true; + var clientSignature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature())); + response.ClientSignature = Convert.ToBase64String(clientSignature); + + QrCode = response.AsQRCodeString(); + IsQrVisible = true; IsAcceptDenyButtonVisible = false; - IsScanButtonVisible = true; + IsScanButtonVisible = true; } private string EncryptCardData(Settings settings, string transactionId) { var clientCardData = new ClientCardData { - TransactionId = transactionId, - CardNumber = settings.CardNumber, - ExpirationDateMMYY = settings.ExpirationDate, - ValidFrom = settings.ValidFrom, - CardHolderName = settings.CardHolderName, - CVC = settings.CVC, - IssueNo = settings.IssueNo + TransactionId = transactionId, + CardNumber = settings.CardNumber, + ExpirationDateYYYYMM = string.IsNullOrWhiteSpace(settings.ExpirationDate) ? null : DateTime.Parse(settings.ExpirationDate).ToString("yyyy-MM"), + ValidFromYYYYMM = string.IsNullOrWhiteSpace(settings.ValidFrom) ? null : DateTime.Parse(settings.ValidFrom).ToString("yyyy-MM"), + CardHolderName = settings.CardHolderName, + CVC = settings.CVC, + IssueNo = settings.IssueNo }; var bytes = _securityService.Encrypt(Encoding.UTF8.GetBytes(clientCardData.AsString()),_securityService.APIServerCertificate); diff --git a/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs b/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs index a9f32f5..93729ee 100644 --- a/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs +++ b/QRBee/QRBee/ViewModels/MerchantPageViewModel.cs @@ -24,38 +24,51 @@ namespace QRBee.ViewModels public MerchantPageViewModel(IQRScanner scanner, ILocalSettings settings, ISecurityService securityService) { - _scanner = scanner; - _settings = settings; - _securityService = securityService; - ScanCommand = new Command(OnScanButtonClicked); + _scanner = scanner; + _settings = settings; + _securityService = securityService; + ScanCommand = new Command(OnScanButtonClicked); GenerateQrCommand = new Command(OnGenerateQrClicked); var localSettings = DependencyService.Resolve(); - Name = localSettings.LoadSettings().Name; + Name = localSettings.LoadSettings().Name; } private async void OnScanButtonClicked(object sender) { try { - var result = await _scanner.ScanQR(); - if (result == null) + var result = await _scanner.ScanQR(); + if (string.IsNullOrWhiteSpace(result)) return; - var client = new HttpClient(GetInsecureHandler()); + var clientResponse = ClientToMerchantResponse.FromString(result, _lastRequest); - var service = new Core.Client.Client(_settings.QRBeeApiUrl, client); - var clientResponse = ClientToMerchantResponse.FromString(result); + if (string.IsNullOrWhiteSpace(clientResponse.ClientSignature)) + throw new ApplicationException("Request is not signed by a client"); + if (string.IsNullOrWhiteSpace(clientResponse.EncryptedClientCardData)) + throw new ApplicationException("Request does not contain client's card data"); - clientResponse.MerchantRequest = _lastRequest; - var paymentRequest = new PaymentRequest + var paymentRequest = new PaymentRequest { - ClientResponse = clientResponse + ClientResponse = clientResponse }; //QrCode = null; IsVisible = false; - var response = await service.PayAsync(paymentRequest); + // ------------------------------------- SEND PAYMENT REQUEST ------------------------------------------ + // + // ____ _ __ ____ __ _____ _ _ _____ + // | _ \ / \\ \ / / \/ | ____| \ | |_ _| + // | |_) / _ \\ V /| |\/| | _| | \| | | | + // | __/ ___ \| | | | | | |___| |\ | | | + // |_| /_/ \_\_| |_| |_|_____|_| \_| |_| + // + // + var apiService = new Core.Client.Client(_settings.QRBeeApiUrl, new HttpClient(GetInsecureHandler())); + var response = await apiService.PayAsync(paymentRequest); + // + // ----------------------------------------------------------------------------------------------------- if (response.Success) { diff --git a/QRBeeApi/Services/Database/IStorage.cs b/QRBeeApi/Services/Database/IStorage.cs index cdc4527..2ad371a 100644 --- a/QRBeeApi/Services/Database/IStorage.cs +++ b/QRBeeApi/Services/Database/IStorage.cs @@ -31,6 +31,12 @@ /// Information to be inserted Task PutTransactionInfo(TransactionInfo info); + /// + /// Try to find if the Transaction already exists in the database + /// + /// parameter by which to find TransactionInfo + /// null if transaction doesn't exist or TransactionInfo + Task TryGetTransactionInfoByTransactionId(string id); /// /// Retrieve transaction information from database /// diff --git a/QRBeeApi/Services/Database/Storage.cs b/QRBeeApi/Services/Database/Storage.cs index 04fa2d3..3feae8d 100644 --- a/QRBeeApi/Services/Database/Storage.cs +++ b/QRBeeApi/Services/Database/Storage.cs @@ -71,7 +71,7 @@ namespace QRBee.Api.Services.Database { var collection = _database.GetCollection("Transactions"); - var transaction = await TryGetTransactionInfo(info.Id); + var transaction = await TryGetTransactionInfoByTransactionId(info.Id); if (transaction == null) { @@ -83,12 +83,7 @@ namespace QRBee.Api.Services.Database _logger.LogInformation($"Found transaction with ClientId: {info.Id}"); } - /// - /// Try to find if the Transaction already exists in the database - /// - /// parameter by which to find TransactionInfo - /// null if transaction doesn't exist or TransactionInfo - private async Task TryGetTransactionInfo(string id) + public async Task TryGetTransactionInfoByTransactionId(string id) { var collection = _database.GetCollection("Transactions"); using var cursor = await collection.FindAsync($"{{ _id: \"{id}\" }}"); @@ -102,7 +97,7 @@ namespace QRBee.Api.Services.Database public async Task GetTransactionInfoByTransactionId(string id) { - var transaction = await TryGetTransactionInfo(id); + var transaction = await TryGetTransactionInfoByTransactionId(id); return transaction ?? throw new ApplicationException($"Transaction with Id: {id} not found."); } diff --git a/QRBeeApi/Services/QRBeeAPIService.cs b/QRBeeApi/Services/QRBeeAPIService.cs index 0cffffe..de25b57 100644 --- a/QRBeeApi/Services/QRBeeAPIService.cs +++ b/QRBeeApi/Services/QRBeeAPIService.cs @@ -14,21 +14,23 @@ namespace QRBee.Api.Services /// public class QRBeeAPIService: IQRBeeAPI { - private readonly IStorage _storage; - private readonly ISecurityService _securityService; + private readonly IStorage _storage; + private readonly ISecurityService _securityService; private readonly IPrivateKeyHandler _privateKeyHandler; - private readonly IPaymentGateway _paymentGateway; - private static readonly object _lock = new (); + private readonly IPaymentGateway _paymentGateway; + private readonly ILogger _logger; + private static readonly object _lock = new (); private const int MaxNameLength = 512; private const int MaxEmailLength = 512; - public QRBeeAPIService(IStorage storage, ISecurityService securityService, IPrivateKeyHandler privateKeyHandler, IPaymentGateway paymentGateway) + public QRBeeAPIService(IStorage storage, ISecurityService securityService, IPrivateKeyHandler privateKeyHandler, IPaymentGateway paymentGateway, ILogger logger) { - _storage = storage; - _securityService = securityService; + _storage = storage; + _securityService = securityService; _privateKeyHandler = privateKeyHandler; - _paymentGateway = paymentGateway; + _paymentGateway = paymentGateway; + _logger = logger; Init(_privateKeyHandler); } @@ -48,14 +50,14 @@ namespace QRBee.Api.Services ValidateRegistration(request); - var info = Convert(request); - - var clientId = await _storage.PutUserInfo(info); - + var info = Convert(request); + + var clientId = await _storage.PutUserInfo(info); + using var rsa = LoadRsaPublicKey(request.CertificateRequest.RsaPublicKey); - var bytes = rsa.ExportRSAPublicKey(); - - var clientCertificate = _securityService.CreateCertificate(clientId,bytes); + var bytes = rsa.ExportRSAPublicKey(); + + var clientCertificate = _securityService.CreateCertificate(clientId,bytes); var convertedClientCertificate = Convert(clientCertificate, clientId,request.Email); await _storage.InsertCertificate(convertedClientCertificate); @@ -81,9 +83,9 @@ namespace QRBee.Api.Services throw new NullReferenceException(); } - var name = request.Name; - var email = request.Email; - var dateOfBirth = request.DateOfBirth; + var name = request.Name; + var email = request.Email; + var dateOfBirth = request.DateOfBirth; var certificateRequest = request.CertificateRequest; if (string.IsNullOrEmpty(name) || name.All(char.IsLetter) == false || name.Length >= MaxNameLength) @@ -126,10 +128,23 @@ namespace QRBee.Api.Services public async Task Pay(PaymentRequest value) { + + // --------------------------------- RECEIVE PAYMENT REQUEST -------------------------------------- + // + // ____ _ __ ____ __ _____ _ _ _____ + // | _ \ / \\ \ / / \/ | ____| \ | |_ _| + // | |_) / _ \\ V /| |\/| | _| | \| | | | + // | __/ ___ \| | | | | | |___| |\ | | | + // |_| /_/ \_\_| |_| |_|_____|_| \_| |_| + // + // + try { //1. Check payment request parameters for validity ValidateTransaction(value); + var tid = value.ClientResponse.MerchantRequest.MerchantTransactionId; + _logger.LogInformation($"Transaction=\"{tid}\" Pre-validated"); //2. Check client signature var t2 = CheckSignature( @@ -144,22 +159,25 @@ namespace QRBee.Api.Services value.ClientResponse.MerchantRequest.MerchantId); //4. Check if transaction was already processed - var t4 = CheckTransaction(value.ClientResponse.MerchantRequest.MerchantTransactionId); + var t4 = CheckTransaction(tid); //Parallel task execution await Task.WhenAll(t2, t3, t4); + _logger.LogInformation($"Transaction=\"{tid}\" Fully validated"); //5. Decrypt client card data var clientCardData = DecryptClientData(value.ClientResponse.EncryptedClientCardData); //6. Check client card data for validity - await CheckClientCardData(clientCardData); + await CheckClientCardData(clientCardData, value.ClientResponse.MerchantRequest.MerchantTransactionId); + _logger.LogInformation($"Transaction=\"{tid}\" Client card data validated"); //7. Register preliminary transaction record with expiry of one minute var info = Convert(value); info.Status = TransactionInfo.TransactionStatus.Pending; await _storage.PutTransactionInfo(info); + _logger.LogInformation($"Transaction=\"{tid}\" initialized"); //8. Send client card data to a payment gateway var res = await _paymentGateway.Payment(info, clientCardData); @@ -175,6 +193,7 @@ namespace QRBee.Api.Services info.RejectReason = res.ErrorMessage; } await _storage.UpdateTransaction(info); + _logger.LogInformation($"Transaction=\"{tid}\" complete Status=\"{info.Status}\""); //10. Make response for merchant var response = MakePaymentResponse(value, info.TransactionId ?? "", info.Status==TransactionInfo.TransactionStatus.Succeeded, info.RejectReason); @@ -194,14 +213,15 @@ namespace QRBee.Api.Services var response = new PaymentResponse { ServerTransactionId = transactionId, - PaymentRequest = value, - ServerTimeStampUTC = DateTime.UtcNow, - Success = result, - RejectReason = errorMessage, + PaymentRequest = value, + ServerTimeStampUTC = DateTime.UtcNow, + Success = result, + RejectReason = errorMessage, }; - var signature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature())); + var signature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature())); response.ServerSignature = System.Convert.ToBase64String(signature); + return response; } @@ -212,10 +232,10 @@ namespace QRBee.Api.Services throw new NullReferenceException(); } - var clientId = request.ClientResponse.ClientId; - var merchantId = request.ClientResponse.MerchantRequest.MerchantId; + var clientId = request.ClientResponse.ClientId; + var merchantId = request.ClientResponse.MerchantRequest.MerchantId; var transactionId = request.ClientResponse.MerchantRequest.MerchantTransactionId; - var amount = request.ClientResponse.MerchantRequest.Amount; + var amount = request.ClientResponse.MerchantRequest.Amount; if (clientId == null || merchantId == null || transactionId == null) { @@ -230,7 +250,7 @@ namespace QRBee.Api.Services private async Task CheckSignature(string data,string signature, string id) { - var info = await _storage.GetCertificateInfoByUserId(id); + var info = await _storage.GetCertificateInfoByUserId(id); var certificate = _securityService.Deserialize(info.Certificate); var check = _securityService.Verify( @@ -246,8 +266,8 @@ namespace QRBee.Api.Services private async Task CheckTransaction(string transactionId) { - var info = await _storage.GetTransactionInfoByTransactionId(transactionId); - switch (info.Status) + var info = await _storage.TryGetTransactionInfoByTransactionId(transactionId); + switch (info?.Status) { case TransactionInfo.TransactionStatus.Succeeded: throw new ApplicationException($"Transaction with Id: {transactionId} was already made."); @@ -262,18 +282,24 @@ namespace QRBee.Api.Services private ClientCardData DecryptClientData(string encryptedClientCardData) { - var info = System.Convert.FromBase64String(encryptedClientCardData); + var info = System.Convert.FromBase64String(encryptedClientCardData); var bytes = _securityService.Decrypt(info); - var s = Encoding.UTF8.GetString(bytes); + var s = Encoding.UTF8.GetString(bytes); + return ClientCardData.FromString(s); } - private async Task CheckClientCardData(ClientCardData data) + private async Task CheckClientCardData(ClientCardData data, string merchantTransactionId) { - var transactionId = data.TransactionId; - var expirationDate = DateTime.Parse(data.ExpirationDateMMYY); - var validFrom = DateTime.Parse(data.ValidFrom); - var holderName = data.CardHolderName; + if ( data.TransactionId != merchantTransactionId) + throw new ApplicationException($"Transaction IDs don't match"); + + //_logger.LogInformation(data.AsString()); + + var transactionId = data.TransactionId; + var expirationDate = string.IsNullOrWhiteSpace(data.ExpirationDateYYYYMM) ? default : DateTime.ParseExact(data.ExpirationDateYYYYMM, "yyyy-MM", null); + var validFrom = string.IsNullOrWhiteSpace(data.ValidFromYYYYMM) ? default : DateTime.ParseExact(data.ValidFromYYYYMM, "yyyy-MM", null); + var holderName = data.CardHolderName; await CheckTransaction(transactionId); diff --git a/QRBeeApi/appsettings.json b/QRBeeApi/appsettings.json index 93e0a67..16535b6 100644 --- a/QRBeeApi/appsettings.json +++ b/QRBeeApi/appsettings.json @@ -12,8 +12,8 @@ "Logging": { "LogLevel": { - "Default": "Trace" - //"Microsoft.AspNetCore": "Debug" + "Default": "Trace", + "Microsoft.AspNetCore": "Information" } }, "AllowedHosts": "*"