Hello.
The doc you linked [1] is the canonical integration path today and what I would recommend doing in your case. At a high level you would do the following steps
1/ Create a Customer
2/ Create a Subscription, passing the right Price id but also `payment_behavior: 'default_incomplete'` (so that the first payment is attempted afterwards) and also using the Expand feature [2] to obtain the first Invoice's PaymentIntent's `client_secret` by passing `expand: ['latest_invoice_payment_intent']`
3/ Send that `client_secret` value client-side to your app so that you can render PaymentElement with all the relevant details (currency, amount, payment methods, etc.)
4/ Collect payment method details and confirm the payment using `confirmPayment()` bringing the Subscription to active
Based on the way you described your app, this seems like the simplest approach. After the end customer selects the price they want to pay you now know exactly how to create the Subscription. This will automatically create an Invoice and a PaymentIntent for you which you can use to render PaymentElement with the right information. What you might have missed here in that doc is the Expand feature I mentioned above that lets you access the underlying PaymentIntent's client_secret as needed during Subscription creation.
An alternative approach would be to collect payment method details first. This is a newer integration path documented here [3]. The main difference is that you render PaymentElement without a client secret first. Instead, you initialize it with specific options such as currency/amount. Doing this though does require you to calculate the right final amount. This can seem easy for basic pricing like $20/month but is harder once you take into account things like discounts, automatic tax or custom pricing scheme like tiered pricing.
In that case, what we usually recommend is to use the Retrieve Upcoming Invoice API [4] server-side as it lets you preview what the first Invoice of a Subscription would look like. Doing this will give you the exact amount/currency that you need to return to your client-side code to properly render PaymentElement.
The advantage of this approach is that you can offer things like an upsell/cross-sell to a different Price, change the quantity or support discounts. You're calculating the amount but the Subscription isn't created yet until they make their decision and enter payment method details.
Both approaches have pros and cons depending on your overall payment flow so I hope one of those will fit your needs!
If you have follow up questions, I'd recommend working with our support team more in a 1:1 setting where they can look at your code, some example objects and advise you on the best path forward.
Best,
Remi