mirror of
https://github.com/NecroticBamboo/QRBee.git
synced 2025-12-21 12:11:53 +00:00
Client response QR code size reduced. Cloud provider support.
This commit is contained in:
parent
1ab2706a53
commit
5c041da318
@ -16,7 +16,7 @@
|
|||||||
/// Convert ClientToMerchantResponse to string to be used as QR Code source (along with client signature)
|
/// Convert ClientToMerchantResponse to string to be used as QR Code source (along with client signature)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns> Converted string</returns>
|
/// <returns> Converted string</returns>
|
||||||
public string AsQRCodeString() => $"{AsDataForSignature()}|{ClientSignature}";
|
public string AsQRCodeString() => $"{ClientId}|{TimeStampUTC:O}|{ClientSignature}";
|
||||||
|
|
||||||
public string AsDataForSignature() => $"{ClientId}|{TimeStampUTC:O}|{MerchantRequest.AsQRCodeString()}";
|
public string AsDataForSignature() => $"{ClientId}|{TimeStampUTC:O}|{MerchantRequest.AsQRCodeString()}";
|
||||||
|
|
||||||
@ -31,15 +31,14 @@
|
|||||||
var s = input.Split('|');
|
var s = input.Split('|');
|
||||||
if (s.Length < 3)
|
if (s.Length < 3)
|
||||||
{
|
{
|
||||||
throw new ApplicationException("Expected 3 or more elements");
|
throw new ApplicationException($"Expected 3 or more elements but got {s.Length}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = new ClientToMerchantResponse()
|
var res = new ClientToMerchantResponse()
|
||||||
{
|
{
|
||||||
MerchantRequest = MerchantToClientRequest.FromString(string.Join("|", s.Skip(2))),
|
|
||||||
ClientId = s[0],
|
ClientId = s[0],
|
||||||
TimeStampUTC = DateTime.ParseExact(s[1], "O", null),
|
TimeStampUTC = DateTime.ParseExact(s[1], "O", null),
|
||||||
ClientSignature = s[3]
|
ClientSignature = s[2]
|
||||||
};
|
};
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|||||||
@ -33,9 +33,9 @@ namespace QRBee.Core.Data
|
|||||||
public static MerchantToClientRequest FromString(string input)
|
public static MerchantToClientRequest FromString(string input)
|
||||||
{
|
{
|
||||||
var s = input.Split('|');
|
var s = input.Split('|');
|
||||||
if (s.Length != 6)
|
if (s.Length < 6)
|
||||||
{
|
{
|
||||||
throw new ApplicationException("Expected 6 elements");
|
throw new ApplicationException($"Expected 6 elements but got {s.Length}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = new MerchantToClientRequest
|
var res = new MerchantToClientRequest
|
||||||
|
|||||||
@ -13,18 +13,6 @@
|
|||||||
/// Convert PaymentRequest to string
|
/// Convert PaymentRequest to string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Converted string</returns>
|
/// <returns>Converted string</returns>
|
||||||
public string AsString() => ClientResponse.AsQRCodeString();
|
public string AsString() => $"{ClientResponse.AsDataForSignature()}|{ClientResponse.ClientSignature}";
|
||||||
|
|
||||||
public static PaymentRequest FromString(string input)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(input))
|
|
||||||
{
|
|
||||||
throw new ApplicationException("The input is wrong!");
|
|
||||||
}
|
|
||||||
|
|
||||||
//doesn't work
|
|
||||||
var response = ClientToMerchantResponse.FromString(input);
|
|
||||||
return new PaymentRequest(){ClientResponse = response};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,7 @@ namespace QRBee.Droid
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.2.0.155")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.1.0.11")]
|
||||||
public partial class Resource
|
public partial class Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,13 @@ namespace QRBee.Droid.Services
|
|||||||
{
|
{
|
||||||
internal class LocalSettings : ILocalSettings
|
internal class LocalSettings : ILocalSettings
|
||||||
{
|
{
|
||||||
|
// Use https://10.0.2.2:7000 if you are running in emulator and API server on localhost
|
||||||
|
#if false
|
||||||
public string QRBeeApiUrl => "https://10.0.2.2:7000";
|
public string QRBeeApiUrl => "https://10.0.2.2:7000";
|
||||||
|
#else
|
||||||
|
public string QRBeeApiUrl => "https://qrbee-api.azurewebsites.net/";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
public async Task SaveSettings(Settings settings)
|
public async Task SaveSettings(Settings settings)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -17,6 +17,8 @@ namespace QRBee.ViewModels
|
|||||||
private decimal _amount;
|
private decimal _amount;
|
||||||
private string _qrCode;
|
private string _qrCode;
|
||||||
|
|
||||||
|
private MerchantToClientRequest _lastRequest;
|
||||||
|
|
||||||
public Command GenerateQrCommand { get; }
|
public Command GenerateQrCommand { get; }
|
||||||
public Command ScanCommand{ get; }
|
public Command ScanCommand{ get; }
|
||||||
|
|
||||||
@ -42,7 +44,13 @@ namespace QRBee.ViewModels
|
|||||||
var client = new HttpClient(GetInsecureHandler());
|
var client = new HttpClient(GetInsecureHandler());
|
||||||
|
|
||||||
var service = new Core.Client.Client(_settings.QRBeeApiUrl, client);
|
var service = new Core.Client.Client(_settings.QRBeeApiUrl, client);
|
||||||
var paymentRequest = PaymentRequest.FromString(result);
|
var clientResponse = ClientToMerchantResponse.FromString(result);
|
||||||
|
|
||||||
|
clientResponse.MerchantRequest = _lastRequest;
|
||||||
|
var paymentRequest = new PaymentRequest
|
||||||
|
{
|
||||||
|
ClientResponse = clientResponse
|
||||||
|
};
|
||||||
|
|
||||||
//QrCode = null;
|
//QrCode = null;
|
||||||
IsVisible = false;
|
IsVisible = false;
|
||||||
@ -152,7 +160,7 @@ namespace QRBee.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var trans = new MerchantToClientRequest
|
var request = new MerchantToClientRequest
|
||||||
{
|
{
|
||||||
MerchantId = _settings.LoadSettings().ClientId,
|
MerchantId = _settings.LoadSettings().ClientId,
|
||||||
MerchantTransactionId = Guid.NewGuid().ToString("D"),
|
MerchantTransactionId = Guid.NewGuid().ToString("D"),
|
||||||
@ -161,10 +169,12 @@ namespace QRBee.ViewModels
|
|||||||
TimeStampUTC = DateTime.UtcNow
|
TimeStampUTC = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
var merchantSignature = _securityService.Sign(Encoding.UTF8.GetBytes(trans.AsDataForSignature()));
|
var merchantSignature = _securityService.Sign(Encoding.UTF8.GetBytes(request.AsDataForSignature()));
|
||||||
trans.MerchantSignature = Convert.ToBase64String(merchantSignature);
|
request.MerchantSignature = Convert.ToBase64String(merchantSignature);
|
||||||
|
|
||||||
QrCode = trans.AsQRCodeString();
|
_lastRequest = request;
|
||||||
|
|
||||||
|
QrCode = request.AsQRCodeString();
|
||||||
IsVisible = true;
|
IsVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -124,7 +124,7 @@ namespace QRBee.ViewModels
|
|||||||
|
|
||||||
await _settings.SaveSettings(settings);
|
await _settings.SaveSettings(settings);
|
||||||
|
|
||||||
//if (!_privateKeyHandler.Exists())
|
if (!_privateKeyHandler.Exists())
|
||||||
{
|
{
|
||||||
_privateKeyHandler.GeneratePrivateKey(settings.Name);
|
_privateKeyHandler.GeneratePrivateKey(settings.Name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ namespace QRBee.Api.Services.Database
|
|||||||
|
|
||||||
[BsonId] public string? Id { get; set; }
|
[BsonId] public string? Id { get; set; }
|
||||||
public string? ClientId { get; set; }
|
public string? ClientId { get; set; }
|
||||||
|
public string? Email { get; set; }
|
||||||
public string? Certificate { get; set; }
|
public string? Certificate { get; set; }
|
||||||
public DateTime ServerTimeStamp { get; set; }
|
public DateTime ServerTimeStamp { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,7 +121,7 @@ namespace QRBee.Api.Services.Database
|
|||||||
throw new ApplicationException("Info Id is null.");
|
throw new ApplicationException("Info Id is null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var certificate = await TryGetCertificateInfo(info.Id);
|
var certificate = await TryGetCertificateInfoByEmail(info.Email ?? throw new ApplicationException("Email is not set"));
|
||||||
|
|
||||||
if (certificate == null)
|
if (certificate == null)
|
||||||
{
|
{
|
||||||
@ -130,7 +130,10 @@ namespace QRBee.Api.Services.Database
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogInformation($"Found certificate with ID: {info.Id}");
|
await collection.DeleteOneAsync($"{{ _id: \"{certificate.Id}\" }}");
|
||||||
|
await collection.ReplaceOneAsync($"{{ _id: \"{info.Id}\" }}", info, new ReplaceOptions() { IsUpsert = true });
|
||||||
|
|
||||||
|
_logger.LogInformation($"Found certificate with old ID: {certificate.Id} and replaced with new ID: {info.Id}");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +154,23 @@ namespace QRBee.Api.Services.Database
|
|||||||
return cursor.Current.FirstOrDefault();
|
return cursor.Current.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Try to find if the Certificate already exists in the database
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="email">parameter by which to find CertificateInfo</param>
|
||||||
|
/// <returns>null if certificate doesn't exist or CertificateInfo</returns>
|
||||||
|
private async Task<CertificateInfo?> TryGetCertificateInfoByEmail(string email)
|
||||||
|
{
|
||||||
|
var collection = _database.GetCollection<CertificateInfo>("Certificates");
|
||||||
|
using var cursor = await collection.FindAsync($"{{ Email: \"{email}\" }}");
|
||||||
|
if (!await cursor.MoveNextAsync())
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cursor.Current.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<CertificateInfo> GetCertificateInfoByCertificateId(string id)
|
public async Task<CertificateInfo> GetCertificateInfoByCertificateId(string id)
|
||||||
{
|
{
|
||||||
var certificate = await TryGetCertificateInfo(id);
|
var certificate = await TryGetCertificateInfo(id);
|
||||||
|
|||||||
@ -57,7 +57,7 @@ namespace QRBee.Api.Services
|
|||||||
|
|
||||||
var clientCertificate = _securityService.CreateCertificate(clientId,bytes);
|
var clientCertificate = _securityService.CreateCertificate(clientId,bytes);
|
||||||
|
|
||||||
var convertedClientCertificate = Convert(clientCertificate, clientId);
|
var convertedClientCertificate = Convert(clientCertificate, clientId,request.Email);
|
||||||
await _storage.InsertCertificate(convertedClientCertificate);
|
await _storage.InsertCertificate(convertedClientCertificate);
|
||||||
|
|
||||||
return new RegistrationResponse
|
return new RegistrationResponse
|
||||||
@ -125,6 +125,8 @@ namespace QRBee.Api.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<PaymentResponse> Pay(PaymentRequest value)
|
public async Task<PaymentResponse> Pay(PaymentRequest value)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
//1. Check payment request parameters for validity
|
//1. Check payment request parameters for validity
|
||||||
ValidateTransaction(value);
|
ValidateTransaction(value);
|
||||||
@ -175,13 +177,27 @@ namespace QRBee.Api.Services
|
|||||||
await _storage.UpdateTransaction(info);
|
await _storage.UpdateTransaction(info);
|
||||||
|
|
||||||
//10. Make response for merchant
|
//10. Make response for merchant
|
||||||
|
var response = MakePaymentResponse(value, info.TransactionId ?? "", info.Status==TransactionInfo.TransactionStatus.Succeeded, info.RejectReason);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var response = MakePaymentResponse(value, "", false, e.Message);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private PaymentResponse MakePaymentResponse(PaymentRequest value, string transactionId, bool result = true, string? errorMessage = null)
|
||||||
|
{
|
||||||
|
|
||||||
var response = new PaymentResponse
|
var response = new PaymentResponse
|
||||||
{
|
{
|
||||||
ServerTransactionId = info.TransactionId,
|
ServerTransactionId = transactionId,
|
||||||
PaymentRequest = value,
|
PaymentRequest = value,
|
||||||
ServerTimeStampUTC = DateTime.UtcNow,
|
ServerTimeStampUTC = DateTime.UtcNow,
|
||||||
Success = res.Success,
|
Success = result,
|
||||||
RejectReason = res.ErrorMessage,
|
RejectReason = errorMessage,
|
||||||
};
|
};
|
||||||
|
|
||||||
var signature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature()));
|
var signature = _securityService.Sign(Encoding.UTF8.GetBytes(response.AsDataForSignature()));
|
||||||
@ -224,7 +240,7 @@ namespace QRBee.Api.Services
|
|||||||
|
|
||||||
if (!check)
|
if (!check)
|
||||||
{
|
{
|
||||||
throw new ApplicationException($"Signature is incorrect for Id: {id}.");
|
throw new ApplicationException($"Signature is incorrect for Id: {id}. Data: {data}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,13 +325,14 @@ namespace QRBee.Api.Services
|
|||||||
return new TransactionInfo(request, DateTime.UtcNow);
|
return new TransactionInfo(request, DateTime.UtcNow);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CertificateInfo Convert(X509Certificate2 certificate, string clientId)
|
private CertificateInfo Convert(X509Certificate2 certificate, string clientId, string email)
|
||||||
{
|
{
|
||||||
var convertedCertificate = _securityService.Serialize(certificate);
|
var convertedCertificate = _securityService.Serialize(certificate);
|
||||||
return new CertificateInfo
|
return new CertificateInfo
|
||||||
{
|
{
|
||||||
Id = certificate.SerialNumber,
|
Id = certificate.SerialNumber,
|
||||||
ClientId = clientId,
|
ClientId = clientId,
|
||||||
|
Email = email,
|
||||||
Certificate = convertedCertificate,
|
Certificate = convertedCertificate,
|
||||||
ServerTimeStamp = DateTime.UtcNow
|
ServerTimeStamp = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user