<!-- Source: https://docs.infraio.xyz/en/checkout/overview -->
<!-- Last updated: 2026-10-04 -->

# Checkout — Overview

The **hosted checkout** is the page where the buyer actually sends
funds. You don't render the asset picker, deposit address, or QR
yourself — the SDK opens our page (at
`https://checkout.infraio.xyz/<session_key>`) and we handle the UI.

## Three modes

- [Popup](https://docs.infraio.xyz/en/sdks/javascript#popup) — Centered overlay popup, ~560×780 default. Storefront stays put. `onSuccess` fires when the popup closes after payment. Default mode.
- [Redirect](https://docs.infraio.xyz/en/sdks/javascript#redirect) — Hard navigation to checkout. Best for popup-blocked browsers or mobile web where overlays feel jarring. Buyer returns via your `success_url` / `cancel_url` from the session.
- [Embed](https://docs.infraio.xyz/en/sdks/javascript#embed) — iframe inside your page. Best when you control layout end-to-end and want zero context switch. Auto-resizes via postMessage.

## Pick-a-mode heuristic

| If… | Use |
| --- | --- |
| Desktop web, default e-commerce | **Popup** |
| Mobile web | **Redirect** (popups are often blocked on mobile) |
| Strict CSP-locked admin panel | **Redirect** |
| In-app webview / native checkout-in-a-page | **Embed** |
| You want a fully custom buyer flow with white-label header | **Embed** + `hideHeader` + your own wallet connect |

## What the buyer sees

Regardless of mode, the page surfaces:

1. **Order summary** (line items, total, currency). Hide with
   `hideSummary` if you've already shown this on your side.
2. **Asset picker** — list of chain × asset combinations you've
   enabled in merchant settings. Buyer picks one.
3. **Deposit address + QR + amount** for the chosen combo. The buyer
   either scans, connects a wallet (WalletConnect button), or pays
   from a pre-connected wallet you supplied via the SDK. On TRON, Solana and TON the buyer pays your wallet directly instead; see [Direct-to-wallet networks](https://docs.infraio.xyz/en/concepts/chains#direct-to-wallet-networks).
4. **Status pulse** — "Waiting for transfer", "Tx detected (3/12
   confirmations)", "Paid".
5. **Cancel** button (always present) → triggers `onCancel`.

## Customising the page

| Knob | How | Limits |
| --- | --- | --- |
| Hide order summary | `hideSummary: true` on SDK | Buyer can still see total in deposit panel |
| Hide InfraIO Pay header | `hideHeader: true` on SDK | Pair with `walletAddress` for full white-label |
| Pre-connect a wallet | `walletAddress` + `walletChainId` + `onSignRequest` | Bypasses the WalletConnect modal |
| Locale | `locale` on SDK — one of `en`, `vi`, `ja`, `ko`, `es`, `pt-BR`, `ru`, `tr`, `zh-CN`, `zh-TW` | Localises the checkout **and** refund pages (and the wallet-connect modal). Unknown or omitted → falls back to `en` |
| Logo, brand color | Merchant **dashboard → Branding** | Applies globally, not per-session |

## Return URL behavior

For **redirect** mode the buyer always returns to one of:

- `success_url` from the session (on settled payment)
- `cancel_url` from the session (on cancel/abandon)
- If you didn't set those, the SDK falls back to the page that
  opened the checkout, with `?session_id=…&status=success|cancel`
  appended

For **popup** and **embed** modes there's no navigation — control
returns to your page via `onSuccess` / `onCancel`. Use those to
decide what UI to show next.

## CSP and embedding

If you use **embed** mode, your CSP must allow our origin in
`frame-src`:

```http
Content-Security-Policy:
  frame-src https://checkout.infraio.xyz https://checkout-dev.infraio.xyz;
```

The iframe carries the permissions policy `allow="payment; clipboard-write"`
— it can invoke the Payment Request API and write to the clipboard,
nothing more. Don't add an HTML `sandbox` attribute to the iframe, because it breaks
wallet connection. The iframe is isolated by the cross-origin boundary
and your `frame-src` CSP.

## Mobile considerations

Mobile browsers, especially Safari, often block popups. If most of your traffic is
mobile, use `mode: "redirect"`. On small screens the popup overlay also
covers the keyboard area, which makes picking an asset awkward.

## White-label branding

Full white-label requires:

1. `hideHeader: true` on the SDK
2. `walletAddress` pre-connected (buyer sees no WalletConnect)
3. Your logo + brand color set in merchant dashboard branding
4. (Optional) Custom domain for the checkout page —
   `pay.your-shop.com` instead of `checkout.infraio.xyz`. Set it up
   in the dashboard once your CNAME is verified.

## What's next

- [SDK → JavaScript](https://docs.infraio.xyz/en/sdks/javascript) — full option reference
  per mode.
- [Concepts → Sessions](https://docs.infraio.xyz/en/concepts/sessions) — what's happening
  server-side while the buyer is on the page.
- [Concepts → Chains & assets](https://docs.infraio.xyz/en/concepts/chains) — which chain×asset
  combinations are available in the picker.
