Inttegro for Svelte
Use @inttegro/svelte to render Inttegro-hosted Checkout as a Svelte 5
component. The adapter uses typed callback props and destroys Checkout when the
component leaves the page.
Prerequisites
- Svelte 5 or newer
- A backend that creates and finalizes an Inttegro Order
- A client-safe finalized Order ID or Purchase Intent ID
Install the component
- npm
- Yarn
- Bun
- Deno
npm install @inttegro/svelte
yarn add @inttegro/svelte
bun add @inttegro/svelte
deno add npm:@inttegro/svelte
Deno installs this package through its npm compatibility layer. When importing without an import map, prefix the package with npm:.
Choose and render a presentation
The NestJS live demo uses Svelte 5 and
@inttegro/svelte for both presentations while keeping pricing and Order
creation on the server; its released Svelte component
shows the complete boundary. Compare the presentations below, then use the
matching implementation that follows. Open any screenshot at full size when you
need to inspect the layout.
- Desktop
- Mobile
Select any image to view it full screen.
Both presentations use the same Checkout component and finalized Order.
Svelte 5 uses callback props such as onCompleted, not the legacy on: event
directive.
- Embedded
- Modal
Choose embedded Checkout for a dedicated payment route, checkout step, or invoice layout where the form should remain visible. Your Svelte markup owns the component's position and surrounding content; Inttegro owns the hosted payment surface inside it.
<script lang="ts">
import { Checkout } from '@inttegro/svelte'
let { orderId }: { orderId: string } = $props()
let message = $state('')
function handleError(error: Error) {
message = error.message
}
</script>
<main>
<h1>Complete your order</h1>
<section aria-label="Payment">
<Checkout
appearance={{ theme: 'system' }}
locale="en-GH"
{orderId}
onCompleted={() => location.assign('/payment-status')}
onError={handleError}
/>
</section>
<p aria-live="polite">{message}</p>
</main>
Keep Checkout mounted while payment or provider confirmation is in progress.
The class prop styles the outer element; merchant CSS does not reach the
hosted controls. Let
Checkout report its own height; avoid fixed heights or overflow clipping on the
payment region.
Choose a modal when payment starts from a button and the current page should
remain mounted underneath. Your application owns the dialog, trigger, close
control, focus restoration, and scrolling. Put the same Checkout component
in an {#if} block so it exists only while the dialog is open.
<script lang="ts">
import { Checkout } from '@inttegro/svelte'
let { orderId }: { orderId: string } = $props()
let dialog: HTMLDialogElement
let open = $state(false)
let message = $state('')
function openDialog() {
open = true
dialog.showModal()
}
function handleError(error: Error) {
message = error.message
}
</script>
<button disabled={open} onclick={openDialog}>Pay now</button>
<dialog
bind:this={dialog}
aria-labelledby="payment-title"
onclose={() => (open = false)}
>
<h2 id="payment-title">Complete payment</h2>
<button type="button" onclick={() => dialog.close()}>Close</button>
{#if open}
<Checkout
appearance={{ theme: 'system' }}
{orderId}
onCompleted={() => location.assign('/payment-status')}
onError={handleError}
/>
{/if}
</dialog>
<p aria-live="polite">{message}</p>
Closing the application dialog resets open; Svelte then unmounts Checkout
and releases its controller and subscriptions. Keep the dialog open while a
payment attempt or provider confirmation is in progress.
Start from a Buy link
Pass a Buy link's public Purchase Intent instead of creating a finalized Order:
<Checkout {purchaseIntentId} />
Use the same prop with presentation="modal" for the managed modal experience.
Checkout renders the full Buy experience and creates the finalized Order only
after the buyer continues. Payment then continues in the same component.
Provide either orderId or purchaseIntentId, never both.
For hosted-page presentation, do not mount the Svelte component. Submit to your
backend and have it return a 303 redirect to the hosted Checkout URL for the
finalized Order, as the NestJS demo does.
The component also accepts features, timeout, and title. features
controls line-item visibility, post-payment invoice and receipt actions, and
whether an attached payment method can be replaced. Changing appearance or
locale updates the active Checkout. Changing features, orderId,
purchaseIntentId, timeout, or title creates a new instance.
Handle callback props
| Prop | Called when |
|---|---|
onCanceled | The payer leaves managed modal Checkout. |
onCompleted | Checkout reaches its successful terminal experience. |
onError | Loading or mounting fails before Checkout can continue. |
onEvent | Any privacy-safe lifecycle event is received. |
onFailed | Checkout reaches a terminal failure. |
onReady | Checkout is ready for customer interaction. |
onError receives an Error for loader or mount failures. onEvent receives
the canonical Checkout lifecycle, including recoverable
paymentAttemptFailed events and the terminal completed, canceled, and
failed events. Order-backed events carry the full client-safe Order.
Use callbacks for interface state and telemetry, then have your backend look up the Order before fulfillment.
Use routes and server rendering
The adapter initializes Checkout in an effect. With server rendering, Svelte renders the empty host element and mounts the hosted experience after client hydration.
Related resources
- JavaScript runtime and loader - Review options, events, CSP, and modal behavior.
- Inertia - Use this component with an Inertia Svelte frontend.
- Web Checkout overview - Prepare the server and verify payment state.