I have a form that sends a request to Stripe, in order for my users to add a payment method:
<form id="card-form">
<label>Card details</label>
<div id="card-element"></div>
<button wire:target="addPaymentMethod" wire:loading.class="hidden" class="button round" id="card-button">Add payment card</button>
<!-- Loading spinner -->
<svg wire:target="addPaymentMethod" wire:loading class="inline-block animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</form>
The (stripped down) JavaScript looks like below:
const stripe = Stripe('stripe-public-key');
const elements = stripe.elements();
const form = document.getElementById('card-form')
const cardButton = document.getElementById('card-button');
const cardElement = elements.create('card');
cardElement.mount('#card-element');
form.addEventListener('submit', async (e) => {
e.preventDefault();
cardButton.disabled = true;
const {
setupIntent,
error
} = await stripe.confirmCardSetup(
clientSecret, {
payment_method: {
card: cardNumber,
billing_details: {
name: 'Oliver'
}
}
}
);
if (error) {
// Display error.message to the user...
cardButton.disabled = false
console.log(error.message)
} else {
// The card has been verified successfully...
@this.addPaymentMethod(setupIntent.payment_method)
}
});
If the response in the async method above is successful, it will trigger the below method in the Livewire component:
public function addPaymentMethod($paymentMethod)
{
//Create the payment method in Stripe...
auth()->user()->addPaymentMethod($paymentMethod);
//Other validation etc...
}
The output of all of this is captured in the below gif. As you can see here, the user enters the credit card details and click on the "Add payment card" and is redirected to another page.
The problem is, that the loading state starts for a while, but disappears before the actual request/redirect is done.
How can I show the loading spinner until the actual request to Stripe is completed?
