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": "*"