Skip to content

Upgrade from v5 to v6 ​

Move a working Vue Stripe 5 app to Vue Stripe 6, which runs on Stripe.js 10 (API version Endive). Most breaking changes follow Stripe: elements and methods that Stripe removed are gone here too, and Checkout Sessions with Elements use the new Checkout Elements SDK.

Before you begin ​

  • Your app runs on Vue 2.7 or Vue 3. Vue 2.6 is no longer supported; upgrade to 2.7 first (see Use Vue Stripe on Vue 2.7).
  • Note which Vue Stripe components, props and composables your app uses, so you can match them against the table in step 3.
  • Find the server routes that create PaymentIntents, SetupIntents or Checkout Sessions, and the version of your server's Stripe library. Step 4 updates them.

1. Update the packages ​

bash
npm install @vue-stripe/vue-stripe@^6 @stripe/stripe-js@^10

Already on a v6 beta?

The range ^6 installs 6.0.0 and later 6.x releases. An app on a ^6.0.0-beta.* range also moves to the latest 6.x with npm update.

2. Import the stylesheet ​

v5 had no stylesheet export. v6 ships the component styles as style.css; without it, the loading and error states and the element wrappers are unstyled.

ts
// main.ts: once, anywhere before the components render
import '@vue-stripe/vue-stripe/style.css'

3. Replace what changed ​

Work through the table row by row. The last column gives the reason in short; Stripe.js versions has the background for each Stripe-driven change.

v5.xv6.0Reason
@stripe/stripe-js ^7.5 || ^8.5^10.0.0Stripe.js Endive
vue ^2.6 || ^3^2.7 || ^3v6 relies on expose and useSlots; Vue 2.6 is end-of-life
No stylesheet exportimport '@vue-stripe/vue-stripe/style.css'Render-function components carry no styles of their own
apiVersion on VueStripeProvider (prop or options.apiVersion) and in createVueStripe()Remove it. v6 ignores it and logs a [Vue Stripe] warning; Stripe.js 10 always uses its own API version. Your server sets the API version (step 4)Versioned Stripe.js refuses apiVersion (API version)
VueStripeIdealBankElement, VueStripeP24BankElement, VueStripeEpsBankElement, VueStripeFpxBankElementVueStripePaymentElementStripe removed these elements (Clover)
<VueStripeElements :payment-method-types>Mode-based flow: :options="{ allowedPaymentMethodTypes }". clientSecret flow: allowed_payment_method_types on the Intent, or Dashboard settingsStripe removed the option (Endive)
Server: payment_method_types when creating PaymentIntents, SetupIntents and Checkout Sessionsallowed_payment_method_types, or no parameter so your Dashboard settings decide (step 4)Stripe removed the parameter (Endive)
@loaderstop on VueStripePaymentElementRemovedStripe never emitted this event
@loadError on VueStripeAddressElement@loaderrorSame casing as Stripe and the other elements
<VueStripeCheckout :session-id> / :price-id (with mode, success-url, cancel-url, customer-email, ...)<VueStripeCheckout :session-url>Stripe removed redirectToCheckout({ sessionId }) (Clover)
useStripeCheckout().redirectToCheckout({ sessionId }) / ({ lineItems, ... }), LegacyCheckoutOptionsredirectToCheckout({ url }) (typed CheckoutRedirectOptions) or redirectToUrl(url)Same
<VueStripeCheckoutProvider :client-secret="string"><VueStripeCheckoutElementsProvider :client-secret="stringOrPromise">. The old name is a deprecated alias, and fetchClientSecret is still acceptedinitCheckout became initCheckoutElementsSdk
VueStripeCheckoutProvider @ready(checkout)@ready(actions), plus a new @change(session)Session methods moved to loadActions()
VueStripeCheckoutProvider renders its default slot once the session is ready, and #loading until thenThe default slot renders before the session's actions load, and #loading shows only while Stripe.js loads. Actions called before @ready resolve to an error (Checkout Sessions with Elements)Stripe.js creates the Checkout SDK synchronously (Clover)
useCheckoutSession().checkout is a StripeCheckout with the session methodscheckout is a StripeCheckoutElementsSdk; session methods are on actions (and still forwarded by useCheckoutSession())Same
Checkout Session ui_mode: 'custom'ui_mode: 'elements', which needs API version 2026-03-25.dahlia or later on your server (step 4)Stripe renamed the value (Dahlia)
StripeCheckout typeStripeCheckoutElementsSdk / StripeCheckoutLoadActionsSuccess from @stripe/stripe-jsSame
VueStripeLoadError, createVueStripeErrorRemoved; catch the typed error classes (VueStripeProviderError, VueStripeElementsError, VueStripeCheckoutError)Never thrown by the library
Address state formatted for the localeLatin characters by default; getValue({ format: 'localized' }) for the old behaviourStripe changed the default (Dahlia)
Link Authentication markup: vue-stripe-link-auth-element, vue-stripe-link-auth-loadingvue-stripe-link-auth-mount, vue-stripe-link-auth-loaderAll elements now share one markup (step 5)

