mirror of
https://github.com/NecroticBamboo/QRBee.git
synced 2025-12-21 12:11:53 +00:00
Merchant to client to merchant round trip implemented (no security).
This commit is contained in:
parent
de95d78a23
commit
575d0ccf0b
@ -32,7 +32,25 @@
|
||||
set;
|
||||
}
|
||||
|
||||
public string AsString() => $"{Request.AsString()}|{ClientId}|{TimeStampUTC:O}";
|
||||
public string AsString() => $"{ClientId}|{TimeStampUTC:O}|{Request.AsString()}";
|
||||
|
||||
public static ClientToMerchantResponse FromString(string input)
|
||||
{
|
||||
var s = input.Split('|');
|
||||
if (s.Length != 3)
|
||||
{
|
||||
throw new ApplicationException("Expected 3 elements");
|
||||
}
|
||||
|
||||
var res = new ClientToMerchantResponse()
|
||||
{
|
||||
Request = MerchantToClientRequest.FromString(string.Join("|", s.Skip(2))),
|
||||
ClientId = s[0],
|
||||
TimeStampUTC = DateTime.ParseExact(s[1], "O", null)
|
||||
};
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
namespace QRBee.Core.Data
|
||||
using System.Globalization;
|
||||
|
||||
namespace QRBee.Core.Data
|
||||
{
|
||||
public record MerchantToClientRequest
|
||||
{
|
||||
@ -32,7 +34,27 @@
|
||||
set;
|
||||
}
|
||||
|
||||
public string AsString() => $"{TransactionId}|{Name}|{Amount:0.00}|{TimeStampUTC:O}";
|
||||
public string AsString() => $"{TransactionId}|{Name}|{Amount.ToString("0.00", CultureInfo.InvariantCulture)}|{TimeStampUTC:O}";
|
||||
|
||||
public static MerchantToClientRequest FromString(string input)
|
||||
{
|
||||
var s = input.Split('|');
|
||||
if (s.Length != 4)
|
||||
{
|
||||
throw new ApplicationException("Expected 4 elements");
|
||||
}
|
||||
|
||||
var res = new MerchantToClientRequest
|
||||
{
|
||||
TransactionId = s[0],
|
||||
Name = s[1],
|
||||
Amount = Convert.ToDecimal(s[2], CultureInfo.InvariantCulture),
|
||||
TimeStampUTC = DateTime.ParseExact(s[3],"O",null)
|
||||
};
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using QRBee.Core.Data;
|
||||
using QRBee.Services;
|
||||
using QRBee.Views;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace QRBee.ViewModels
|
||||
{
|
||||
|
||||
|
||||
internal class ClientPageViewModel
|
||||
internal class ClientPageViewModel: BaseViewModel
|
||||
{
|
||||
public bool _isVisible;
|
||||
public string _amount;
|
||||
private string _qrCode;
|
||||
private MerchantToClientRequest _merchantToClientRequest;
|
||||
private readonly ClientPage _clientPage;
|
||||
|
||||
public ClientPageViewModel(Views.ClientPage clientPage)
|
||||
{
|
||||
ScanCommand = new Command(OnScanButtonClicked);
|
||||
GenerateQrCommand = new Command(OnGenerateQrClicked);
|
||||
_clientPage = clientPage;
|
||||
}
|
||||
|
||||
public Command ScanCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
public Command GenerateQrCommand
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
private async void OnScanButtonClicked(object sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
var scanner = DependencyService.Get<IQRScanner>();
|
||||
var result = await scanner.ScanQR();
|
||||
if (result != null)
|
||||
{
|
||||
_merchantToClientRequest = MerchantToClientRequest.FromString(result);
|
||||
Amount = $"{_merchantToClientRequest.Amount:N2}";
|
||||
IsVisible = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public string Amount
|
||||
{
|
||||
get => _amount;
|
||||
set
|
||||
{
|
||||
if (value == _amount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_amount = value;
|
||||
OnPropertyChanged(nameof(Amount));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get => _isVisible;
|
||||
set
|
||||
{
|
||||
if (value == _isVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isVisible = value;
|
||||
OnPropertyChanged(nameof(IsVisible));
|
||||
}
|
||||
}
|
||||
|
||||
public string QrCode
|
||||
{
|
||||
get => _qrCode;
|
||||
set
|
||||
{
|
||||
// _qrCode = $"{Amount}/{Name}";
|
||||
if (_qrCode == value)
|
||||
return;
|
||||
|
||||
_qrCode = value;
|
||||
OnPropertyChanged(nameof(QrCode));
|
||||
}
|
||||
}
|
||||
|
||||
public async void OnGenerateQrClicked(object obj)
|
||||
{
|
||||
|
||||
bool answer = await _clientPage.DisplayAlert("Confirmation", "Would you like to accept the offer?", "Yes", "No");
|
||||
if (answer)
|
||||
{
|
||||
var response = new ClientToMerchantResponse
|
||||
{
|
||||
ClientId = Guid.NewGuid().ToString("D"),
|
||||
TimeStampUTC = DateTime.UtcNow,
|
||||
Request = _merchantToClientRequest
|
||||
|
||||
};
|
||||
// TODO Create merchant signature.
|
||||
QrCode = response.AsString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,21 +1,43 @@
|
||||
using System;
|
||||
using QRBee.Core.Data;
|
||||
using QRBee.Services;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace QRBee.ViewModels
|
||||
{
|
||||
internal class MerchantPageViewModel : BaseViewModel
|
||||
{
|
||||
private bool _isVisible;
|
||||
private string _name;
|
||||
private decimal _amount;
|
||||
private string _qrCode;
|
||||
|
||||
public Command GenerateQrCommand { get; }
|
||||
public Command ScanCommand{ get; }
|
||||
|
||||
public MerchantPageViewModel()
|
||||
{
|
||||
ScanCommand = new Command(OnScanButtonClicked);
|
||||
GenerateQrCommand = new Command(OnGenerateQrClicked);
|
||||
}
|
||||
|
||||
private async void OnScanButtonClicked(object sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
var scanner = DependencyService.Get<IQRScanner>();
|
||||
var result = await scanner.ScanQR();
|
||||
if (result != null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
@ -42,6 +64,20 @@ namespace QRBee.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsVisible
|
||||
{
|
||||
get => _isVisible;
|
||||
set
|
||||
{
|
||||
if (value == _isVisible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_isVisible = value;
|
||||
OnPropertyChanged(nameof(IsVisible));
|
||||
}
|
||||
}
|
||||
|
||||
public string QrCode
|
||||
{
|
||||
get => _qrCode;
|
||||
@ -58,9 +94,16 @@ namespace QRBee.ViewModels
|
||||
|
||||
public async void OnGenerateQrClicked(object obj)
|
||||
{
|
||||
QrCode = $"{Name}.{Amount:0.00}.{DateTime.UtcNow:O}";
|
||||
// Prefixing with `//` switches to a different navigation stack instead of pushing to the active one
|
||||
// await Shell.Current.GoToAsync($"//{nameof(AboutPage)}");
|
||||
var trans = new MerchantToClientRequest
|
||||
{
|
||||
TransactionId = Guid.NewGuid().ToString("D"),
|
||||
Name = Name,
|
||||
Amount = Amount,
|
||||
TimeStampUTC = DateTime.UtcNow
|
||||
};
|
||||
// TODO Create merchant signature.
|
||||
QrCode = trans.AsString();
|
||||
IsVisible = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:viewmodels="clr-namespace:QRBee.ViewModels"
|
||||
xmlns:forms="clr-namespace:ZXing.Net.Mobile.Forms;assembly=ZXing.Net.Mobile.Forms"
|
||||
xmlns:common="clr-namespace:ZXing.Common;assembly=zxing.portable"
|
||||
x:DataType="viewmodels:ClientPageViewModel"
|
||||
x:Class="QRBee.Views.ClientPage">
|
||||
<ContentPage.Content>
|
||||
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
|
||||
@ -9,13 +13,28 @@
|
||||
<!-- HorizontalOptions="CenterAndExpand" /> -->
|
||||
<StackLayout Orientation="Vertical" VerticalOptions="FillAndExpand">
|
||||
<StackLayout Orientation="Vertical">
|
||||
<Label x:Name="Name" VerticalOptions="FillAndExpand" Text="Merchant name: "/>
|
||||
<Label x:Name="Amount" VerticalOptions="FillAndExpand" Text="Amount: "/>
|
||||
<Label VerticalOptions="FillAndExpand" Text="Amount:"/>
|
||||
<Label VerticalOptions="FillAndExpand" Text="{Binding Amount}"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Orientation="Horizontal" VerticalOptions="End" Margin="0,0,0,10">
|
||||
<Button Text="Scan me" HorizontalOptions="CenterAndExpand" BackgroundColor="Aqua" TextColor="Red" Clicked="OnScanButtonClicked"/>
|
||||
<forms:ZXingBarcodeImageView
|
||||
BarcodeFormat="QR_CODE"
|
||||
BarcodeValue="{Binding QrCode}"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="FillAndExpand">
|
||||
<forms:ZXingBarcodeImageView.BarcodeOptions>
|
||||
<common:EncodingOptions Width="300" Height="300" />
|
||||
</forms:ZXingBarcodeImageView.BarcodeOptions>
|
||||
</forms:ZXingBarcodeImageView>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout Orientation="Vertical" VerticalOptions="End" Margin="0,0,0,10">
|
||||
<StackLayout Orientation="Horizontal">
|
||||
<Button Text="Accept" HorizontalOptions="FillAndExpand" BackgroundColor="DarkGreen" IsVisible="{Binding IsVisible}" Command="{Binding GenerateQrCommand}"/>
|
||||
<Button Text="Deny" HorizontalOptions="FillAndExpand" BackgroundColor="DarkRed" IsVisible="{Binding IsVisible}"/>
|
||||
</StackLayout>
|
||||
<Button Text="Scan me" HorizontalOptions="FillAndExpand" BackgroundColor="Aqua" TextColor="Red" Command="{Binding ScanCommand}"/>
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using QRBee.Services;
|
||||
using QRBee.ViewModels;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
@ -11,25 +12,7 @@ namespace QRBee.Views
|
||||
public ClientPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void OnScanButtonClicked(object sender, EventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var scanner = DependencyService.Get<IQRScanner>();
|
||||
var result = await scanner.ScanQR();
|
||||
if (result != null)
|
||||
{
|
||||
Name.Text = result;
|
||||
Amount.Text = result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
throw;
|
||||
}
|
||||
this.BindingContext = new ClientPageViewModel(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -23,9 +23,6 @@
|
||||
<!-- -->
|
||||
<!-- </StackLayout> -->
|
||||
<!-- -->
|
||||
<!-- <StackLayout Orientation="Horizontal"> -->
|
||||
<!-- -->
|
||||
<!-- </StackLayout> -->
|
||||
|
||||
<forms:ZXingBarcodeImageView
|
||||
BarcodeFormat="QR_CODE"
|
||||
@ -39,10 +36,10 @@
|
||||
|
||||
</StackLayout>
|
||||
|
||||
|
||||
|
||||
<StackLayout Orientation="Horizontal" VerticalOptions="End" Margin="0,0,0,10">
|
||||
<Button Text="Generate QR code" HorizontalOptions="CenterAndExpand" BackgroundColor="Red" TextColor="Aqua" Command="{Binding GenerateQrCommand}"/>
|
||||
<StackLayout Orientation="Vertical" VerticalOptions="End" Margin="0,0,0,10">
|
||||
<Button Text="Scan response" HorizontalOptions="FillAndExpand" BackgroundColor="Aqua" TextColor="Red" IsVisible="{Binding IsVisible}" Command="{Binding ScanCommand}"/>
|
||||
<Button Text="Generate QR code" HorizontalOptions="FillAndExpand" BackgroundColor="Red" TextColor="Aqua" Command="{Binding GenerateQrCommand}"/>
|
||||
</StackLayout>
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user