Set up future Link payments
You can use the Setup Intents API and Stripe Elements to set up your payments page for customers with Link payment methods and charge them later. This allows you to charge your customers in the future, when they’re offline.

If you want to save a Link payment method while charging your customer, see how to save Link as a payment method.
Set up StripeServer-side
First, you need a Stripe account. Register now.
Use our official libraries for access to the Stripe API from your application:
Create a Customer before setupServer-side
To set up a payment method for future payments, you must attach it to a Customer. Create a Customer
object when your customer creates an account with your business. Customer objects allow for reusing payment methods and tracking across multiple payments.
Create a SetupIntentServer-side
A SetupIntent is an object that represents your intent to set up a customer’s payment method for future payments during a session and tracks the status of that session. Create a SetupIntent on your server with link
and the other payment methods you want to support:
To see how to set up other payment methods, see the Set up future payments guide.
Included in the returned SetupIntent is a client secret, which the client side uses to securely complete the payment process instead of passing the entire SetupIntent object. You can use different approaches to pass the client secret to the client side.
Decide when to collect email
Link authenticates customer accounts using their email address. Use the Link Authentication Element, an email input Element, to both collect a customer’s email during the payment process and enable your customer to authenticate to Link.
If you previously collected email ahead of the payment process or prefer to use your own email input field, you can pass a customer’s email into the Payment Element. In this scenario, you only integrate the Payment Element, and a customer authenticates to Link directly in the payment form.
Set up your payment formClient-side
Now you can set up your custom payment form with the Elements prebuilt UI components.
The payment page address must start with https://
rather than http://
for your integration to work. You can test your integration without using HTTPS. Enable it when you’re ready to accept live payments.
Submit the SetupIntentClient-side
Use stripe.confirmSetup to complete the setup with the details you collected. Provide a return_url to this function so that Stripe can redirect users after they complete their setup. When a payment is successful, Stripe immediately redirects Link and card payments to the return_url
.
Merchant domain cookieServer-side
To provide your customers with the best experience, you can persist a Link session for your customers and automatically log them in to Link, without additional authentication.
This works automatically for browsers that support persistent third-party local storage, such as Chrome and Firefox. For browsers that don’t, like Safari, you can enable persistent sessions in the three following steps:
- Retrieve a
persistent_token
from SetupIntent after an attempt to confirm the SetupIntent:
- To remember the customer across browser sessions, set a cookie with the
persistent_token
value with the HTTP response on the server side:
- When you create the SetupIntent, pass in the
persistent_token
value as an additional option:
You might need to update the SetupIntent with the persistent_token
value explicitly if you create the SetupIntent before involving the customer in confirming the payment later. You might want to use this type of configuration for recurring charges where you contact customers to confirm their payment.
Privacy implications
You should always check with your legal counsel to understand how you should comply with applicable legal obligations with setting cookies, but this section has the information you should keep in mind.
Based on your integration choice for Link in Elements, Stripe either provides a randomly generated value for you to store in a cookie on your domain (e.g. on your checkout flow domain) or for storage on a local cache on the Stripe domain (which is also considered a cookie from a legal perspective). We use these cookies to help remember the end user on that browser for Link. You should ensure that your own privacy policy tells your end users about this type of data collection, and also update your cookie banner accordingly after reviewing the cookies placed on your website. Here is a paragraph you could add to your privacy policy if it does not already include such a disclosure:
We use Stripe for payment, analytics, and other business services. Stripe collects identifying information about the devices that connect to its services, including via cookies. Stripe uses this information to operate and improve the services it provides to us, including for fraud detection. You can learn more about Stripe and read its privacy policy at https://stripe.com/privacy.
Charge the saved payment method laterServer-side
When you’re ready to charge your customer, use the Customer and PaymentMethod IDs to create a PaymentIntent. To find a payment method to charge, list the payment methods associated with your customer.
When you have the Customer and PaymentMethod IDs, create a PaymentIntent with the amount and currency of the payment with these parameters:
- Set the value of the PaymentIntent’s confirm property to
true
, which causes confirmation to occur immediately when the PaymentIntent is created. - Set payment_method to the ID of the PaymentMethod
- Set customer to the ID of the Customer.
- Set off_session to
true
. This causes the PaymentIntent to send an error if authentication is required when your customer isn’t actively using your site or app.
Test the integration
Don’t store real user data in test mode Link accounts. Treat them as if they’re publicly available, because these test accounts are associated with your publishable key.
Currently Link only works with credit cards, debit cards, and US bank accounts (for qualifying purchases). To give your customers more payment options at checkout, Stripe is working to add additional funding sources to Link. Periodically test your checkout flow to confirm the look and feel of your payments page is what you expect.
You can create test mode accounts for Link using any valid email address. The following table shows the fixed one-time passcode values that Stripe accepts for authenticating test mode accounts:
Value | Outcome |
---|---|
any other 6 digits not listed below | Success |
000001 | Error, code invalid |
000002 | Error, code expired |
000003 | Error, max attempts exceeded |
For testing specific payment methods, refer to the Payment Element testing examples.
Multiple funding sources
Currently, Link only works with credit cards, debit cards, and US bank accounts for qualifying purchases. But as Stripe adds additional funding sources, Link automatically supports them with instant confirmation for your company’s payments, and the same transaction settlement timeline and guarantees as cards and bank account-funded payments. This adaptive support means that you don’t need to update your integration to let your customers save and reuse their preferred payment method on your domain.
To test that your integration can handle additional funding sources, provide an email in the form of {any_prefix}+multiple_funding_sources@{any_domain}
when you’re testing your check out flow with Link.
Card authentication and 3D Secure
Link supports 3D Secure (3DS) authentication for card payments. 3DS requires customers to complete an additional verification step with the card issuer when paying. Payments that have been successfully authenticated using 3D Secure are covered by a liability shift.
To trigger 3DS authentication challenge flows with Link in test mode, use the following test card with any CVC, postal code, and future expiration date:
In test mode, the authentication process displays a mock authentication page. On that page, you can either authorize or cancel the payment. Authorizing the payment simulates successful authentication and redirects you to the specified return URL. Clicking the Failure button simulates an unsuccessful attempt at authentication.
For more details, refer to the 3D Secure authentication page.