Vue Use Stripe
Vue Use Stripe is a lightweight (0.7 KB gzipped) Vue 3 wrapper for Stripe.js, providing a Composition API hook (`useStripe`) and a `StripeElement` component to simplify the integration of Stripe Elements. It is written in TypeScript and ships with comprehensive type definitions. The library currently stands at version 0.1.1 and has a relatively stable, though infrequent, release cadence, primarily focusing on minor enhancements and bug fixes. A key differentiator is its support for both Vue 2 (via `vue-demi` and `@vue/composition-api`) and Vue 3, allowing for broader compatibility in existing projects. It primarily focuses on exposing Stripe's functionalities through reactive Vue constructs, rather than introducing complex abstractions, making it a thin and flexible layer over the official Stripe.js library.
Common errors
-
TypeError: Cannot read properties of null (reading 'confirmCardSetup')
cause The `stripe` instance is `null` because Stripe.js has not finished loading or initializing when `useStripe` is called.fixEnsure Stripe.js is loaded and the component has mounted before attempting to use the `stripe` object. The `stripe` ref provided by `useStripe` is reactive, so watch for its value to become non-null. -
Component is missing template or render function.
cause When using `StripeElement`, you must correctly assign the `element` prop with a reactive Stripe element instance obtained from `useStripe`.fixEnsure your `StripeElement` component has `:element="cardElement"` (or similar) where `cardElement` is one of the reactive elements returned by `useStripe`.
Warnings
- gotcha To ensure proper TypeScript type inference for Stripe objects, you should install `@stripe/stripe-js`. Even if you load Stripe.js via a script tag, installing this package as a `devDependency` is crucial for types.
- gotcha When using Vue 2, you must explicitly install `@vue/composition-api` to enable the Composition API features that `vue-use-stripe` relies on. This package is marked as an optional peer dependency for npm, but functionally required for Vue 2 projects.
- gotcha Stripe.js must be loaded before `vue-use-stripe` can initialize. This can be done by including the Stripe.js script tag in your `index.html` or by importing `@stripe/stripe-js` as a side effect in your entry file.
Install
-
npm install vue-use-stripe -
yarn add vue-use-stripe -
pnpm add vue-use-stripe
Imports
- useStripe
const { useStripe } = require('vue-use-stripe')import { useStripe } from 'vue-use-stripe' - StripeElement
import { StripeElement } from 'vue-use-stripe' - Stripe
import type { Stripe } from '@stripe/stripe-js'
Quickstart
import { defineComponent, ref } from 'vue'
import { useStripe, StripeElement } from 'vue-use-stripe'
export default defineComponent({
components: { StripeElement },
setup() {
const event = ref(null)
const { stripe, elements: [cardElement] } = useStripe({
key: process.env.VUE_APP_STRIPE_PUBLIC_KEY ?? '',
elements: [{ type: 'card', options: {} }],
})
const registerCard = async () => {
if (event.value?.complete && stripe.value && cardElement.value) {
// Example: Confirm card setup. Replace with your actual Stripe API call.
// Ensure a client secret is provided from your backend.
const { setupIntent, error } = await stripe.value.confirmCardSetup(
'<YOUR_CLIENT_SECRET_FROM_BACKEND>', // Replace with actual client secret
{
payment_method: {
card: cardElement.value,
},
}
)
if (error) {
console.error('Error confirming card setup:', error.message)
} else if (setupIntent) {
console.log('Card setup successful:', setupIntent)
// Send setupIntent.id to your server for further processing
}
}
}
return {
event,
cardElement,
registerCard,
}
},
template: `
<div>
<StripeElement :element="cardElement" @change="event = $event" />
<button @click="registerCard">Add Card</button>
<div v-if="event && event.error" style="color: red;">{{ event.error.message }}</div>
<div v-else-if="event && event.complete">Card input complete.</div>
</div>
`
})