Same issue with other frontend framework and it fixed in some
I'm trying to use stripe in a Sapper app. Stripe requires to send credit card data using their secure stripe.js which you reference in the head of your page. I use svelte onMount() because stripe submit the data using their script and server is not involved.
I arrive at this payment component after I click on checkout button in my shopping cart component which uses goTo to direct me to this pay page/component:
function checkout(){
// handle shopping cart items
await goto('./checkout/pay');
}
navigateAndSave()
}
My pay component has the following code to collect credit card data:
onMount(async () => {
var stripe = await Stripe('pk_test....');
// call stripe.elements which will create the credit card fields
// use the fields for card #, expiration and cvv
var elements = await stripe.elements();
var card = await elements.create('card');
// mount the card to the dom
card.mount("#card-element");
card.on('change', ({error}) => {
// code the validate the credit card number, expiration date and other data.
}); //end of card.on fn
// code to charge the card. Call
// now that you mounted the stripe credit card Elment. Collect credit
// card details and submit it to stripe to process the payment using
// their api confirmCardPayment
stripe.confirmCardPayment(client_secret, {
payment_method: {
// the stripe card element has the credit card data
card: card,
billing_details: {
name: 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
}
}
}).then(function(result) {
if (result.error) {
console.log(result.error.message);
} else {
if (result.paymentIntent.status === 'succeeded') {
// update db, send emails to customer and admin...etc
}
}
});
// End of submit card information code
} // end onMount()
My html form is:
<svelte:head>
<script src="https://js.stripe.com/v3/"></script>
</svelte:head>
<h1> clientSecret Checkout </h1>
<form on:submit|preventDefault={onMount}>
<div id="card-element">
<!-- Elements will create input elements here -->
</div>
<!-- We'll put the error messages in this element -->
<div id="card-errors" role="alert"></div>
<button id="submit">Pay </button>
</form>
When I submit the pay form by filling all the fields (which the iframe from stripe) and click the pay button, I receive the following error Uncaught (in promise) IntegrationError: We could not retrieve data from the specified Element. Please make sure the Element you are attempting to use is still mounted.
I see the card fields and I enter the required card details but the error says that the Element is not mounted or the one I'm using is not mounted. So it seems to me that it's something related to mounting the component.
Anyone out there with understanding of svelte, component mounting should be able to help out with this issue. After reading some other similar questions in vue, react and angular, I realized it is something specific about mounting the frontend but I can't figure it out with svlete yet.
Is there an issue with mounting Iframe in Svelte/sapper? Looked at sapper preload fn but how do I access card in my onMount() is another issue I face. If I put anything in preload, how do I have access to card?
Any solution?