Svelte Components
Use @monei-js/svelte-components to add MONEI payment components to your Svelte 5 app. Each component uses runes-based props and bind:this for submit().
Install
- npm
- yarn
- pnpm
npm install @monei-js/svelte-components @monei-js/components
yarn add @monei-js/svelte-components @monei-js/components
pnpm add @monei-js/svelte-components @monei-js/components
Requires Svelte 5 or later. All components use Svelte 5 runes ($props(), $state, $effect) — Svelte 4 is not supported.
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 bind:this to call submit() and get a .
<script lang="ts">
import {CardInput, confirmPayment} from '@monei-js/svelte-components';
let {paymentId}: {paymentId: string} = $props();
let cardInput: CardInput;
let error = $state('');
function handleChange(event: {error?: string}) {
error = event.error ?? '';
}
async function handleSubmit() {
const result = await cardInput.submit();
if (result.error) {
error = result.error;
return;
}
await confirmPayment({paymentId, paymentToken: result.token});
}
</script>
<div>
<CardInput bind:this="{cardInput}" {paymentId} onChange="{handleChange}" />
<button onclick="{handleSubmit}">Pay</button>
{#if error}
<p>{error}</p>
{/if}
</div>
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() during component init. Pass a thunk for reactive options — changes sync to the group automatically:
<script>
import {CardNumber, CardExpiry, CardCvc, useCardGroup, confirmPayment} from '@monei-js/svelte-components';
let {paymentId} = $props();
const group = useCardGroup(() => ({paymentId}));
let complete = $state(false);
let error = $state('');
async function handleSubmit() {
const result = await group.submit();
if (result.error) {
error = result.error; // the offending field is already highlighted
return;
}
await confirmPayment({paymentId, paymentToken: result.token});
}
</script>
<label>Card number</label>
<CardNumber {group} class="card-box" onChange={(e) => (complete = e.complete)} />
<div class="row">
<div>
<label>Expiry</label>
<CardExpiry {group} class="card-box" />
</div>
<div>
<label>CVC</label>
<CardCvc {group} class="card-box" />
</div>
</div>
<button disabled={!complete} onclick={handleSubmit}>Pay</button>
{#if error}<p>{error}</p>{/if}
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. bind:this 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.
<script lang="ts">
import {Bizum, confirmPayment} from '@monei-js/svelte-components';
let {paymentId}: {paymentId: string} = $props();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
<Bizum {paymentId} onSubmit="{handleSubmit}" onError="{handleError}" />
PayPal
The PayPal component renders a PayPal checkout button. When the customer approves, you receive a token to confirm the payment.
<script lang="ts">
import {PayPal, confirmPayment} from '@monei-js/svelte-components';
let {paymentId}: {paymentId: string} = $props();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
<PayPal {paymentId} onSubmit="{handleSubmit}" onError="{handleError}" />
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.
<script lang="ts">
import {PaymentRequest, confirmPayment} from '@monei-js/svelte-components';
let {paymentId}: {paymentId: string} = $props();
async function handleSubmit(result: {token?: string}) {
if (result.token) {
await confirmPayment({paymentId, paymentToken: result.token});
}
}
function handleError(error: string) {
console.error(error);
}
</script>
<PaymentRequest {paymentId} onSubmit="{handleSubmit}" onError="{handleError}" />
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.
<script lang="ts">
import {confirmPayment} from '@monei-js/svelte-components';
let {paymentId}: {paymentId: string} = $props();
async function handleClick() {
const result = await confirmPayment({paymentId});
// Payment completed — check result.status
console.log(result);
}
</script>
<button onclick="{handleClick}">Pay</button>
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
- This is a new package — there was no previous Svelte driver. See the Migration Guide for general v2 → v3 changes