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

# Hydrogen / Headless

> Integrate FlexyPe checkout into Hydrogen and other headless/React storefronts built on Shopify

The **FlexyPe Checkout SDK** is a lightweight browser script that opens checkout from any storefront built on Shopify — including [Shopify Hydrogen](https://hydrogen.shopify.dev) and other headless or React frontends. Load the script, then call a global `window.FlexyPeCheckout` object to open or close checkout.

<Warning>
  Complete the [Shopify onboarding](/platforms/shopify) first. It's **mandatory** — your store must be onboarded and your domain registered with FlexyPe before you can integrate on any storefront.
</Warning>

<Note>
  Contact the FlexyPe team for your **script URL** and to register your **store domain** before you start.
</Note>

## Add the script

Place the script tag in your site's `<head>`. The `defer` attribute ensures it loads without blocking rendering.

```html theme={null}
<script src="https://static.flexype.io/scripts/checkout.min.js" defer></script>
```

Once loaded, the global `window.FlexyPeCheckout` object becomes available with `open` and `close` methods.

<Note>
  In a Hydrogen or React app, add the tag to your root HTML document (e.g. the `<head>` in your root route / document component) so it loads once for the whole app.
</Note>

## How store detection works

FlexyPe detects your store from the **domain the script runs on**. That domain must match the store domain you **registered with us during onboarding** — otherwise checkout won't open.

* **Production:** no extra config needed. The SDK uses your live domain automatically.
* **Local development:** add a `data-shop-domain` attribute to the script tag with your registered domain so the SDK can detect the store while running on `localhost`.

```html theme={null}
<script
  src="https://static.flexype.io/scripts/checkout.min.js"
  data-shop-domain="your-domain.com"
  defer
></script>
```

<Warning>
  `data-shop-domain` is for local development only. Remove it on production, where the store is detected from the live domain.
</Warning>

## Open checkout

`FlexyPeCheckout.open` accepts a params object whose `flow` field determines the checkout behavior.

<Tabs>
  <Tab title="Cart checkout">
    Use the `checkout` flow to open checkout with cart items.

    ```js theme={null}
    window.FlexyPeCheckout.open({
      flow: "checkout",
      source: "checkout_button", // optional
      items: [
        { product_id: 123456, variant_id: 789012, quantity: 1 },
        { product_id: 234567, variant_id: 890123, quantity: 2 },
      ],
    });
    ```

    <ParamField path="flow" type="string" required>
      Must be `"checkout"`.
    </ParamField>

    <ParamField path="items" type="array">
      Items to check out. Each item has `product_id`, `variant_id`, and `quantity`.
    </ParamField>

    <ParamField path="source" type="string">
      Optional label identifying where checkout was triggered (for analytics).
    </ParamField>

    <ParamField path="session" type="string">
      Optional session ID for resuming an abandoned checkout.
    </ParamField>
  </Tab>

  <Tab title="Buy now">
    Use the `buynow` flow for Buy Now buttons. It requires a reference to the button element that triggered the action.

    ```js theme={null}
    window.FlexyPeCheckout.open({
      flow: "buynow",
      btn: document.getElementById("buy-now-btn"),
      variantId: 789012, // optional
    });
    ```

    <ParamField path="flow" type="string" required>
      Must be `"buynow"`.
    </ParamField>

    <ParamField path="btn" type="HTMLButtonElement" required>
      Reference to the button element that triggered the action.
    </ParamField>

    <ParamField path="variantId" type="number">
      The variant ID of the product to purchase.
    </ParamField>
  </Tab>
</Tabs>

## Close checkout

Close the checkout programmatically at any time:

```js theme={null}
window.FlexyPeCheckout.close();
```

## Examples

<CodeGroup>
  ```html Buy Now button theme={null}
  <button id="buy-now-btn" onclick="handleBuyNow(this, 789012)">Buy Now</button>

  <script>
    function handleBuyNow(btn, variantId) {
      window.FlexyPeCheckout.open({
        flow: "buynow",
        btn: btn,
        variantId: variantId,
      });
    }
  </script>
  ```

  ```html Cart checkout button theme={null}
  <button onclick="handleCartCheckout()">Checkout</button>

  <script>
    async function handleCartCheckout() {
      // Step 1: Get current cart items
      // Step 2: Map them to { product_id, variant_id, quantity }
      const items = [/* ...mapped cart items... */];

      // Step 3: Open checkout
      window.FlexyPeCheckout.open({
        flow: "checkout",
        source: "cart_checkout_button",
        items: items,
      });
    }
  </script>
  ```
</CodeGroup>

## Quick reference

```js theme={null}
// Minimal — single item checkout
window.FlexyPeCheckout.open({
  flow: "checkout",
  items: [{ product_id: 123456, variant_id: 789012, quantity: 1 }],
});

// Full — checkout with source
window.FlexyPeCheckout.open({
  flow: "checkout",
  source: "buy_now_button",
  items: [{ product_id: 123456, variant_id: 789012, quantity: 1 }],
});

// Buy Now
window.FlexyPeCheckout.open({
  flow: "buynow",
  btn: document.querySelector("#buy-now-btn"),
  variantId: 789012,
});

// Close checkout
window.FlexyPeCheckout.close();
```

## Testing on localhost

Use the `data-shop-domain` attribute (see [How store detection works](#how-store-detection-works)) to point the SDK at your registered store while developing locally.

<Tip>
  You can test the full FlexyPe checkout flow on localhost, but payments may not go through — payment gateways usually block local environments.
</Tip>

## Need help?

Reach out to the FlexyPe team at [hello@flexype.io](mailto:hello@flexype.io) for your script URL and any integration support.
