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
npm install @vue-stripe/vue-stripe@^6 @stripe/stripe-js@^10Already 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.
// 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.x | v6.0 | Reason |
|---|---|---|
@stripe/stripe-js ^7.5 || ^8.5 | ^10.0.0 | Stripe.js Endive |
vue ^2.6 || ^3 | ^2.7 || ^3 | v6 relies on expose and useSlots; Vue 2.6 is end-of-life |
| No stylesheet export | import '@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, VueStripeFpxBankElement | VueStripePaymentElement | Stripe removed these elements (Clover) |
<VueStripeElements :payment-method-types> | Mode-based flow: :options="{ allowedPaymentMethodTypes }". clientSecret flow: allowed_payment_method_types on the Intent, or Dashboard settings | Stripe removed the option (Endive) |
Server: payment_method_types when creating PaymentIntents, SetupIntents and Checkout Sessions | allowed_payment_method_types, or no parameter so your Dashboard settings decide (step 4) | Stripe removed the parameter (Endive) |
@loaderstop on VueStripePaymentElement | Removed | Stripe never emitted this event |
@loadError on VueStripeAddressElement | @loaderror | Same 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, ... }), LegacyCheckoutOptions | redirectToCheckout({ 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 accepted | initCheckout 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 then | The 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 methods | checkout 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 type | StripeCheckoutElementsSdk / StripeCheckoutLoadActionsSuccess from @stripe/stripe-js | Same |
VueStripeLoadError, createVueStripeError | Removed; catch the typed error classes (VueStripeProviderError, VueStripeElementsError, VueStripeCheckoutError) | Never thrown by the library |
Address state formatted for the locale | Latin characters by default; getValue({ format: 'localized' }) for the old behaviour | Stripe changed the default (Dahlia) |
Link Authentication markup: vue-stripe-link-auth-element, vue-stripe-link-auth-loading | vue-stripe-link-auth-mount, vue-stripe-link-auth-loader | All 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.
<!-- 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.
<!-- v5 -->
<VueStripeCheckout :session-id="sessionId" />
<!-- v6 -->
<VueStripeCheckout :session-url="session.url" />See Redirect to Stripe Checkout for the server code.
Checkout Sessions with Elements
<!-- 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:
loadingfromuseCheckoutSession()(and the default slot'sloadingprop) istrue.sessionandactionsarenull.- Every action resolves to
{ type: 'error', error: { message: 'Checkout session is not ready yet' } }. It does not throw and logs nothing. #loadingis not shown: it covers only the Stripe.js load. Useloadingfor 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:
// 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:
Replace
payment_method_types. Endive rejects it when you create a PaymentIntent, SetupIntent or Checkout Session: "Thepayment_method_typesparameter is no longer supported". Pass the same list asallowed_payment_method_types, or drop the parameter so your Dashboard payment method settings decide. Clover already acceptsallowed_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'] })Upgrade the
stripepackage and renameui_modein the same change. Runnpm install stripe@^23. Clover rejectsui_mode: 'elements'("you must upgrade to Stripe API version 2026-03-25.dahlia"), and Dahlia and later rejectui_mode: 'custom'("Useelementsinstead"), so neither value works on both sides of the upgrade. The same goes forui_mode: 'embedded', which became'embedded_page'. If your code pins a version withnew 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 uses2026-09-30.endive.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
stripepackage'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-jsis^10,vueis^2.7or^3 - [ ]
@vue-stripe/vue-stripe/style.cssis imported once - [ ] No
apiVersiononVueStripeProvideror increateVueStripe() - [ ] No iDEAL / P24 / EPS / FPX element components remain; the Payment Element collects those methods
- [ ] No
payment-method-typesprop onVueStripeElements - [ ]
VueStripeCheckoutgetssession-url; the server creates the session - [ ]
VueStripeCheckoutProvideris renamed, and its@readyhandler takesactions - [ ] Code that calls a Checkout Session action on mount waits for
@readyor foractionsfromuseCheckoutSession() - [ ] The server sends no
payment_method_types - [ ] The server runs
stripe23 (API version2026-09-30.endive) and creates Checkout Sessions withui_mode: 'elements' - [ ]
@loadErrorbecame@loaderror;@loaderstopis gone - [ ] CSS that targets
vue-stripe-link-auth-element/-loadinguses-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 aVueStripeProvider. In v6 the plugin loads Stripe.js the first time something needs it, so element components,VueStripeElementsand the composables work without a provider. Pages that use the plugin's key can drop theirVueStripeProvider. See Provide Stripe app-wide. - Element components inside Checkout Sessions. Inside
VueStripeCheckoutElementsProvider,VueStripePaymentElement,VueStripeAddressElement,VueStripeExpressCheckoutElementand others mount from the session, in place ofcheckout.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.jsconfirm<Method>Paymentandconfirm<Method>Setupmethod. - New events and actions:
@changeonVueStripeCheckoutElementsProvider, andactions,validateElements(),loadFonts()and the element getters (getPaymentElement(), ...) onuseCheckoutSession().
The API reference lists every export, and Stripe.js coverage shows which export wraps each Stripe.js 10 element and method.
