As long as the frontend sends the card details only directly back to the PCI compliant service's servers, you are fine. This can still be done if your frontend is server rendered -- the data isn't there yet when you server render the form.
What I believe you can't do is have your own frontend send the data in the form to your own backend, then forward on to the other service from there. Once the plaintext card details touch your servers you have to be PCI compliant, even if you aren't storing them.
If you absolutely can't do the former on your frontend, eg because you don't want to use JS or something similar, then you can use services like Stripe checkout where they host the frontend on a URL you redirect to from your app, etc.
In that case I think it is just slightly more convenient to render a PCI compliant entity's frontend as an iframe inside your application and have it send the details directly to the processor's server, perhaps saves one additional hop
Could be, I guess the downside of this is that you don't get full control of the UI which is a problem for some products. Depends on the tradeoffs I guess.
In general I am a fan of just using things like Stripe Checkout though - it's not just about compliance but also just the complexity of getting the frontend part right with the myriad different payment flows, errors, and other subtle details that exist.
But my original comment was more just clearing up confusion that you can absolutely do the frontend UI customly if you want to - there's no issue with this and PCI compliance, that only kicks in once the data goes to your server.
I have tried it, though years ago. It's good but quite low level - it gives you some nice components which is a bit of work saved but does still leave you with all of the (really complex) flows to implement.
This always feels weird to me. Who is auditing my site to make sure I don’t send the details to my server, or some nefarious server, along with the Stripe request? The user would only see the actions of the Stripe success/failure and never know a copy was made elsewhere.
If your frontend handles card data, it is in scope. Among other things, you will have to prove that you are not sending card data to your backend servers in any way (logs, etc.).
Prove to who? If I sign up for Stripe, all I have to do is complete a questionnaire annually. I could easily lie or make my frontend compliant during that time period and nefarious afterwards.
It seems like a veil of security versus any actual security. My guess is that it's really just meant to assign liability to the merchant when nefarious stuff happens and there's plenty of ways a fraudster could shield themselves from that as well.
At the end of the day, as a customer visiting some random merchant website showing a "Powered by Stripe" logo does not actually make me feel like my CC data is secure. Anytime I enter info into a UI/DOM that is not directly under the stripe.com/paypal.com/etc (full page load), I don't feel my info is necessarily safe; but that's what they want me to believe. It's totally possible to just put a "powered by Stripe" UI element on a page without having any relationship with Stripe. And, the false security of that UI element tricks you into putting your info into some random site. I just don't see how that's secure at all to train users that anytime you see that UI element you can safely input your payment information regardless of the site you are on.
Stripe must diligently ensure their merchants are not improperly handling card data. Failing to do this could cost them their PCI status, so they will definitely shut down your account if they find you’re not properly using their services, meaning you’ll lose any funds in it along with your ability to use their services. Any other PayFac worth their salt will also begin to refuse your account if you continue bad bahavior. If you read Stripe’s docs, you’ll see specific instructions on how to use their elements (don’t host them locally, as an example), and I assume they have a variety of automated and manual methods to flag improper use.
Stripe aside, if you claim to not be in scope, but that claim is in question, then you’ll likely have to prove you do not improperly handle card data to an auditor, or risk fines and/or loss of any funds you’ve accumulated so far.
PCI isn’t perfect, but they do have business reasons to stop most obvious bad behavior.
What I believe you can't do is have your own frontend send the data in the form to your own backend, then forward on to the other service from there. Once the plaintext card details touch your servers you have to be PCI compliant, even if you aren't storing them.
If you absolutely can't do the former on your frontend, eg because you don't want to use JS or something similar, then you can use services like Stripe checkout where they host the frontend on a URL you redirect to from your app, etc.