Level up your integration with SetupIntents
Stripe tries to make payments as easy as can be, but sometimes it can be a bit overwhelming with all the industry terms and APIs available to you. This Stripe Payment Fundamentals series is a blog where we tackle a fundamental topic each time and explain them in simple terms.
This week, Paul Asjes will explain what SetupIntents are, how they work and why you’d want to use them.
Just what are SetupIntents?
Remember PaymentIntents from our previous article? They are what you’d use if you wish to make a payment immediately. SetupIntents are similar, but solve a different use case. You’d use them to set up a future payment rather than take an immediate one. Setting one up for future use means you can handle any authentication the eventual payment might require before the payment is even created. We’ll cover this more in detail below.
How do I use them?
Almost exactly the same way you’d use a PaymentIntent! The APIs were built to overlap and provide some similarity, so if you’re familiar with the PaymentIntents API you should have no problem implementing SetupIntents.
Consider the following hypothetical scenarios:
Scenario A - Buy now, pay later
Say you are a business who sells physical goods online. Your business model requires that your users be able to put in an order, but only pay once the goods have actually shipped. You’d probably want to do this if you weren’t sure about stock levels when the order was put in. In this scenario, you want to collect their payment method details right away, but you don’t want to charge them immediately.
It’s easy enough to collect those details, save them to a customer and then attempt to create a PaymentIntent at a later time, but what if the cardholder’s bank requires additional authentication for the payment to succeed? You then would need to get your user back “on-session” (i.e. back on your website or app) to authenticate and confirm the payment. For more information, check out our previous article that discussed SCA and 3DS.
💡 “On-session” is when your user is present your website or app, whereas “off-session” is when they’re not. Getting a user back “on-session” means getting them to return to your website or app, for example via email or notification.
This is where SetupIntents come in. Just like PaymentIntents, SetupIntents can be confirmed and trigger a 3DS modal for your users to authenticate. They key difference between the two is that PaymentIntents actually move funds, whereas SetupIntents don’t. Instead SetupIntents ensure that the next non-zero payment made with that PaymentMethod will not require 3DS, meaning a PaymentIntent (which will move funds) can be created and confirmed without needing involvement from your user.
Note how the off-session flow doesn’t require any input from your user.
Here’s a table to further demonstrate the difference between PaymentIntents and SetupIntents:
PaymentIntents | SetupIntents | |
---|---|---|
Triggers 3DS | Yes | Yes |
Lets you defer payment | No | Yes |
Used to move funds | Yes | No |
💡 Deferment is different from separate auth & capture, in which flow you’d authorize funds and capture them at a later date. In the case of SetupIntents you’d authorize any non-zero future payment rather than authorize a specific amount.
The gif above shows an tinydemo example of what the SetupIntent flow would look like to a customer.
Before we wrap up, let’s consider one more scenario. This one builds off of Scenario A earlier, but shows how you can use a mix of SetupIntents and PaymentIntents to streamline your payments page.
Scenario B - Dynamically determine when to pay
Let’s think back to Scenario A, where you have a company that only wishes to take payment once the order has shipped. While that scenario works, you might want to minimise the risk of failed payments by checking your stock levels first. Say a customer clicks the buy button on your site, your business logic could then first check whether the items in question are actually in stock and ready to be shipped. If yes, then create a PaymentIntent and let the customer pay immediately. If they aren’t in stock (but will be soon), create a SetupIntent instead with the intention of completing the payment off-session later.
Let’s look at another scenario where SetupIntents are frequently used.
Scenario C - Trial periods on subscriptions
Now imagine that your business offers a subscription based product. In order to drive adoption and get more paying customers, you decide to offer the first month of a new subscription for free. In a normal flow you’d create the subscription with the payment details and the first invoice would immediately trigger a payment. If the payment succeeds the subscription is activated and all is well. In the case of a trial period however you don’t want to charge anything up front. Instead you want to collect those payment details but wait till the first free month is over before making the off-session payment on the first invoice.
This is where SetupIntents shine again. If you didn’t use them to set up the payment method, then it’s possible that when the trial period completes and the first invoice is created, the payment fails due to the card requiring 3DS. In which case you’d have to bring your user back on-session to complete said payment, adding friction and creating the real possibility that your user simply doesn’t bother to do so. Using a SetupIntent when creating the subscription ensures that when that first invoice rolls around after the trial period, the payment can successfully be made off-session.
Anything I should be aware of?
While SetupIntents work remarkably well in the scenarios described above, there are a few things to watch out for when implementing them.
Issuing banks are the definitive authority on authorization
The benefit of SetupIntents is that you can get the business of authenticating a payment out of the way without actually creating a payment. It’s very important to note however that while Stripe will do its best to apply for the exception with the successful confirmation of a SetupIntent, the ultimate decision on whether a transaction requires authentication lies with the issuing bank.
This effectively means that even though you correctly set up a PaymentMethod to be used later, it’s still possible (but rare) that the payment requires authentication before it can be completed.
As such you must always have a plan for how to get users back on-session to complete payments, even if you do everything correctly with SetupIntents. If you don’t you run the risk of abandoned payments and loss of revenue.
PaymentIntents can be used to set up future payments too!
You don’t always need SetupIntents for future off-session payments. In scenarios where you want to take a payment immediately up front, but then take subsequent payments at a later date off-session, you can do that by instructing Stripe when creating the initial PaymentIntent.
Now that you know about SetupIntents and what they are for, you can level up your Stripe integration by ensuring the smoothest experience for your users and your bottom line.
Related resources
SetupIntents example [tinydemo]
The SetupIntents API [doc]
Setting up Future Payments [doc]
Setup future payments with Checkout [video]
Next up: Digital Wallets
In our next post in the Stripe Payment Fundamentals series, we’ll introduce Digital Wallets like Apple and Google Pay.
In the meanwhile, you can stay up to date with Stripe in a few ways:
📣 Follow us on Twitter
💬 Join the official Discord server
📺 Subscribe to our Youtube channel
📧 Sign up for the Dev Digest