#tfh_
1 messages ยท Page 1 of 1 (latest)
Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- tfh-3ds-modalconflict, 2 hours ago, 23 messages
So the URL is https://staging-ultraservers.vercel.app/dashboard/billing/invoices/592. It'll be required to log in to view the page. When someone is available to do so, let me know and you can log in with tyler@foresthauser.com. This will email a code to me that I can relay to you in order to get logged in. Once there, you can try clicking on "Pay with Stripe" and add a new card (using 4000002760003184 as a card number) in order to observe the behaviour of the iframe.
HI ๐
I"m catching up on the thread but can you specifically describe your concern here?
For sure. Let me try to summarize...
Basically, when running stripe.confirmCardPayment, Stripe adds an iframe overlay to the site that is being obstructed by our own modal that is open when running stripe.confirmCardPayment. Specifically, it seems the overlay backdrop of our modal is preventing interaction with the iframe content โ the content itself is actually visible, but it's not possible to interact with it using the cursor (tabbing to the content works just fine)
I've found that adding a single CSS property to the div that Stripe adds to the page that houses the iframe actually fixes the issue
Adding pointer-events: all; to the div allows the user to interact with the iframe content
Okay, just so I'm clear on the flow, you have a modal dialog (with an overlay) open to collect payment details but then when 3DS is triggered it launches another modal window with another overlay and this is somehow sitting on top of the actual modal and thus preventing interaction. Correct?
The 3DS modal is sitting on top of our modal (which is expected and desired) but the user is not able to interact with the contents of the 3DS modal
And yes, it seems it's the result of our modal being added to the end of the body tag whereas the Stripe modal is being added at the beginning, thus sitting earlier in the document
And when. you add the CSS property you mentioned earlier that resolves the issue. What do you add it to?
The div that contains the Stripe iframe. I've added the CSS property just using developer tools in my browser
And it would be difficult for you to modify where your modal window is appended?
It seems the Stripe modal is always added to the beginning, so even by moving ours to the beginning, it's added before the Stripe modal, so the order doesn't change
If that makes sense?
Yes I think that does. I'm struggling with how to address it though. I am guessing you would not want to dismiss your existing modal when calling confirmCardPayment.
Indeed, I would not. It remains open until the payment is complete so we can present error messages, if needed
So far, the two possible solutions I can come up with rest on Stripe's end: 1) appending the iframe content to the end of the body tag or 2) adding pointer-events: all; to the iframe's parent div's style tag
I can raise those issues but I would highly doubt they could be actioned quickly. Can you try adjusting the z-index value of your modal/overlay when the 3Ds modal is presented?
I've tried but unfortunately it would wreak havoc on the user experience, especially in the event a 3DS modal isn't presented to the user โ it would essentially appear as though the site "glitched out", if you will, as the modal would seemingly disappear and then this mystery modal would randomly appear. From the user's perspective, it would instantly seem as though something were wrong
Yes I can understand that concern
Before stumbling upon the "pointer-events:all" solution, I had tried adjusting this property for our own modal (and specifically the overlay) to try to let click events through, but alas, this did not work
And, of course, you cannot programmatically manipulate the 3DS modal to move it above the other overlay
Indeed
If I could, honestly the only thing I'd do is add that css prop. Moving its position in the dom feels wrong ๐
That makes sense.
Unfortunately we are not likely to change things about the 3DS iframe property
This would still need to be something you handle with respect to your other modal/overlay.
I understand. It's such a frustrating thing because it all comes down to the odd decision to add the Stripe modal to the beginning of the body tag.
Are there events I could possibly listen for when the Stripe iframe is added to the DOM?
Unfortunately we don't emit any events for when this occurs. I"m not 100% certain but I think it would be a security concern. Unfortunately the clearest work-around I can see would be a significant change.
That would involve confirming the payment on the server and returning a response back to the client if 3DS is required .
https://stripe.com/docs/payments/finalize-payments-on-the-server - this is the doc for that integration
The step on handling next actions is where you would trigger the 3DS auth flow: https://stripe.com/docs/payments/finalize-payments-on-the-server?platform=web&type=payment#next-actions.
It's a lot more work/complexity in the checkout process so I'm not sure it's worth it but it would allow you to distinguish between other payment/card errors and 3DS so you could handle them in separate front-end flows.
I see. Yeah, the first Stripe staff member I spoke to about this issue made this sound like quite the daunting task
Solving the modal issue? Or attempting the Finalize on Server integration path?
Oh sorry, this is a different flow than had been discussed.
I'm still reading through this doc...
Yes, this approach adds significant complexity and more overhead but it's one way I can think of to separate the confirmation of the Payment Intent from hanlding 3DS
So if I were to decouple the confirmation of the payment intent from handling 3DS, how would you recommend proceeding with the "handling 3DS" part specifically? I'd still have the issue of the 3DS modal being added to the beginning of the body tag, correct? So this would be a way to use this specific moment in the flow to perhaps try to move the position of our own modal in the DOM?
I am suggesting that, if the server returns a payment intent that requires 3Ds, you dismiss your modal window before you call the Stripe.js function handleNextAction() which will trigger the 3DS flow
Then what if there is an issue with the 3DS verification? We lose the opportunity to (easily) present errors to the user
Sorry, the more I'm thinking about this, the more this sounds like our best bet, regardless of its shortcomings
I'll just have to make this work
I would look into both that integration path as well as whether or not it is feasible to hide just the overlay (not the modal) when calling confirmCardPayment
The trouble is it's actually not just the overlay preventing interaction with the Stripe modal. Any fixed element that appears later in the body tag with a z-index set on it will prevent the interaction. So, in our case, it's our actual modal itself "covering" the Stripe modal
The video is tough to tell but I'm not able to select the text in the Stripe modal
Hmmm yes that is hard to tell. It would make more sense to try and click the butons.
Oh that is interesting. You are still interacting with the modal window
Yeah, it seems it's because it comes later in the dom, so despite the Stripe modal having an extremely high z-index, it's still being treated as if it's earlier in the doc. So that's why it seems like a bug that Stripe is adding the modal at the beginning of the body tag OR that it doesn't have "pointer-events:all" set on it
Hello again! Trying to log in to your test site now.
So I should try to pay this Invoice with a test card that will trigger 3D Secure, correct?
Correct
Ah, yeah, the main issue here is that you're setting pointer-events: none on the <body>. It's not that your overlay is covering the Stripe modal, it's that you're saying "no pointer events on anything in the entire body" and the modal (like everything else) is in the body.
Oh interesting
Can you alter your modal approach to... not do that? ๐
Haha man, this is the trouble with using component libraries. It's Radix UI and apparently that is how they've decided to do it ๐ซค
Well, I mean...
I generally don't like to say a particular approach is bad or anything, but I might make an exception in this case? ๐
I might have a workaround, hang on...
Haha I hear ya. So indeed, without that property, it works exactly as expected
Okay, try adding this to your CSS and see if that fixes the issue:
body div:first-child {
pointer-events: auto !important;
}
Awesome!
Now, what are the chances the Stripe SDK changes where the div is placed in the DOM? ๐
You mean placed elsewhere in the DOM?
I think it's unlikely.
It is possible though.
If I had to guess, I'd give it a... 1% chance of happening in the next year.
At least if it were to move, it would (hopefully) be to the end of the body tag anyways, right? ๐
That said, you should add a verbose comment above that CSS explaining why it's there, what it does, etc.
Indeed. I truly appreciate this investigation
I think the most likely place for it to move is the bottom of the <body>, yeah.
But I really don't think it will.
That's fair
It makes sense for our modal to come first in the DOM.
Why is that, if you don't mind me asking?
I'm just trying to broaden my understanding of it all
Mostly because it's more predictable. It's more likely for things to be added to the end of the <body> than to the top. If we added the modal <div> to the end of the <body> there could be another script or something that adds additional elements after it. If we add it to the top it's less likely that something will add stuff before it.
But, honestly, I don't know all the reasons. I'm not on the team that made that decision.
As far as I know we've been adding it to the top for years, so something really significant would have to pop up for us to change it at this point.
I fully appreciate that and thank you for taking the time to explain
Agreed! And I'm glad to hear it. You truly saved my day with this workaround. ๐