Vue Stripe provides composables to access Stripe, Elements, and Checkout instances from within your components. These composables work with the Elements, CheckoutElementsProvider, CheckoutFormProvider, and EmbeddedCheckoutProvider components.
The useStripe composable returns a reference to the Stripe instance passed to the Elements, CheckoutElementsProvider, or CheckoutFormProvider.
<script setup>
import { useStripe } from 'vue-stripe'
const stripe = useStripe()
async function createPaymentMethod() {
if (!stripe.value) {
return
}
const { error, paymentMethod } = await stripe.value.createPaymentMethod({
type: 'card',
card: cardElement,
})
if (error) {
console.error(error.message)
}
else {
console.log('Payment method:', paymentMethod.id)
}
}
</script>
useStripe: () => Readonly<Ref<Stripe | null>>
Use useStripe when you need to:
The useElements composable returns a reference to the Elements instance, which you can use to submit forms and access element instances.
<script setup>
import { PaymentElement, useElements, useStripe } from 'vue-stripe'
const stripe = useStripe()
const elements = useElements()
async function handleSubmit() {
if (!stripe.value || !elements.value) {
return
}
// Trigger form validation and wallet collection
const { error: submitError } = await elements.value.submit()
if (submitError) {
console.error(submitError.message)
return
}
// Get the Payment Element instance
const paymentElement = elements.value.getElement(PaymentElement)
// Continue with payment confirmation
const { error } = await stripe.value.confirmPayment({
elements: elements.value,
clientSecret: '{{CLIENT_SECRET}}',
confirmParams: {
return_url: 'https://example.com/return',
},
})
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<PaymentElement />
<button type="submit">
Pay
</button>
</form>
</template>
useElements: () => Readonly<Ref<StripeElements | null>>
Use useElements when you need to:
getElement()The useCheckoutElements composable returns the Checkout state from CheckoutElementsProvider. It provides access to the Checkout instance and session data.
useCheckout still works under both CheckoutElementsProvider and CheckoutFormProvider, but it is deprecated. Prefer useCheckoutElements() or useCheckoutForm(), which return the exact action surface their SDK exposes. See the Checkout guide for both providers.<script setup>
import { useCheckoutElements } from 'vue-stripe/checkout'
const checkout = useCheckoutElements()
async function handleConfirm() {
if (checkout.value.type === 'loading') {
// Still loading
return
}
if (checkout.value.type === 'error') {
// Handle error
console.error(checkout.value.error.message)
return
}
// checkout.value.type === 'success'
const { checkout: checkoutInstance } = checkout.value
// Apply promotion code
await checkoutInstance.applyPromotionCode('PROMO_CODE')
// Confirm the session
const result = await checkoutInstance.confirm()
if (result.type === 'error') {
console.error(result.error.message)
}
else {
// Customer will be redirected
}
}
</script>
useCheckoutElements: () => ComputedRef<StripeUseCheckoutElementsResult>
The checkout state can be one of three types:
type StripeUseCheckoutElementsResult
= | { type: 'loading' }
| { type: 'success', checkout: StripeCheckoutElementsValue }
| { type: 'error', error: { message: string } }
Use useCheckoutElements when you need to:
<script setup>
import { ref } from 'vue'
import {
PaymentElement,
useElements,
useStripe
} from 'vue-stripe'
const stripe = useStripe()
const elements = useElements()
const errorMessage = ref(null)
async function handleSubmit() {
if (!stripe.value || !elements.value) {
errorMessage.value = 'Stripe.js has not loaded yet.'
return
}
// Trigger form validation
const { error: submitError } = await elements.value.submit()
if (submitError) {
errorMessage.value = submitError.message
return
}
// Create PaymentIntent on server
const res = await fetch('/create-payment-intent', {
method: 'POST',
})
const { clientSecret } = await res.json()
// Confirm payment
const { error } = await stripe.value.confirmPayment({
elements: elements.value,
clientSecret,
confirmParams: {
return_url: 'https://example.com/order/123/complete',
},
})
if (error) {
errorMessage.value = error.message
}
}
</script>
<template>
<form @submit.prevent="handleSubmit">
<PaymentElement />
<button type="submit" :disabled="!stripe || !elements">
Pay
</button>
<div v-if="errorMessage" class="error">
{{ errorMessage }}
</div>
</form>
</template>
Always check if the composables return non-null values before using them:
<script setup>
const stripe = useStripe()
const elements = useElements()
function safeOperation() {
if (!stripe.value || !elements.value) {
console.warn('Stripe.js has not loaded yet')
}
// Safe to use stripe.value and elements.value
}
</script>
For detailed information about Stripe.js methods and Elements API, refer to the Stripe.js documentation.