Skip to content
Create account or Sign in
The Stripe Docs logo
/
Ask AI
Create accountSign in
Get started
Payments
Revenue
Platforms and marketplaces
Money management
Developer resources
APIs & SDKsHelp
Overview
About Stripe payments
Upgrade your integration
Payments analytics
Online payments
OverviewFind your use caseUse Managed Payments
Use Payment Links
Use a pre-built checkout page
Build a custom integration with Elements
Build an in-app integration
    Overview
    Payment Sheet
    Payment Element
    Address Element
    Link out for in-app purchases
    Manage payment methods in settings
    Migrate to Confirmation Tokens
    US and Canadian cards
In-person payments
Terminal
Payment Methods
Add payment methods
Manage payment methods
Faster checkout with Link
Payment scenarios
Handle multiple currencies
Custom payment flows
Flexible acquiring
Orchestration
Beyond payments
Incorporate your company
Crypto
Agentic commerce
Financial Connections
Climate
Understand fraud
Radar fraud protection
Manage disputes
Verify identities
United States
English (United Kingdom)
HomePaymentsBuild an in-app integration

Migrate to Confirmation Tokens

Use a ConfirmationToken instead of a PaymentMethod to handle payments

This guide demonstrates how to migrate from the legacy PaymentMethod to the ConfirmationToken in your mobile integration.

You can use the ConfirmationToken object instead of the PaymentMethod to:

  • Simplify server-side code: You won’t need to manually construct mandate_data or pass return_url and shipping when you confirm intents.
  • Handle data: It automatically includes shipping information and other payment context for you.
FeaturePaymentMethod (Legacy)ConfirmationToken
Payment confirmation
Set up future usageManualAutomatic
Shipping informationManualAutomatic
Mandate dataManualAutomatic
Return URLManualAutomatic
Server-side CVC recollection

Before you begin

This guide assumes you have an existing mobile integration using the legacy PaymentMethod. If you’re building a new integration, follow the Accept a payment guide which uses ConfirmationTokens by default.

Update your client code
Client-side

To access and use payment details, pass a callback that receives a confirmationToken:

let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD") ) { paymentMethod, shouldSavePaymentMethod, intentCreationCallback in // Make a request to your server, passing paymentMethod.stripeId ) { confirmationToken, intentCreationCallback in // Make a request to your server to create a PaymentIntent and return its client secret. // Optionally pass confirmationToken.stripeId if doing server-side confirmation. let myServerResponse: Result<String, Error> = ... switch myServerResponse { case .success(let clientSecret): intentCreationCallback(.success(clientSecret)) case .failure(let error): intentCreationCallback(.failure(error)) } }

Update your server code
Server-side

When you accept payments, you can choose where to confirm the PaymentIntent or SetupIntent:

  • Client-side confirmation: Your server creates an unconfirmed Intent and returns its client_secret to your app. The mobile SDK then confirms the Intent directly to Stripe.

  • Server-side confirmation: Your app sends the ConfirmationToken to your server, which both creates and confirms the Intent in a single API call by setting confirm: true. The confirmation happens entirely on your server when you call the Stripe API, and provides you with more control over the payment flow.

Create the PaymentIntent or SetupIntent by excluding payment_method, return_url, mandate_data and shipping. The mobile SDK handles confirmation on the client side using the ConfirmationToken:

app.post('/create-intent', async (req, res) => { try { const args = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true}, // No longer needed - ConfirmationToken provides these automatically payment_method: req.body.paymentMethodId, return_url: 'your-app://stripe-redirect', mandate_data: { customer_acceptance: { type: "online", online: { ip_address: req.ip, user_agent: req.get("user-agent"), }, }, }, shipping: { name: 'Jenny Rosen', address: { line1: '1234 Main Street', city: 'San Francisco', state: 'CA', postal_code: '94111', country: 'US', }, }, }; const intent = await stripe.paymentIntents.create(args); res.json({ client_secret: intent.client_secret }); } catch (err) { res.status(err.statusCode).json({ error: err.message }); } });

Any parameters that you provide directly to the PaymentIntent or SetupIntent at confirmation time, such as shipping, override the corresponding properties on the ConfirmationToken.

Note

If you previously inspected the PaymentMethod object, you can now access payment method details through the paymentMethodPreview property on the ConfirmationToken.

See also

  • Accept a payment
  • Finalise payments on the server
  • ConfirmationToken API reference
Was this page helpful?
YesNo
  • Need help? Contact Support.
  • Check out our changelog.
  • Questions? Contact Sales.
  • LLM? Read llms.txt.
  • Powered by Markdoc