We have our own simple Blazor form which captures CC, Date CVV etc. We send it to the server where I can create the token if possible via Square API but nothing seems to be available for it. The Javascript (const result = await card.tokenize(); ) but we don’t want to do this in Javascript as it requires too much work and changes outside of Blazor and C# like using JS Interop etc.
Currently, with Square creating a card token directly with the .NET SDK isn’t currently available. You’ll need to use our client side SDK to first create the token and then use the API to process the payment.
I just published a nuget package containing a custom EditForm compatible input component that you may be able to use. The component encapsulates all the Javascript so all you should need to do is insert the InputSquarePayment component in your EditForm.
@page "/checkout"
@using System.ComponentModel.DataAnnotations
@using Simple.Components
@using BlazorSquareToolkit.WebPayments
<h3>Checkout</h3>
<div id="checkout">
<PaymentFlow @ref=@paymentFlow>
<PaymentPending>
<div id="payment-pending">
<CheckoutInfo></CheckoutInfo>
<EditForm Model="@paymentFormData" OnSubmit="@HandlePaymentSubmit">
<div>
<DataAnnotationsValidator />
<ValidationSummary />
<InputSquarePayment @bind-Value="paymentFormData.Nonce" @ref="inputSquarePayment" />
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</EditForm>
</div>
</PaymentPending>
<PaymentProcessing>
<div id="payment-processing">
<div>Processing payment</div>
<div class="spinner-border"></div>
<div>@ProcessingMessage</div>
</div>
</PaymentProcessing>
<PaymentComplete>
<div id="payment-complete">
<div>Thank you for your payment.</div>
</div>
</PaymentComplete>
</PaymentFlow>
</div>
@code {
InputSquarePayment? inputSquarePayment;
PaymentFlow? paymentFlow;
string? ProcessingMessage;
async Task HandlePaymentSubmit(EditContext editContext)
{
if (editContext.Validate())
{
paymentFlow!.PaymentFlowState = PaymentFlow.State.Processing;
ProcessingMessage = "Retrieving token";
StateHasChanged();
var tokenizeResponse = await inputSquarePayment!.Tokenize();
if (tokenizeResponse != null && tokenizeResponse.IsValid())
{
var card = tokenizeResponse.Details?.Card!;
ProcessingMessage = $"{card.Brand} with Exp:{card.ExpMonth}/{card.ExpMonth} and Ending in {card.Last4}";
StateHasChanged();
// send payment request to backend
await Task.Delay(5000);
//
paymentFlow.PaymentFlowState = PaymentFlow.State.Complete;
}
else
{
ProcessingMessage = "Unable to process payments at this time. Please retry later.";
}
}
}
PaymentFormData paymentFormData = new();
public class PaymentFormData
{
[Required(ErrorMessage = "Card information must be completed.")]
public string Nonce { get; set; } = string.Empty;
}
}