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

# Embed SDK Reference

> Complete reference for Shoppex Checkout Embed SDK

This page documents the current behavior of the Checkout Embed SDK (`window.Shoppex`).

## Script

```html theme={"system"}
<script src="https://checkout.shoppex.io/embed/embed.iife.js" defer></script>
```

Global object:

```javascript theme={"system"}
window.Shoppex
```

***

## Integration Modes

<Tabs>
  <Tab title="Declarative (Data Attributes)">
    The SDK auto-binds clickable elements matching:

    * `[data-shoppex-product-id]`
    * `[data-shoppex-group-id]`
    * `[data-shoppex-checkout]`

    Simple button:

    ```html theme={"system"}
    <button
      data-shoppex-product-id="PRODUCT_ID"
      data-shoppex-variant-id="VARIANT_ID"
      data-shoppex-quantity="1"
      data-shoppex-theme="auto"
    >
      Buy now
    </button>
    ```

    Multi-item via JSON:

    ```html theme={"system"}
    <button
      data-shoppex-checkout="1"
      data-shoppex-items='[
        {"productId":"PRODUCT_ID_1","variantId":"VARIANT_1","quantity":1},
        {"productId":"PRODUCT_ID_2","quantity":2}
      ]'
    >
      Checkout
    </button>
    ```

    Group button:

    ```html theme={"system"}
    <button
      data-shoppex-group-id="GROUP_ID"
      data-shoppex-referral-code="CREATOR123"
      data-shoppex-return-url="https://your-site.com/thank-you"
    >
      Open group
    </button>
    ```
  </Tab>

  <Tab title="Programmatic (JS API)">
    ```javascript theme={"system"}
    Shoppex.open({
      shopId: 'YOUR_SHOP',
      items: [
        { productId: 'PRODUCT_ID', variantId: 'VARIANT_ID', quantity: 1 }
      ],
      theme: 'auto',
      email: 'customer@example.com',
      couponCode: 'SAVE20',
      affiliateCode: 'CREATOR123',
      returnUrl: 'https://your-site.com/thank-you',
      metadata: { campaign: 'launch' }
    });
    ```
  </Tab>
</Tabs>

***

## Data Attributes

| Attribute                     | Required | Description                              |
| ----------------------------- | -------- | ---------------------------------------- |
| `data-shoppex-product-id`     | Yes\*    | Product identifier                       |
| `data-shoppex-group-id`       | Yes\*\*  | Group identifier                         |
| `data-shoppex-variant-id`     | No       | Variant identifier                       |
| `data-shoppex-quantity`       | No       | Quantity (`1..999`, default `1`)         |
| `data-shoppex-theme`          | No       | `light`, `dark`, `auto` (default `auto`) |
| `data-shoppex-return-url`     | No       | Return URL after checkout                |
| `data-shoppex-email`          | No       | Prefill customer email                   |
| `data-shoppex-coupon-code`    | No       | Prefill coupon code                      |
| `data-shoppex-affiliate-code` | No       | Affiliate code                           |
| `data-shoppex-referral-code`  | No       | Referral code alias                      |
| `data-shoppex-metadata`       | No       | JSON object with string values           |
| `data-shoppex-items`          | No       | JSON array of checkout items             |
| `data-shoppex-shop-id`        | No       | Optional field in current API payload    |
| `data-shoppex-checkout`       | No       | Marker selector for custom triggers      |

\* Required unless `data-shoppex-items` contains at least one valid item.
\*\* Required when you want to open a group instead of a product checkout.

`data-shoppex-metadata` example:

```html theme={"system"}
<button
  data-shoppex-product-id="PRODUCT_ID"
  data-shoppex-metadata='{"campaign":"summer","source":"landing"}'
>
  Buy now
</button>
```

***

## JavaScript API

### `Shoppex.init(config?)`

Initializes bindings and keyboard handlers.

```javascript theme={"system"}
Shoppex.init({
  nonce: 'YOUR_CSP_NONCE'
});
```

Notes:

* Usually optional because the script initializes automatically.
* Safe to call multiple times; first call wins.

### `Shoppex.open(options)`

Opens modal checkout.

```typescript theme={"system"}
type CheckoutOptions = {
  shopId?: string;
  groupId?: string;
  items: Array<{
    productId: string;
    variantId?: string;
    quantity?: number;
  }>;
  theme?: 'light' | 'dark' | 'auto';
  returnUrl?: string;
  email?: string;
  couponCode?: string;
  affiliateCode?: string;
  metadata?: Record<string, string>;
};
```

Important behavior:

* `items` must contain at least one valid `productId`, unless `groupId` is provided.
* `groupId` opens a group picker first, then forwards the buyer into the normal product checkout page.
* If more than one item is passed, current modal flow uses the first valid item.
* Calling `open()` while a modal is open closes the old modal first.

### `Shoppex.close()`

Closes the modal programmatically.

```javascript theme={"system"}
Shoppex.close();
```

***

## Events

Listen on `document`:

```javascript theme={"system"}
document.addEventListener('shoppex:success', (event) => {
  console.log(event.detail.invoiceId);
});

document.addEventListener('shoppex:error', (event) => {
  console.error(event.detail.error);
});
```

Event payloads:

| Event             | Detail                   |
| ----------------- | ------------------------ |
| `shoppex:success` | `{ invoiceId?: string }` |
| `shoppex:error`   | `{ error?: string }`     |

Internal iframe events used by the SDK:

* `shoppex:ready`
* `shoppex:resize`
* `shoppex:close`

***

## URL Mapping

The SDK resolves checkout iframe URLs to:

```text theme={"system"}
https://checkout.shoppex.io/e/:productId
https://checkout.shoppex.io/g/:groupId
```

Supported query params sent by SDK:

* `quantity`
* `variantId`
* `theme` (only when not `auto`)
* `flow`
* `shopId`
* `returnUrl`
* `email`
* `couponCode`
* `affiliateCode`
* `metadata[key]=value`

***

## Runtime Behavior

* Modal uses Shadow DOM (`mode: closed`) for style isolation.
* `Escape`, backdrop click, and close button all close modal.
* Dynamically inserted buttons are auto-bound (MutationObserver).
* Message handling only accepts trusted checkout origins.

***

## Practical Example

```html theme={"system"}
<button id="buy">Buy now</button>
<script src="https://checkout.shoppex.io/embed/embed.iife.js" defer></script>
<script>
  document.getElementById('buy').addEventListener('click', () => {
    Shoppex.open({
      items: [{ productId: 'PRODUCT_ID', quantity: 1 }],
      theme: 'auto'
    });
  });

  document.addEventListener('shoppex:success', (event) => {
    console.log('Invoice paid:', event.detail.invoiceId);
  });
</script>
```

***

## Need Faster Setup?

<Card title="Copy/Paste Snippets" icon="code" href="/guides/embeds-snippets">
  Framework snippets for Next.js, React, WordPress, and Webflow.
</Card>
