#raohongping_best-practices

1 messages ยท Page 1 of 1 (latest)

viral badgeBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1468924260616765543

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

bleak ginkgo
#

hey there ๐Ÿ‘‹ could you share the Subscription ID (sub_123) or PaymentIntent ID (pi_123) for the example you already tested with?

#

also just to clarify, you mentioned a free trial, but you also mentioned a payment amount

can you confirm if you want to charge an amount to the customer at the time the subscription is created? or is it a truly free trial?

grave current
#

sub_1Sx3Ar1n1QMvNfT82rM8BYJa

grave current
bleak ginkgo
#

just double checking whether the 'call to action' button can be customised

grave current
bleak ginkgo
#

this way, you could render your own custom text in the button in your app

grave current
#

This seems more complicated than it should be. I believe this is a very common use case โ€” users subscribing to both free trial plans and non-free-trial plans.
Isn't there a way to use PaymentIntent without it automatically completing the payment for free trial subscriptions? Is there a configuration option or parameter to prevent the automatic payment while still using PaymentIntent?

bleak ginkgo
#

there isn't even a PaymentIntent created for a free trial subscription, at the time of subscription creation

a PaymentIntent is only created when the customer will be charged - a SetupIntent is created instead when no payment is due

so you shouldn't have a PaymentIntent at this point in the flow

grave current
#

So here's the approach I'm considering:
Server-side:
For free trial subscriptions โ†’ use SetupIntent
For non-free-trial subscriptions โ†’ use PaymentIntent
Client-side:
Check the prefix of the returned clientSecret
If it starts with seti_ (SetupIntent): manually set the button label using configuration.primaryButtonLabel = "$0.00"
If it starts with pi_ (PaymentIntent): no modification needed, the PaymentSheet will automatically display the payment price
Is this approach considered a best practice? Or is there a better/recommended way to handle this scenario?

bleak ginkgo
#

ah yes, apologies, I was incorrect above where I said that it's not possible to customise the button test - primaryButtonLabel is the right way to do this

#

your approach makes sense, but I'd caution against relying on the ID prefixes (pi / seti / etc) - while those are generally fairly robust, officially in our API specs we don't guarantee that they'll always be consistent, so it's possible they could change in the future and break your integration

#

instead, I'd recommend relying on the parameters and objects where you get the client_secret from - for instance, if you're creating a free trial subscription, then the SetupIntent will be returned to you in the pending_setup_intent parameter on the Subscription object - that way you know for sure that this is a SetupIntent

https://docs.stripe.com/billing/subscriptions/deferred-payment#use-setupintents

#

you shouldn't ever need to manually create PaymentIntents or SetupIntents directly when creating subscriptions

grave current
#

My main question is: Is it a reasonable/recommended approach for the server to use SetupIntent for free trial subscriptions and PaymentIntent for non-free-trial subscriptions?
Is this the correct pattern for handling these two different scenarios?

bleak ginkgo
#

I think this is the core confusion here

Is it a reasonable/recommended approach for the server to use SetupIntent for free trial subscriptions and PaymentIntent for non-free-trial subscriptions?

What do you mean by 'use', in this sentence?

#

For context, what's expected to happen is:

  1. Create subscription
  2. In response, Stripe creates either a SetupIntent or PaymentIntent automatically
  3. On the client-side, you use the client_secret returned in 2, to complete/activate the subscription and collect the customer's payment method
#

so your server never needs to create a PaymentIntent or SetupIntent manually - which one you 'use' is defined by the type of subscription you create (i.e. paid or free)

viral badgeBOT
grave current
#

On the server side, how should I implement the logic to automatically create a SetupIntent or PaymentIntent based on the subscription type?
Specifically:
When a user selects a free trial subscription โ†’ create SetupIntent
When a user selects a non-free-trial subscription โ†’ create PaymentIntent
Is there a built-in way for Stripe to handle this automatically, or do I need to implement this conditional logic myself based on the Price ID or subscription parameters?

