Hello,
Elements is a library of UI components [1] to help collect payment method details and other information client-side. We have multiple flavours of elements in there from the PaymentElement [2] (likely what you use) to our PaymentRequestButton [3] for displaying a branded button for wallets payments like Apple Pay and Google Pay through our newer AddressElement [4] to collect address details.
When we designed PaymentElement, the intent was to make it easy to collect any and all payment method information client-side without having to change your code. Each payment methods can have their own specificities though from a specific minimum or maximum amount, to which currencies are supported or in which country. Others require an email to be collected or a billing address. And others require certain additional options such as mandate details or not supporting separate authorization and capture.
Because of those additional restrictions, we needed a simple and reliable way to know what you planned to use to ensure that we showed only viable and compatible information to the end customer. That's what the PaymentIntent or SetupIntent APIs were designed for. They represent the lifecycle of attempting to collect payment details and are modeled as a state machine reflecting what has happened to it. For that reason, PaymentElement was built to rely on simply the `client_secret` associated with your PaymentIntent or SetupIntent to configure it easily and seamlessly client-side. Over time, as you change the amount or currency associated with the object, for example when the customer changes what's in their cart, the PaymentElement UI can dynamically render updated information.
This flexibility has also allowed us to release support for the "automatic payment methods" feature last year. You can now enable or disable new payment methods in the Dashboard with a simple click and your integration can now accept those easily without having to change your client-side integration (or often the server-side part).
Now, while this has served us and developers extremely well, it still can appear too restrictive and it has some downsides such as having a lot of "abandoned" objects that are never completed. While this integration path still offers numerous upsides, we have been working on an alternative one for a while. We now have a public beta that covers this where you can defer the creation of the PaymentIntent to later and render a PaymentElement with all the options you'd expect client-side only. We have a public doc for this here [5] which goes over the flow of that integration. You can request access to the beta directly at the top of that page too.
Alternatively, if you only use card payments, you can use the CardElement integration which lets you collect card details first and then confirm separately. This is documented here [6].
Hope this helps!
Remi