Payment method types on VueStripeElements ​

allowedPaymentMethodTypes works when VueStripeElements gets mode / currency / amount instead of a client secret, and in elements.update(). With a clientSecret, Stripe reads the payment methods from the Intent, so set allowed_payment_method_types on the PaymentIntent or SetupIntent on your server, or manage them in the Dashboard.

vue
<!-- v5 -->
<VueStripeElements :client-secret="clientSecret" :payment-method-types="['card', 'klarna']">

<!-- v6, mode-based -->
<VueStripeElements
  mode="payment"
  currency="usd"
  :amount="1099"
  :options="{ allowedPaymentMethodTypes: ['card', 'klarna'] }"
>

Hosted Checkout ​

Create the session on your server and pass its url. Session settings that were props in v5 move to stripe.checkout.sessions.create() on your server: line_items, mode, success_url, cancel_url, customer_email, client_reference_id and submit_type. If your session code passes payment_method_types, step 4 replaces it. VueStripeCheckout no longer needs VueStripeProvider around it.

vue
<!-- v5 -->
<VueStripeCheckout :session-id="sessionId" />

<!-- v6 -->
<VueStripeCheckout :session-url="session.url" />

See Redirect to Stripe Checkout for the server code.

Checkout Sessions with Elements ​

vue
<!-- v5 -->
<VueStripeCheckoutProvider :client-secret="clientSecret" @ready="(checkout) => ...">

<!-- v6 -->
<VueStripeCheckoutElementsProvider
  :client-secret="clientSecretPromise"
  @ready="(actions) => ..."
>

Inside the provider, useCheckoutSession() keeps the v5 method names (confirm, applyPromotionCode, updateEmail, ...). What changed is when they work.