flint pier
#

Is there a built-in way for Stripe to handle this automatically
We do handle that automatically upon Subscription generation, which is what you're seeing here

grave current
# flint pier > Is there a built-in way for Stripe to handle this automatically We do handle t...

Question
I'm integrating Stripe using the iOS SDK and have encountered an issue.
The Problem:
When creating a subscription with a free trial, I used PaymentIntent from the server side. However, the payment was automatically completed even before the client performed any payment action.
Our Workaround:
We switched to using SetupIntent instead. This solved the free trial issue - the payment is no longer automatically completed.
New Issue:
With SetupIntent, the PaymentSheet no longer displays the payment price. The button text shows "Set up" instead of showing the actual subscription price.
What I'm Looking For:
How can I achieve both of the following:
Free trial subscriptions should NOT
PaymentSheet displays the payment price

What do you think are the best practices to follow?

#

@flint pier We are on a tight deadline and need to launch very soon. This is quite urgent for us. Could you please help us look into this as soon as possible?

flint pier
#

Please be patient, we're busy helping others users too

I don't think there's really a perfect solution for you like you describe, though

real lily
#

hi

flint pier
real lily
#

We're building an iOS subscription flow with Stripe API version 2025-12-15.clover and need to handle these scenarios:

  1. Trial subscriptions - User must provide payment method BEFORE starting trial (prevent freeloading)
  2. Non-trial subscriptions - Show the actual price in the mobile payment sheet
  3. Returning users - Allow reusing saved payment methods without re-entering card details
#

Our Implemented Solution

We designed a three-flow approach based on the user's situation:


Flow 1: USE_SAVED_OR_ADD_NEW

When: User has saved payment methods on file

  • Retrieve saved payment methods via paymentMethods.list
  • Use invoices.createPreview to calculate and display the subscription price
  • User can either select a saved card (create subscription directly) or add a new one
  • For trials: still use SetupIntent when adding new cards

Flow 2: SETUP_INTENT

When: No saved payment methods + has trial period

  • Create SetupIntent to collect payment method
  • Use invoices.createPreview to show price in our app UI (not in PaymentSheet)
  • After user confirms, create subscription with the collected payment method
  • Limitation accepted: PaymentSheet itself won't show the amount

Flow 3: PAYMENT_INTENT

When: No saved payment methods + no trial period

  • Create subscription immediately with payment_behavior: 'default_incomplete'
  • Use confirmation_secret from latest_invoice for PaymentSheet
  • PaymentSheet displays the actual charge amount
  • Rollback (cancel subscription) if payment fails

Key Design Decisions

  1. Price display workaround: For trials, we show price in our native UI before opening PaymentSheet, since SetupIntent cannot display amounts by design
  2. Prevent orphan subscriptions: For trials, we do NOT create the subscription until SetupIntent succeeds
  3. Invoice Preview API: Used consistently across all flows to show accurate pricing including discounts and trial information

Is this the level of detail you need, or should I add/clarify anything?

flint pier
#

I'm not sure where the question is? Your colleague was asking if there's a way to display the pricing in the payment sheet when there's a trial and, AFAIK, the answer is no
You need to use the two-step flow (linked above) to get that

real lily
#

As my colleague mentioned, these issues we're facing should be quite common. Is my proposed solution considered a recommended practice?

viral badgeBOT
flint pier
#

Yeah, looks good to me

real lily
#

One last question: Are there other customers who have encountered similar issues to ours, and have they also adopted a solution like the one I described above? As a first-time Stripe integrator, Iโ€™m very concerned about following best practices.

river sedge
#

๐Ÿ‘‹ Hey, taking over here as my colleague has had to step away, just taking a look to familiarize myself with your approach

#

I'm not familiar with a lot of use cases that are exactly the same as yours, but as ynnoj mentioned, the approach seems sound, and there wouldn't be any alternative recommended best practice to achieve this, so you should be good to go