stripe-react-native
stripe-react-native copied to clipboard
PaymentSheet and subscription
Feature request: I'd like to be able to use PaymentSheet to offer subscriptions to my users. I know stripe discourage doing so because in most cases, subscriptions should use in app purchases. There are a few edge cases where this does not apply. In my case, we checked with both google and apple and no in-app purchase is required. That's why (for now at least), I'd like to use stripe to handle subscriptions on my react-native app as well.
Describe the solution you'd like So far, if we want to use PaymentSheet as is, we need to create a subscription PRIOR any card form to get paymentIntent/setupIntent that we can provide to paymentSheet. This works fine after some tries and I'm able to get working scenarios with PaymentSheet that way. Subscription are created as "incomplete" and are set as active when users validate their card / payment. Great.
A major problem arises as soon as you use "trial" period, or a coupon that makes it "free" for the first payment. The subscription created before paymentSheet is set to active so this is no a valid workflow. If user stops there in its process, we need to cancel that subscription and hence increase our churn rate or decrease our trial activation rate. That's a double no-go.
Describe alternatives you've considered I've considered using setupIntent to attach a card to a customer via paymentSheet and only after that, create the subscription with some custom logic but that seems pretty weird. As a fallback, I use the CardFormField to retrieve a cardToken and create subscriptions with it.
I really would like to be able to build upon PaymentSheet to ease integration with google pay / apple pay and so forth.
Additional context I'm a user from tipsi-stripe and have followed all changes since the beginning on that lib. Thanks for all that work.
Hi! Great request, I think this is something you can do now :) I just went through and tested it myself.
With a trial period, you should be able to use the subscription's pending_setup_intent
. Retrieve that setup intent's client_secret
, and pass that to initPaymentSheet
under setupIntentClientSecret
. Let me know if that works for you!
Hi @charliecruzan-stripe, thanks for your answer. I think I wasn't clear the first time, I apologize. Your answer isn't what I'm looking for.
I already have a successful PaymentSheet + subscriptions scenario. Like you said, we can achieve this with payment_intent
or pending_setup_intent
.
My problem is that subscriptions are created BEFORE users add their cards. One example: With a trial period, subscription is created with an "trial" status whereas user has not entered his card yet. If this user leaves the paymentSheet at this point (before completing), he is considered subscribed but no card has been registered and that person will churn a few days later. It's quite common for users to open the paymentSheet and drop before paying. (sadly) If this creates an "active" (or "trial") subscription, this will be disastrous for our stripe churn rate or our trial activation rate. Those are two key metrics for us. And probably for most people. Another consequence: users can be led to subscribe many times without them knowing (if they open numerous time the PaymentSheet). This is a bit of a nightmare scenario, this can't be the way to do so. I don't think canceling by hand subscriptions if users closes their PaymentSheet is the way to go. (And it still affects our churn rate)
We can't force subscriptions to be in an "incomplete" state (for trial periods and/or coupons that makes it 0€ for first payment). That's why I'm looking for a better solution with PaymentSheet and subscriptions. I hope this is clearer now :/
I see, so what you want is for the subscription object to be created after submitting the payment sheet? Essentially just using the payment sheet to create a payment method & attach it to a customer?
YES, I'd like subscription to be created afterwards. I'd like to provide all necessary data to the PaymentSheet and subscription to be created after card or payment method has been correctly attached to the customer.
I guess I could use paymentSheet to add a card and then manually add the subscription but half the value of the paymentSheet is lost : display the final price to pay, provide a unique and complete payment workflow etc.
Is this what you suggest ? It does not really provide more value than the cardField form if it's used that way.
Thanks again for your time (I deleted my previous answers to be more accurate and concise)
We're looking into better supporting subscriptions in the PaymentSheet, but I don't have a timeline for that.
You could go that route, yes. PaymentSheet still provides you with the UI and the ability to collect all of the other supported payment methods in addition to cards (whereas obviously CardField only helps you collect card details), but I see your point that you're missing out on some of the value of Payment Sheet in that situation
Hi there, I fail to see how "apple pay line items" stuff solves any of the above problems. Sorry if I missed something. I've had a look to the changelog as well with no luck.
Oh- there was a separate issue where Apple was rejecting some apps if the subscription amount was "Pending" in Apple Pay in the Payment Sheet. Sorry, I must have mistakenly correlated this issue with the PR. my bad @adrien-may
Hi, we are facing the same issue so is there any solution ? When creating a trial we use the following:
const subscription = await stripe.subscriptions.create({ customer: customerId, items: [ { price: priceId, }, ], payment_behavior: "default_incomplete", payment_settings: { save_default_payment_method: "on_subscription" }, expand: ["pending_setup_intent"], trial_period_days: 7, }); res.send({ subscriptionId: subscription.id, clientSecret: subscription?.pending_setup_intent?.client_secret, });
This leads to the subscription being paid just by opening the payment sheet. We would like to keep it incomplete until the user fills his card details and clicks the button to setup the trial.
I tried to use the setupIntent but I did not succeed in making it work.
Thank you.
in my code subscription?.pending_setup_intent this is null can anybody knows why