Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Migrate to Confirmation Tokens


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
Setup 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
) { confirmationToken in
 try await withCheckedThrowingContinuation() { continuation in
 // If you send paymentMethod.stripeId to your server, send confirmationToken.stripeId instead.
 let myServerResponse: Result<String, Error> = ... // Make a request to your server
 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

Last verified 2026-09-24

Is this helpful?