Vue Components
Use @monei-js/vue-components to add MONEI payment components to your Vue 3 app. Each component is a native Vue component with typed props and template ref submit().
Install
- npm
- yarn
- pnpm
npm install @monei-js/vue-components @monei-js/components
yarn add @monei-js/vue-components @monei-js/components
pnpm add @monei-js/vue-components @monei-js/components
Requires Vue 3.3 or later.
Components
| Component | Description |
|---|---|
CardInput | Secure card input (iframe) with submit() |
CardNumber / CardExpiry / CardCvc | Individually mountable card fields, coordinated by useCardGroup() |
Bizum | Bizum button + phone verification modal |
PayPal | PayPal checkout button |
PaymentRequest | Apple Pay / Google Pay button |
Card input
The Card Input component collects card number, expiry, and in a single secure iframe. Use a template ref to call submit() and get a .
<template>
<div>
<CardInput ref="cardInput" :payment-id="paymentId" :on-change="handleChange" />
<button @click="handleSubmit">Pay</button>
<p v-if="error">{{ error }}</p>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue';
import {CardInput, confirmPayment} from '@monei-js/vue-components';
const props = defineProps<{paymentId: string}>();
const cardInput = ref<InstanceType<typeof CardInput>>();
const error = ref('');
function handleChange(event: {error?: string}) {
error.value = event.error ?? '';
}
async function handleSubmit() {
const result = await cardInput.value!.submit();
if (result.error) {
error.value = result.error;
return;
}
await confirmPayment({paymentId: props.paymentId, paymentToken: result.token});
}
</script>
See the API Reference for all CardInput props (style, placeholders, error messages, event callbacks).
Split card fields
Mount the number, expiry and CVC as separate components in your own layout. Create the group with useCardGroup() inside setup() — payment identifiers live on the group, the parts take presentation props only.
<script setup>
import {ref} from 'vue';
import {
CardNumber,
CardExpiry,
CardCvc,
useCardGroup,
confirmPayment
} from '@monei-js/vue-components';
const props = defineProps({paymentId: String});
const group = useCardGroup({paymentId: props.paymentId});
const complete = ref(false);
const error = ref('');
async function handleSubmit() {
const result = await group.submit();
if (result.error) {
error.value = result.error; // the offending field is already highlighted
return;
}
await confirmPayment({paymentId: props.paymentId, paymentToken: result.token});
}
</script>
<template>
<label>Card number</label>
<CardNumber :group="group" class="card-box" :onChange="(e) => (complete = e.complete)" />
<div class="row">
<div>
<label>Expiry</label>
<CardExpiry :group="group" class="card-box" />
</div>
<div>
<label>CVC</label>
<CardCvc :group="group" class="card-box" />
</div>
</div>
<button :disabled="!complete" @click="handleSubmit">Pay</button>
<p v-if="error">{{ error }}</p>
</template>
Style that box in your own CSS — the class you pass is set on the very element each part toggles monei-component--focus, --invalid, --empty and --complete on, so .card-box.monei-component--invalid {} matches. A template ref on a part exposes focus(), blur() and clear().
See the API Reference for all options and behavior details.
Bizum
The Bizum component renders a Bizum payment button. When the customer clicks it, a phone verification modal opens to complete the payment.
<template>
<Bizum :payment-id="paymentId" :on-submit="handleSubmit" :on-error="handleError" />
</template>
<script setup lang="ts">
import {Bizum, confirmPayment} from '@monei-js/vue-components';
const props = defineProps<{paymentId: string}>();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId: props.paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
PayPal
The PayPal component renders a PayPal checkout button. When the customer approves, you receive a token to confirm the payment.
<template>
<PayPal :payment-id="paymentId" :on-submit="handleSubmit" :on-error="handleError" />
</template>
<script setup lang="ts">
import {PayPal, confirmPayment} from '@monei-js/vue-components';
const props = defineProps<{paymentId: string}>();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId: props.paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
PaymentRequest (Apple Pay / Google Pay)
The PaymentRequest component renders an Apple Pay or Google Pay button depending on the customer's browser and device.
Apple Pay requires domain verification in both development and production.
<template>
<PaymentRequest :payment-id="paymentId" :on-submit="handleSubmit" :on-error="handleError" />
</template>
<script setup lang="ts">
import {PaymentRequest, confirmPayment} from '@monei-js/vue-components';
const props = defineProps<{paymentId: string}>();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId: props.paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
Payment modal
Calling confirmPayment() without a paymentToken opens the MONEI Payment Modal — a full in-page checkout where the customer can select a payment method and complete the payment.
<template>
<button @click="handleClick">Pay</button>
</template>
<script setup lang="ts">
import {confirmPayment} from '@monei-js/vue-components';
const props = defineProps<{paymentId: string}>();
async function handleClick() {
const result = await confirmPayment({paymentId: props.paymentId});
// Payment completed — check result.status
console.log(result);
}
</script>
Apple Pay is not available in the Payment Modal. Use the PaymentRequest component instead.
See Use Payment Modal for the full integration guide.
Next steps
- Check the API Reference for all component options and methods
- See the Migration Guide if you're upgrading from the
.driver('vue3')API