Vue Stripe provides composables to access Stripe, Elements, and Checkout instances from within your components. These composables work with the Elements, CheckoutProvider, and EmbeddedCheckoutProvider components.
The useStripe composable returns a reference to the Stripe instance passed to the Elements or CheckoutProvider.
<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 useCheckout composable returns the Checkout state from CheckoutProvider. It provides access to the Checkout instance and session data.
<script setup>
import { useCheckout } from 'vue-stripe/checkout'
const checkout = useCheckout()
async function handleConfirm() {
if (checkout.value?.type === 'loading') {
// Still loading
return
}
if (checkout.value?.type === 'error') {
// Handle error
console.error(checkout.value.error)
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>
useCheckout: () => ComputedRef<CheckoutContextValue | null>
The checkout state can be one of three types:
type CheckoutState
= | { type: 'loading', sdk: StripeCheckout | null }
| { type: 'success', sdk: StripeCheckout, checkoutActions: LoadActionsSuccess, session: StripeCheckoutSession }
| { type: 'error', error: { message: string } }
Use useCheckout 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.