Inttegro Checkout collects payment for a finalized Order inside a hosted frame. Your server remains responsible for creating the Order and deciding when it is safe to fulfill; the browser receives only the client-safe Order ID and the hosted experience owns sensitive payer input.
This separation gives you a small integration surface:
loadInttegro, creates a CheckoutController, and mounts it into an empty element.Create the Order from a trusted server environment using your secret Inttegro credentials. Do not create Orders from a browser and never put a secret API key in a page, mobile application, repository, or framework environment variable that is exposed to the client.
The orderId passed to Checkout is intentionally safe to place in browser code. It identifies the commercial terms that your server already finalized. A payer can attempt to satisfy those terms, but Checkout does not let the browser change the amount, currency, merchant, items, or shipping destination.
Return the Order ID in the response that renders the payment page, for example:
{
"orderId": "ord_01J..."
}
Use the package manager already used by your application:
npm install @inttegro/js
# or: yarn add @inttegro/js
# or: bun add @inttegro/js
# or: deno add npm:@inttegro/js
The package contains the loader and TypeScript types. It does not contain the executable payment-collection runtime. loadInttegro always loads that runtime from Inttegro's fixed origin so every integration receives the maintained hosted experience.
Give Checkout an empty, visible container. Your application controls the container's width and placement; Checkout controls everything inside it.
<main>
<h1>Complete your order</h1>
<div id="checkout"></div>
</main>
#checkout {
inline-size: 100%;
max-inline-size: 34rem;
min-block-size: 32rem;
}
Load the runtime, create the controller, subscribe to events, and then mount it:
import {
InttegroCheckoutError,
loadInttegro,
type CheckoutEvent,
} from '@inttegro/js'
const target = document.querySelector<HTMLElement>('#checkout')
if (!target) throw new Error('Checkout container is missing')
try {
const inttegro = await loadInttegro()
// loadInttegro returns null during server-side rendering.
if (!inttegro) return
const checkout = inttegro.createCheckout({
orderId: window.checkoutOrderId,
appearance: { theme: 'system' },
locale: 'en-GH',
title: 'Payment for your order',
})
const unsubscribe = checkout.onEvent((event: CheckoutEvent) => {
sendCheckoutTelemetry(event)
if (event.type === 'completed') {
window.location.assign('/orders/complete')
}
})
await checkout.mount(target)
// Keep these references and call both when the page is permanently removed.
window.addEventListener(
'pagehide',
() => {
unsubscribe()
checkout.destroy()
},
{ once: true },
)
} catch (error) {
if (error instanceof InttegroCheckoutError) {
showCheckoutUnavailable(error.code)
} else {
throw error
}
}
Register event handlers before CheckoutController.mount so you also observe early lifecycle events such as ready. The mount promise resolves only when the hosted experience is interactive.
Use system unless your checkout surface deliberately has a fixed theme. It follows the payer's browser preference and responds when that preference changes.
const checkout = inttegro.createCheckout({
orderId,
appearance: { theme: 'system' },
locale: 'en-GH',
})
You can change presentation settings without replacing Checkout or discarding payer progress:
checkout.update({
appearance: { theme: 'dark' },
locale: 'fr-FR',
})
Changing orderId, timeout, or title requires a new controller. Framework adapters handle that replacement automatically.
The browser's completed event is useful for navigation, confirmation messaging, and telemetry. It is not a fulfillment credential. Browser events can be interrupted, suppressed, or replayed.
After completion, either:
If the payer closes the page after authorizing a payment but before the browser receives completed, server-side reconciliation still gives you the correct outcome.
Use CheckoutController.unmount when a view is temporarily removed and the same controller will be mounted again. It retains subscriptions. Use CheckoutController.destroy when the flow or route is permanently finished. Destruction removes the frame and every event subscription and is safe to call more than once.
Framework adapters perform this cleanup during their normal unmount lifecycle. Keep the component mounted while a payment or provider confirmation is pending.