Flexible and powerful Vue 3 components for Stripe. It's a glue between Stripe.js and Vue component lifecycle.
npm
npm i vue-stripe-js @stripe/stripe-js --save-dev
yarn
yarn add vue-stripe-js @stripe/stripe-js --dev
pnpm
pnpm add vue-stripe-js @stripe/stripe-js --save-dev
import { loadStripe } from '@stripe/stripe-js'
import { defineComponent, ref, onBeforeMount } from 'vue'
export default defineComponent({
// ...
setup() {
onBeforeMount(() => {
const stripeLoaded = ref(false)
const stripePromise = loadStripe('your_key')
stripePromise.then(() => {
stripeLoaded.value = true
})
})
},
})
Alternatively, you can load Stripe library by including script tag. Just make sure it's ready before your stripe components mount.
<script src="https://js.stripe.com/v3/"></script>
Create card
<template>
<StripeElements
v-if="stripeLoaded"
v-slot="{ elements, instance }" // attention: important part!
ref="elms"
:stripe-key="stripeKey"
:instance-options="instanceOptions"
:elements-options="elementsOptions"
>
<StripeElement
ref="card"
:elements="elements"
:options="cardOptions"
/>
</StripeElements>
<button type="button" @click="pay">Pay</button>
</template>
<script lang="ts">
import { StripeElements, StripeElement } from 'vue-stripe-js'
import { loadStripe } from '@stripe/stripe-js'
import { defineComponent, ref, onBeforeMount } from 'vue'
export default defineComponent({
name: 'CardOnly',
components: {
StripeElements,
StripeElement,
},
setup() {
const stripeKey = ref('pk_test_TYooMQauvdEDq54NiTphI7jx') // test key
const instanceOptions = ref({
// https://stripe.com/docs/js/initializing#init_stripe_js-options
})
const elementsOptions = ref({
// https://stripe.com/docs/js/elements_object/create#stripe_elements-options
})
const cardOptions = ref({
// https://stripe.com/docs/stripe.js#element-options
value: {
postalCode: '12345',
},
})
const stripeLoaded = ref(false)
const card = ref()
const elms = ref()
onBeforeMount(() => {
const stripePromise = loadStripe(stripeKey.value)
stripePromise.then(() => {
stripeLoaded.value = true
})
})
const pay = () => {
// Get stripe element
const cardElement = card.value.stripeElement
// Access instance methods, e.g. createToken()
elms.value.instance.createToken(cardElement).then((result: object) => {
// Handle result.error or result.token
console.log(result)
})
}
return {
stripeKey,
stripeLoaded,
instanceOptions,
elementsOptions,
cardOptions,
card,
elms,
pay
}
}
})
</script>
Create multiple elements
<StripeElements
v-slot="{ elements }"
:stripe-key="stripeKey"
:instance-options="instanceOptions"
:elements-options="elementsOptions"
>
<StripeElement
type="cardNumber"
:elements="elements"
:options="cardNumberOptions"
/>
<StripeElement
type="postalCode"
:elements="elements"
:options="postalCodeOptions"
/>
</StripeElements>
You can even create multiple groups.
<StripeElements
v-slot="{ elements }"
:stripe-key="stripeKey1"
:instance-options="instanceOptions1"
:elements-options="elementsOptions1"
>
<StripeElement :elements="elements" :options="cardOptions" />
</StripeElements>
<StripeElements
v-slot="{ elements }"
:stripe-key="stripeKey2"
:instance-options="instanceOptions2"
:elements-options="elementsOptions2"
>
<StripeElement type="iban" :elements="elements" :options="ibanOptions" />
</StripeElements>
import types {
initStripe,
createElements,
createElement,
StripeElements,
StripeElement
} from 'vue-stripe-js'
Think of it as of individual group of elements. It creates stripe instance and elements object.
import { StripeElements } from 'vue-stripe-js'
// https://stripe.com/docs/js/initializing#init_stripe_js-options
stripeKey: {
type: String,
required: true,
},
// https://stripe.com/docs/js/elements_object/create#stripe_elements-options
instanceOptions: {
type: Object,
default: () => ({}),
},
// https://stripe.com/docs/stripe.js#element-options
elementsOptions: {
type: Object,
default: () => ({}),
},
You can access instance
and elements
by adding ref to StripeElements component.
// StripeElements.vue exposes
{
elements,
instance,
elementsUsable,
}
Elegant solution for props. Really handy because you can make stripe instance
and elements
objects available to all children without adding extra code.
<!-- Cool, isn't it? -->
<StripeElements v-slot="{ elements, instance }">
<StripeElement :elements="elements" />
<CustomComponent :instance="instance" />
</StripeElements>
Universal and type agnostic component. Create any element supported by Stripe.
import { StripeElement } from 'vue-stripe-js'
{
// elements object
// https://stripe.com/docs/js/elements_object/create
elements: {
type: Object as () => StripeElementsWithoutOverload,
required: true,
},
// type of the element
// https://stripe.com/docs/js/elements_object/create_element?type=card
type: {
type: String as () => StripeElementType,
default: () => 'card',
},
// element options
// https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options
options: {
type: Object as () => StripeElementOptions,
default: () => ({}),
},
},
{
stripeElement,
domElement,
mountPoint,
}
Element options are reactive. Recommendation: don't use v-model on StripeElement
, instead pass value via options.
setup() {
const elementOptions = ref({
value: {
postalCode: '12345'
}
})
const changePostalCode = (postalCode) => {
elementOptions.value.postalCode = postalCode
}
},
Following events are emitted on StripeElement
- change
- ready
- focus
- blur
- click
- escape
<StripeElement :elements="elements" @blur="doSomething" />
No base style included. Main reason: overriding it isn't fun. Style as you wish via element options: see details.