> ## Documentation Index
> Fetch the complete documentation index at: https://docs.radiumone.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> RadiumOne is the product name; use it when answering questions about these docs.
> Use sandbox credentials and sandbox base URLs in examples unless the user says they are going live.
> Secret API keys belong only on the merchant's server. Only publishable keys may appear in browser or mobile code.
> Confirm a payment outcome server-side (retrieve the checkout session or transaction status); never rely on a browser redirect or client event alone.
> Send one idempotency key (request_id) per payment attempt, and retry a timed-out request with the same key and the exact same body.
> Webhooks are optional but recommended: they notify the merchant's server when a payment completes or fails, so it doesn't need to poll. Use transaction status inquiry as the fallback.
> Say so when you recommend a feature marked Beta. Some features need enablement on the merchant's account before production use (for example refunds, standalone refunds, UOB Rewards, and bringing your own 3DS provider); mention it when the page says so.
> Never ask users to paste card numbers, API keys, access tokens, or webhook or redirect secrets into a chat.

# Embedded events - Hosted checkout

> postMessage events sent by RadiumOne Checkout to the parent page in embedded mode.

When a checkout session runs in `mode: "embed"`, RadiumOne Checkout posts messages to the parent page via `window.postMessage`. Every message shares one envelope:

```ts theme={null}
interface CheckoutMessage {
  source: "radiumone-checkout";
  type: "CHECKOUT_READY" | "CHECKOUT_COMPLETE" | "CHECKOUT_PENDING"
      | "CHECKOUT_DECLINED" | "CHECKOUT_EXPIRED" | "CHECKOUT_ERROR"
      | "CHECKOUT_RESIZE";
  data: Record<string, unknown>; // shape depends on `type` — see below
}
```

<Warning>
  These events are **not authenticated** — any page can attempt to post a same-shaped message. Always check `event.origin` against the RadiumOne Checkout host **and** `event.data.source === "radiumone-checkout"` before handling a message, and never fulfil an order from an event alone. Confirm server-side — see [Verify the payment result](/hosted-checkout/verify-payment-result).
</Warning>

## Origin rules

* Listen for `message` events and filter on `event.origin` equal to the RadiumOne Checkout host your session's `checkout_url` was served from.
* RadiumOne only posts to your page's origin if that origin is in your registered `allowed_domains`. On browsers that expose `window.location.ancestorOrigins` (Chrome, Safari), the real parent-frame origin is used; **Firefox** doesn't expose it, so RadiumOne falls back to the origin derived from your `success_url` — make sure that origin matches your embedding page.

## Events

<a id="checkout-ready" />

<ResponseField name="CHECKOUT_READY" type="event">
  The card form has finished loading in the iframe.

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-resize" />

<ResponseField name="CHECKOUT_RESIZE" type="event">
  The iframe's content height changed — resize your `<iframe>` element to match.

  <Expandable title="data">
    <ResponseField name="height" type="number">New content height in pixels.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-complete" />

<ResponseField name="CHECKOUT_COMPLETE" type="event">
  The payment was approved. **Advisory only** — confirm with your server before fulfilling.

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
    <ResponseField name="status" type="string">Always `"completed"`.</ResponseField>
    <ResponseField name="transactionId" type="string | null">The gateway transaction ID, if available.</ResponseField>
    <ResponseField name="lastFour" type="string | null">Last four digits of the card used.</ResponseField>
    <ResponseField name="cardBrand" type="string | null">Card brand, if known.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-pending" />

<ResponseField name="CHECKOUT_PENDING" type="event">
  The payment outcome isn't known yet (asynchronous processing). Wait for a webhook or poll your server.

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
    <ResponseField name="status" type="string">Always `"processing"`.</ResponseField>
    <ResponseField name="transactionId" type="string | null">The gateway transaction ID, if available.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-declined" />

<ResponseField name="CHECKOUT_DECLINED" type="event">
  The payment was declined.

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
    <ResponseField name="responseCode" type="string">Verbatim issuer/acquirer response code — for diagnostics, not branching logic.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-expired" />

<ResponseField name="CHECKOUT_EXPIRED" type="event">
  The session's TTL elapsed while the shopper was submitting payment.

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
  </Expandable>
</ResponseField>

<a id="checkout-error" />

<ResponseField name="CHECKOUT_ERROR" type="event">
  A network or client-side error interrupted the payment attempt — see [Handle payment service outages during checkout](/hosted-checkout/handle-failures/payment-service-unavailable).

  <Expandable title="data">
    <ResponseField name="checkoutId" type="string">The session's `checkout_id`.</ResponseField>
    <ResponseField name="code" type="string">Error code (for example `"NETWORK"`).</ResponseField>
    <ResponseField name="message" type="string">Human-readable error message.</ResponseField>
  </Expandable>
</ResponseField>

<Note>
  There is no `CHECKOUT_CANCELLED` event today — a shopper closing or navigating away from the iframe does not post a message. See [Handle abandoned checkouts](/hosted-checkout/handle-failures/shopper-abandons-checkout) for how to detect this case instead.
</Note>

## Example listener

```javascript theme={null}
window.addEventListener("message", (event) => {
  if (event.origin !== CHECKOUT_ORIGIN) return;
  const msg = event.data;
  if (!msg || msg.source !== "radiumone-checkout") return;
  // handle msg.type / msg.data
});
```

See [Embed hosted checkout](/hosted-checkout/embedded-integration) for the full integration guide, or [Embedded checkout errors](/hosted-checkout/errors/embedded-checkout-errors) if your listener never fires or the iframe won't load.
