Stripe is a service for processing payments online. They have an API and libraries to use in just about any language. Payment can be really complicated and loaded with legal requirements. Having a service like stripe limits how much a developer needs to know in order to build an application.
The project I worked on sells a subscription service, so there needs to be an initial registration and payment workflow, and a way for customers to adjust their subscription and payment later.
There are some out of the box features that are easy to set up on your site. For example, you can create a link to a stripe page that handles everything you need for payment and redirects back to your site. If that's not smooth enough, there are elements you can load on the page with a js library that works as well. You can integrate this with other form elements for a secure way to do complex registration forms.
I had to learn about how the system was already built, what options are in the stripe api, and how the Drupal module implements things.
In order to get a stripe element into a drupal form, the module provides an Element with a process function that loads the PaymentIntent. When the submit button is first clicked, the stripe part of the form is submitted to an ajax callback where Drupal can process form fields and adjust the payment before returning to the client side to send it to stripe it to stripe.
When the Payment Intent is created, a client secret key is provided that we can store in the form as a hidden value and used to adjust the payment throughout the workflow.
I also had to juggle how to create customers and subscriptions. At first I set things up when the form was loaded, but seemed to be creating too many objects each time.
I went with SetupIntent over PaymentIntent, since it seemed more appropriate.