<form @onsubmit="ProcessCheckout">
<div>
<h2>Checkout</h2>
<button type="submit" class="btn btn-primary">Place Order</button>
<a href="/cart" class="btn btn-secondary">Back to Shopping Bag</a>
</div>
</form>
Best way to redirect to the authorizationUrl link in a new tab when the 'Place Order' button is clicked.
@code {
private bool shouldRedirect;
private string authorizationUrl;
protected override async Task OnInitializedAsync()
{
await ProcessCheckout();
}
private async Task ProcessCheckout()
{
try
{
// Initialize checkout process
var userId = await GetUserIdAsync();
var netTotal = await _cartService.GetBasketNetTotalAsync(userId);
var authState = await _authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
string strEmail = user.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value;
string token = _configuration["PayStackSettings:PayStackSecretKey"];
var payStack = new PayStackApi(token);
TransactionInitializeRequest request = new()
{
AmountInKobo = Convert.ToInt32(netTotal) * 100,
Email = strEmail,
Reference = Generate().ToString(),
Currency = "GHS"
};
// Initiate transaction
var response = payStack.Transactions.Initialize(request);
if (response.Status)
{
authorizationUrl = response.Data.AuthorizationUrl;
shouldRedirect = true;
StateHasChanged(); // Trigger re-render
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (shouldRedirect)
{
shouldRedirect = false; // Reset flag to prevent re-invoking
await JS.InvokeVoidAsync("open", authorizationUrl, "_blank");
}
}
private async Task<string> GetUserIdAsync()
{
var authState = await _authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
return user.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
}
private static int Generate() => new Random((int)DateTime.Now.Ticks).Next(100000000, 999999999);
}
Hi guys! I'm trying to open the authorizationUrl in a new browser tab when the 'Place Order' button is clicked. My code is just refreshing the page though it hits the ProcessCheckout in debug mode. And please note that this is a Blazor Server application
I have resolved the issue by first adding @rendermode InteractiveServer to the page since I'm using a Blazor server application and by removing the OnInitializedAsync() method from the code so the final code becomes:
@page "/checkout"
@attribute [Authorize]
@rendermode InteractiveServer
@inject AuthenticationStateProvider _authStateProvider
@inject ICartService _cartService
@inject IUserService _userService
@inject IConfiguration _configuration
@inject IJSRuntime JS
@inject NavigationManager _navigation
<PageTitle>Checkout | LearnSpace</PageTitle>
<SectionContent SectionName="page-header-title">Checkout</SectionContent>
<div>
<h2>Checkout</h2>
<button class="btn btn-primary" @onclick="ProcessCheckout">Place Order</button>
<a href="/cart" class="btn btn-secondary">Back to Shopping Bag</a>
</div>
@code {
private bool shouldRedirect;
private string authorizationUrl;
private bool shouldOpenInNewTab = false;
private async Task ProcessCheckout()
{
try
{
// Initialize checkout process
var userId = await GetUserIdAsync();
var netTotal = await _cartService.GetBasketNetTotalAsync(userId);
var authState = await _authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
string strEmail = user.FindFirst(System.Security.Claims.ClaimTypes.Email)?.Value;
string token = _configuration["PayStackSettings:PayStackSecretKey"];
var payStack = new PayStackApi(token);
TransactionInitializeRequest request = new()
{
AmountInKobo = Convert.ToInt32(netTotal) * 100,
Email = strEmail,
Reference = Generate().ToString(),
Currency = "GHS"
};
// Initiate transaction
var response = payStack.Transactions.Initialize(request);
if (response.Status)
{
authorizationUrl = response.Data.AuthorizationUrl;
shouldOpenInNewTab = true;
StateHasChanged(); // Trigger re-render to ensure OnAfterRenderAsync runs
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (shouldOpenInNewTab && authorizationUrl != null)
{
shouldOpenInNewTab = false; // Reset the flag after the redirect
await JS.InvokeVoidAsync("openInNewTab", authorizationUrl);
}
}
private async Task<string> GetUserIdAsync()
{
var authState = await _authStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
return user.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
}
private static int Generate() => new Random((int)DateTime.Now.Ticks).Next(100000000, 999999999);
}
So that's it.