#geimsdin
1 messages ยท Page 1 of 1 (latest)
It looks like the second mount didn't go well
did you mount to a same or different HTML element?
I guessed so but then the payment is processed correctly
I mount to the same HTML element
should I empty it before mounting?
I don't think the Payment (or to be correct, the SetupIntent) is processed. The error states confirmSetup() failed
I would recommend against using the same HTML div. It only to create unexpected bugs
Can I just empty it or should I remove from the DOM and recreate?
Let's remove and recreate
Ok, thanks, will try
wcnpPaymentElement.parentNode.removeChild(wcnpPaymentElement);
newWcnpPaymentElement = document.createElement('div');
newWcnpPaymentElement.setAttribute("id", "wcnp-payment-element");
wcnpPaymentForm.prepend(newWcnpPaymentElement);
I do this: remove and recreate from scratch but I still get the error: "Invalid value for stripe.confirmSetup(): elements should have a mounted Payment Element."
And how are you remounting this div?
wcnpPaymentForm.prepend(newWcnpPaymentElement);
it works, I get a new clean payment form
but when I submit I get no errors from stripe but that error in console
But there should be another code block like
const options = {
clientSecret: '{{CLIENT_SECRET}}',
// Fully customizable with appearance API.
appearance: {/*...*/},
};
// Set up Stripe.js and Elements to use in checkout form, passing the client secret obtained in step 2
const elements = stripe.elements(options);
// Create and mount the Payment Element
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');
You probably need to recreate elements here then calling mount against your newWcnpPaymentElement
let elements = stripe.elements({
clientSecret: wcNinjaPaymentData.wcNpClientSecret,
loader: 'always',
});
wcnpPayment = elements.create("payment");
wcnpPayment.mount("#wcnp-payment-element");
I recall the same function that created it the first time
You sure it has been called? Put some breakpoint?
I'm prett sure because the payment form appear again and there is no other code mounting it
Hmm I see. any chances the elements passed in confirmSetup() is the old one instead of the new one?
it is defined inside the function, not a global var, then every execution is created again from scratch
Okie. It seems strange. I would try with a bit different element id
But overall, why don't you just refresh your customer in the page again instead of doing this thing? It will only complicated bugs and errors
I'm trying to handle by ajax for better UX
Ok let's try a different element id, probably #wcnp-payment-element-{timestamp} and somehow passing it with your function. But honestly I am not sure if it works. The DOM tree might be in a weird state after the removal :/
Ok, I try
If you can generate different element id, it might be a good idea to not remove the first element while appending the 2nd one, to see if it work without the removal logic
Even if you have 2 elements on the page, you have different Id and both mounted to different instance of elements
It doesn't work, even with different ID, I will try to destroy all and recreate
๐ Taking over this thread from orakaro
Let me know if you have any follow up question
Hi
I still have the same problem, even destroying completely the object
Is there a way to completely delete the created stripe.elements and restart from scratch in the same webpage?
What's the error you're facing?
Now this: We could not retrieve data from the specified Element.
Please make sure the Element you are attempting to use is still mounted.
But the one I want to fix is this: "Invalid value for stripe.confirmSetup(): elements should have a mounted Payment Element."
The original one
It sounds like the element is not mounted
Yes but it is
Could you share the code?
Sure, let me remove the modifications and I will share here
file or directly as a message? it is 208 lines
You can send it as a file
on line 85 is where I intercept the event "checkout_error" and try to reinitialize the element
With this code, which error does it throw?
"We could not retrieve data from the specified Element. Please make sure the Element you are attempting to use is still mounted." OR
"Invalid value for stripe.confirmSetup(): elements should have a mounted Payment Element"
I get this now: We could not retrieve data from the specified Element. Please make sure the Element you are attempting to use is still mounted.
Which line does it throw from?
If I don't remove the childnode but just overwrite I get this: Invalid value for stripe.confirmSetup(): elements should have a mounted Payment Element
line 15007 of some stripe js
15007 if prettyprint
Even if I get this errors in console the payment is passed correctly to stripe and I can find subscription and payment on my dashboard... really strange
Not the line of StripeJS, but the line in your code that triggers the error
Is not thrown by my code
115
Is where I intercept the submit
Do you have any idea?
I guess I found the problem: the first stripe.elements is still there, when I submit the second time the error is displayed 2 times, when I submit the 3rd time it is displayed 3 times
It is like adding instances instead of overwriting the old one
Then I get back to my first question: how to reinitialize stripe.elements or stripe object directly?
Could you share why you want to re-initialise the elements?
What's the use case here?
The user submit the payment form but doesn't fill some required billing data, woocommerce perform an ajax check and if there is an error stays in the page showing the error message.
If I keep the same payment form it will not work because of the setupIntent state that is already changed
Then I am forced to unmount the payment and reinitialize the elements with a new client secret
Hey! Taking over for my colleague. Let me catch up.
Please help me
Could you please resume your last follow-up Question ?
quote: "Then I get back to my first question: how to reinitialize stripe.elements or stripe object directly?"
if I delete the var it doesn't work, it is still stacking instances
Better to say: if I delete the var is better because stacks only 2 instances instead of adding at every submit a new one, but still I want to clean it
Sorry, I'm not understanding about what var and what instances, could you please share some code snippet and what is the issue ?
I already shared the code here
I initialize stripe, then create the stripe.element... when I need to reload it I delete both stripe var and elements var
but still it keeps the old instance in Stripe (I guess) and that is a nonsense
Here the code again
elements.clear() in that code is just a test, you can ignore it
I initialize stripe, then create the stripe.element... when I need to reload it I delete both stripe var and elements var
I don't understand why you want to delete Stripe and element vars? You should reuse them it's like initializing a builder in your application and once you need to create a new element you juste call it
Ok, please explain hoiw
how
Because before I was trying to reuse but since the SetupIntent has already been confirmed I thought that I was forced to do it
The SetupIntent is managed by your backend, and StripeJs is in your Frontend
So you aren't obliged to reinitialize StripeJs each time
check the JS part of this guide it could Help you:
https://stripe.com/docs/payments/quickstart?client=html&lang=node
I don't reinitialize stripejs, ok, but I have to reinitialize the stripe.elements with the new clientsecret, correct?
I did as you suggested and now I get this error: wc-ninja-payment-public.js?ver=1.0.0:161 Uncaught (in promise)
Each time you get a new secret you should do something like this:
const appearance = {
theme: 'stripe',
};
elements = stripe.elements({ appearance, clientSecret });
const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");
Without re-initializing stripe
I did initialize only one time and I get wc-ninja-payment-public.js?ver=1.0.0:161 Uncaught (in promise)
if ( c === 0 ) {
//Initialize Stripe
wcnpStripe = Stripe(wcNinjaPaymentData.wcNpPubKey);
c++;
}
Every submit I get more errors
Could you please share all the Stacktrace in order to see what issue are you getting ?
from console?
Hi! I'm taking over this thread.
Can you clarify why you want to unmount remount the PaymentElement on your page? What are you trying to achieve?
Because I need it in case the order fails for external cause and I have to resubmit the payment
makes sense I suppose. What specific problem are you having? This thread has been open for 7 hours so we can't really keep helping this way, it's clearly not working.
You are the 5th trying to help me
I suggest taking a bit of time to think over what's been shared, summarise the issue, and write an email to https://support.stripe.com/?contact=true with a bullet point of list of specific questions.
I really believe that something is not correct in the Stripe js object but I'm figuring out how to handle it in reverse: if checkout is succesful then submit to stripe... then I will not need a second payment to be mounted
ultimately I doubt we really support this level of dynamism in recreating the stripe.js objects, it's not at all how most sites integrate it
we create various iframes and context in global scope so deleting things and such will cause problems. Really I'd just reload the full page or something and keep things simple rather than spend more time on this