According to [1] it is required and there's no other (documented) way to do it.
Ditto for stripe.createToken() [2].
In fact, there's no word in the docs on how to feed raw card data into the v3 at all.
So we had no choice but to use Stripe.card.createToken() from the v2, but then also use stripe.handleCardAction() from the v3 for confirmation... it's a mess. What did we miss?
[1] https://stripe.com/docs/stripe-js/reference#stripe-create-pa...
[2] https://stripe.com/docs/stripe-js/reference#stripe-create-to...
[0] https://stripe.com/docs/security#validating-pci-compliance
[1] https://stripe.com/docs/api/payment_methods/create#create_pa...
[2] https://stripe.com/docs/stripe-js/reference#stripe-handle-ca...
That's the flow we had with the v2 and that's what we can't replicate with the v3.