recurly / recurly-js

Simple subscription billing in the browser
https://js.recurly.com/
MIT License
647 stars 139 forks source link

Recurly (3DS) in Test Mode with `<dialog />` elements #876

Closed simeydotme closed 5 months ago

simeydotme commented 5 months ago

Hi,

I'm trying to build out the 3DSecure flow with Recurly, using the test environment. I have the checkout flow open in a side-panel utilising <dialog /> and the HTML Api for TopLayer.

When the challenge test screen appears (<iframe name="__privateStripeFrame****"> inside of a <div>), it is BEHIND the TopLayer and attached to the very beginning of the <body>. I have tried two things;

1) set the attach() to my <dialog />

  const topModal = document.querySelector('dialog[data-is-top=true]');
  const attachTo = topModal || document.body;
  threeDSecure.attach(attachTo);

In the screenshot (with some redaction) you can see the Visa Test Card Modal is stuck behind my <dialog />'s ::backdrop . The reason is because the <dialog /> API promotes it to the ::TopLayer which cannot be overwritten with a non-top-layer element.

Screenshot 2024-03-15 at 15 28 31

So the questions are;

chrissrogers commented 5 months ago

For Stripe's 3-D Secure implementation, we're somewhat limited in our attachment controls. See code. From that call, they are making some assumptions about modal placement, and aren't going to make use of the DOM attachment point passed to attach.

Moving an <iframe> would cause it to re-render, and likely to break the communication between the controlling entity on the parent (Stripe.js) and the application inside of the iframe.. that's likely the cause of the disappearance you're seeing.

I'll admit my familiarity with the dialog element and the TopLayer are limited, so I'm not sure I can provide any direct help with those.. but if there is no way to lift the Stripe modal element into the TopLayer, then it may be best to go the "classic" modal render route, unfortunately.

simeydotme commented 5 months ago

Thanks for the response @chrissrogers :) Sadly, our entire frontend design system was recently moved over to <dialog />

But for now, I'm closing the side-panel drawer upon triggering the 3DS flow. And re-opening upon an error or failed challenge. It's not ideal, as it can wipe out the creditcard fields, but it's the only thing I could come up with.

don't hesitate to @ me if anything changes with the way modals/iframes are rendered 👍

simeydotme commented 5 months ago

https://stackoverflow.com/a/75947179/1121532

According to this, it may only be a test-env issue, so I will monitor how it works with a real card payment in prod, and if there's no issue I'll put a flag in to close only in staging/dev.