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

# Embed SDK

> Open a server-created Boxpressd Payments URL as a desktop modal or mobile sheet.

Load the browser SDK from the same Payments environment that created the session. Pass only the server-created one-time URL.

```html theme={null}
<script src="https://payments.boxpressd.com/sdk/v1/boxpressd-payments.js"></script>
<script>
  const checkout = BoxpressdPayments.open({
    url: hostedSessionUrl,
    theme: "dark",
    dismissible: true,
    onStatus(event) {
      console.log(event.sessionId, event.status);
    },
    onClose(reason) {
      console.log(reason);
    },
  });

  // Close from your own interface when needed.
  // checkout.close("caller_closed");
</script>
```

`theme` accepts `light` or `dark`. When omitted, the SDK follows the device preference. Desktop clients render a modal. Narrow screens render a bottom sheet.

## Security checks

The SDK accepts a message only when both conditions match:

* `event.origin` equals the hosted session origin.
* `event.source` is the checkout iframe window.

Payments posts only to the registered `parentOrigin`. Register every production embedding origin in the service-client policy and Payments frame-ancestor configuration.

## Status events

The SDK forwards `boxpressd:payments:status` messages to `onStatus`. It closes automatically for these terminal interface statuses:

* `paid_pending_fulfillment`
* `fulfilled`
* `cancelled`
* `failed`

Use these events to update the interface. Confirm payment or fulfillment from your backend with the session status endpoint or a verified signed callback.

## Top-level redirect

You can redirect the browser to the same hosted URL when an iframe is not appropriate:

```javascript theme={null}
window.location.assign(hostedSessionUrl);
```

Payments returns the user only to a registered `returnUrl` or `cancelUrl` stored in the session.
