Inttegro for Angular
Use @inttegro/angular to render Inttegro-hosted Checkout as a standalone
Angular component. The adapter uses Angular inputs, outputs, and component
lifecycle hooks to manage Checkout.
Prerequisites
- Angular 18 through 22
- 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/angular
yarn add @inttegro/angular
bun add @inttegro/angular
deno add npm:@inttegro/angular
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 FastAPI live demo uses Angular 21 and
@inttegro/angular for both presentations while keeping credentials and Order
creation on the server; its released Angular 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.
CheckoutComponent is standalone. Import it into the Angular component that
owns payment collection, then choose whether it participates in the page layout
or opens above it.
- Embedded
- Modal
Choose embedded Checkout for a dedicated payment route, checkout step, or invoice layout where the form should remain visible. Your Angular template owns the component's position and surrounding content; Inttegro owns the hosted payment surface inside it.
import { Component, Input } from '@angular/core'
import { CheckoutComponent } from '@inttegro/angular'
@Component({
selector: 'app-checkout-page',
standalone: true,
imports: [CheckoutComponent],
template: `
<main>
<h1>Complete your order</h1>
<section aria-label="Payment">
<inttegro-checkout
[appearance]="{ theme: 'system' }"
[orderId]="orderId"
locale="en-GH"
(completed)="handleCompleted()"
(error)="handleError($event)"
/>
</section>
<p aria-live="polite">{{ message }}</p>
</main>
`,
})
export class CheckoutPageComponent {
@Input({ required: true }) orderId = ''
message = ''
handleCompleted(): void {
window.location.assign('/payment-status')
}
handleError(error: Error): void {
this.message = error.message
}
}
Keep the component mounted while payment or provider confirmation is in progress. Your layout controls the host element's width and placement; 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. Create the same CheckoutComponent
only while the dialog is open.
import { Component, Input } from '@angular/core'
import { CheckoutComponent } from '@inttegro/angular'
@Component({
selector: 'app-payment-action',
standalone: true,
imports: [CheckoutComponent],
template: `
<button [disabled]="open" (click)="openDialog(dialog)">Pay now</button>
<dialog #dialog aria-labelledby="payment-title" (close)="open = false">
<h2 id="payment-title">Complete payment</h2>
<button type="button" (click)="dialog.close()">Close</button>
@if (open) {
<inttegro-checkout
[appearance]="{ theme: 'system' }"
[orderId]="orderId"
(completed)="handleCompleted()"
(error)="handleError($event)"
/>
}
</dialog>
<p aria-live="polite">{{ message }}</p>
`,
})
export class PaymentActionComponent {
@Input({ required: true }) orderId = ''
open = false
message = ''
openDialog(dialog: HTMLDialogElement): void {
this.open = true
dialog.showModal()
}
handleCompleted(): void {
window.location.assign('/payment-status')
}
handleError(error: Error): void {
this.message = error.message
}
}
Closing the application dialog resets open; Angular then destroys the
Checkout component, its controller, and its subscriptions. Keep the dialog open
while a payment attempt or provider confirmation is in progress.
Start from a Buy link
Bind a Buy link's public Purchase Intent instead of creating a finalized Order:
<inttegro-checkout [purchaseIntentId]="purchaseIntentId" />
Set presentation="modal" on the same component 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. Bind either orderId or purchaseIntentId, never both.
For hosted-page presentation, do not mount CheckoutComponent. Submit to your
backend and have it return a 303 redirect to the hosted Checkout URL for the
finalized Order, as the FastAPI 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 output events
| Output | Emitted when |
|---|---|
canceled | The payer leaves managed modal Checkout. |
completed | Checkout reaches its successful terminal experience. |
error | Loading or mounting fails before Checkout can continue. |
event | Any privacy-safe lifecycle event is received. |
failed | Checkout reaches a terminal failure. |
ready | Checkout is ready for customer interaction. |
The error output contains an Error for loader or mount failures. The event
output 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 these outputs for interface state and telemetry. Before fulfillment, have
your backend look up the Order; the completed
output alone is not authoritative money state.
Focus or update Checkout
Use ViewChild to call the component's public focus() or update() method:
import { Component, ViewChild } from '@angular/core'
import { CheckoutComponent } from '@inttegro/angular'
@Component({
selector: 'app-focused-checkout',
standalone: true,
imports: [CheckoutComponent],
template: `
<inttegro-checkout [orderId]="orderId" (ready)="focusCheckout()" />
`,
})
export class FocusedCheckoutComponent {
@ViewChild(CheckoutComponent) checkout?: CheckoutComponent
orderId = 'ORDER_ID_FROM_YOUR_BACKEND'
focusCheckout(): void {
this.checkout?.focus()
}
}
Use update() only for appearance and locale. Angular inputs are
preferable when those values already belong to component state.
Use routes and server rendering
The loader returns null outside a browser. With Angular server rendering, the
server produces the empty host element and the adapter mounts Checkout during
the client view lifecycle.
Related resources
- JavaScript runtime and loader - Review options, events, CSP, and modal behavior.
- Web Checkout overview - Prepare the server and verify payment state.