In v5 the provider showed #loading until the session was ready and rendered your form after that. In v6 it renders your form as soon as Stripe.js has loaded, so elements can mount while the session loads, and the session's actions arrive later. Until the provider emits @ready:

  • loading from useCheckoutSession() (and the default slot's loading prop) is true.
  • session and actions are null.
  • Every action resolves to { type: 'error', error: { message: 'Checkout session is not ready yet' } }. It does not throw and logs nothing.
  • #loading is not shown: it covers only the Stripe.js load. Use loading for a spinner while the session loads.

A v5 form that calls an action when it mounts, such as updateEmail() for a signed-in customer, now gets that error and the email is never set, so session.canConfirm stays false. Run the call once the actions have loaded:

ts
// v5: the form mounted after the session was ready
const { updateEmail } = useCheckoutSession()

onMounted(() => updateEmail(user.email))

// v6: wait for the actions
const { actions, updateEmail } = useCheckoutSession()

watch(
  actions,
  (ready) => {
    if (ready) updateEmail(user.email)
  },
  { immediate: true }
)

The provider's @ready handler works too, since it receives the actions: @ready="(actions) => actions.updateEmail(user.email)". Read session with a null check, and keep buttons that call actions disabled while loading is true. The provider's Slots section has the details.

A Payment Element that v5 code created itself with checkout.createPaymentElement() still mounts, because checkout exists from the first render. A session created with return_url must be confirmed without returnUrl; Stripe rejects a second one. See Build your own checkout page on a Checkout Session.

4. Update your server ​

The v6 guides write their server code for the Node.js stripe package 23, which uses API version 2026-09-30.endive, the same release train as Stripe.js 10. A v5 server usually runs an older package on a Clover API version (stripe 19 uses 2025-10-29.clover), and two of its calls break on the way to Endive. Make these changes in this order:

  1. Replace payment_method_types. Endive rejects it when you create a PaymentIntent, SetupIntent or Checkout Session: "The payment_method_types parameter is no longer supported". Pass the same list as allowed_payment_method_types, or drop the parameter so your Dashboard payment method settings decide. Clover already accepts allowed_payment_method_types, so you can deploy this change before the others.

    js
    // v5
    const setupIntent = await stripe.setupIntents.create({ payment_method_types: ['card'] })
    
    // v6
    const setupIntent = await stripe.setupIntents.create({ allowed_payment_method_types: ['card'] })
  2. Upgrade the stripe package and rename ui_mode in the same change. Run npm install stripe@^23. Clover rejects ui_mode: 'elements' ("you must upgrade to Stripe API version 2026-03-25.dahlia"), and Dahlia and later reject ui_mode: 'custom' ("Use elements instead"), so neither value works on both sides of the upgrade. The same goes for ui_mode: 'embedded', which became 'embedded_page'. If your code pins a version with new Stripe(key, { apiVersion }), set it to '2026-09-30.endive' or remove it. On another server language, upgrade its Stripe library to a release that uses 2026-09-30.endive.

  3. Check the rest of your server code. The move from Clover to Endive crosses the Dahlia and Endive API releases. Stripe's API changelog lists their breaking changes, and the stripe package's changelog lists changes to its own methods and types.

The browser side accepts sessions from either server version: v5 confirms a ui_mode: 'elements' session, and v6 confirms a ui_mode: 'custom' session. You can deploy the browser and server changes in either order.

5. Check your CSS ​

Every element component now renders the same markup: a vue-stripe-<name>-element wrapper with -error, -mount and -loader children, plus shared vue-stripe-element* classes. The element-specific class names match v5 for every element except Link Authentication (see the last row of the table). If your CSS targets the old Link Authentication classes, rename them.

Checklist ​

  • [ ] @stripe/stripe-js is ^10, vue is ^2.7 or ^3
  • [ ] @vue-stripe/vue-stripe/style.css is imported once
  • [ ] No apiVersion on VueStripeProvider or in createVueStripe()
  • [ ] No iDEAL / P24 / EPS / FPX element components remain; the Payment Element collects those methods
  • [ ] No payment-method-types prop on VueStripeElements
  • [ ] VueStripeCheckout gets session-url; the server creates the session
  • [ ] VueStripeCheckoutProvider is renamed, and its @ready handler takes actions
  • [ ] Code that calls a Checkout Session action on mount waits for @ready or for actions from useCheckoutSession()
  • [ ] The server sends no payment_method_types
  • [ ] The server runs stripe 23 (API version 2026-09-30.endive) and creates Checkout Sessions with ui_mode: 'elements'
  • [ ] @loadError became @loaderror; @loaderstop is gone
  • [ ] CSS that targets vue-stripe-link-auth-element / -loading uses -mount / -loader

What's new in v6 ​

These additions need no changes to v5 code:

  • The plugin provides Stripe app-wide. In v5, createVueStripe() only stored the key, and every page still needed a VueStripeProvider. In v6 the plugin loads Stripe.js the first time something needs it, so element components, VueStripeElements and the composables work without a provider. Pages that use the plugin's key can drop their VueStripeProvider. See Provide Stripe app-wide.
  • Element components inside Checkout Sessions. Inside VueStripeCheckoutElementsProvider, VueStripePaymentElement, VueStripeAddressElement, VueStripeExpressCheckoutElement and others mount from the session, in place of checkout.createPaymentElement() calls (Elements inside the provider).
  • New elements: Tax ID, Currency Selector, Contact Details, Terms and Link Signup (the last two are Stripe betas), the Issuing elements, and the Issuing, Treasury and Financial Account disclosures.
  • New Checkout integrations: VueStripeEmbeddedCheckout, and the Checkout Form (VueStripeCheckoutFormProvider, VueStripeCheckoutForm, useCheckoutForm(), a Stripe beta).
  • New composables: useCreateConfirmationToken, useCreateToken, useHandleCardAction, useVerifyMicrodepositsForPayment, useVerifyMicrodepositsForSetup, useRadarSession, useEphemeralKeyNonce, useFinancialConnections, useIdentity, usePaymentRequest, and one method confirmer per Stripe.js confirm<Method>Payment and confirm<Method>Setup method.
  • New events and actions: @change on VueStripeCheckoutElementsProvider, and actions, validateElements(), loadFonts() and the element getters (getPaymentElement(), ...) on useCheckoutSession().

The API reference lists every export, and Stripe.js coverage shows which export wraps each Stripe.js 10 element and method.