@namespace MidrandBooks.Components @using Microsoft.AspNetCore.Components @using MidrandBooks.Models @if (IsOpen) {

Secure Checkout Gate

@if (CurrentStep == "cart") { @if (CartItems.Count > 0) {
@foreach (var item in CartItems) {
@if (!string.IsNullOrEmpty(item.Book.CoverUrl)) { @item.Book.Title } else {
BOOK
}

@item.Book.Title

By @item.Book.Author

@item.Format
R @item.Price.ToString("F2")
}
} else {

Your shopping cart is empty

Browse our catalogs and add premium South African manuscripts or immersive studio audiobooks to check out.

} } else if (CurrentStep == "details") {
Secure Payment Methods

Complete South African Settlement

@if (PaymentMethod == "card") {
} else {
}
} else if (CurrentStep == "processing") {

Processing Secure Transaction

@ProcessingStatus

} else if (CurrentStep == "otp") {

Dual-Factor Verification Required

Enter the simulated SMS OTP code dispatched to secure checkout settlement: @GeneratedOtp

@if (!string.IsNullOrEmpty(OtpError)) { @OtpError }
} else if (CurrentStep == "success") {

Authorization Passed

Thank you! Your PayFast checkout transaction was approved. Your newly acquired digital books have been unlocked and compiled into your Secure Library.

}
@if (CurrentStep == "cart" || CurrentStep == "details") {
Subtotal (ZAR) R @Subtotal().ToString("F2")
VAT (15% SA) R @Vat().ToString("F2")
Total Due R @Total().ToString("F2")
} @if (CurrentStep == "cart") { } else if (CurrentStep == "details") { } else if (CurrentStep == "otp") { } else if (CurrentStep == "success") { }
} @code { [Parameter] public bool IsOpen { get; set; } [Parameter] public EventCallback OnClose { get; set; } [Parameter] public List CartItems { get; set; } = new(); [Parameter] public EventCallback> OnCheckoutSuccess { get; set; } [Parameter] public EventCallback OnRemoveFromCart { get; set; } private string CurrentStep { get; set; } = "cart"; // "cart", "details", "processing", "otp", "success" private string PaymentMethod { get; set; } = "card"; // "card", "eft" // Processing parameters private string ProcessingStatus { get; set; } = string.Empty; private int ProcessingProgress { get; set; } = 0; // Form inputs private string CardName { get; set; } = string.Empty; private string CardNumber { get; set; } = string.Empty; private string CardExpiry { get; set; } = string.Empty; private string CardCvv { get; set; } = string.Empty; private string SelectedBank { get; set; } = "Capitec"; private string EftUsername { get; set; } = string.Empty; private string EftPassword { get; set; } = string.Empty; // OTP Parameters private string GeneratedOtp { get; set; } = "482903"; private string OtpInput { get; set; } = string.Empty; private string OtpError { get; set; } = string.Empty; private double Subtotal() { return CartItems.Sum(i => i.Price); } private double Vat() { return Subtotal() * 0.15; } private double Total() { return Subtotal(); // ZAR pricing includes VAT } private void ProceedToDetails() { CurrentStep = "details"; } private void SetPaymentMethod(string method) { PaymentMethod = method; } private void RemoveItem(CartItem item) { OnRemoveFromCart.InvokeAsync(item); } private async Task ProcessSecureCheckout() { CurrentStep = "processing"; ProcessingProgress = 15; ProcessingStatus = "Establishing secure proxy to South African gateway nodes..."; await Task.Delay(1000); ProcessingProgress = 45; ProcessingStatus = "Securing socket with SSL 256-bit encryption..."; await Task.Delay(1000); ProcessingProgress = 75; ProcessingStatus = "Contacting issuing merchant bank for authorization..."; await Task.Delay(1000); ProcessingProgress = 90; ProcessingStatus = "Spawning 3D Secure 2.0 dual-factor authentication challenge..."; await Task.Delay(800); GeneratedOtp = new Random().Next(100000, 999999).ToString(); OtpError = string.Empty; OtpInput = string.Empty; CurrentStep = "otp"; } private void VerifyOtp() { if (OtpInput.Trim() == GeneratedOtp) { CurrentStep = "success"; OnCheckoutSuccess.InvokeAsync(CartItems); } else { OtpError = "The authentication code is incorrect. Please check SMS dispatch."; } } private void CloseAndFinish() { CurrentStep = "cart"; // reset step for next load OnClose.InvokeAsync(); } }