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

# React Hooks API Reference

> Complete reference for all Ollie Shop hooks to access checkout data and actions

<Note>
  These hooks give your components access to live checkout data and the ability to modify the checkout experience. All hooks are TypeScript-ready with full type definitions, and are imported from `@ollie-shop/sdk`.
</Note>

## Quick Reference

<CardGroup cols={2}>
  <Card title="useCheckoutSession" icon="cart-shopping" href="/ollie-shop/api/useCheckoutSession">
    Read the parsed checkout session (cart items, customer, totals, locale) and validate it
  </Card>

  <Card title="useCheckoutAction" icon="bolt" href="/ollie-shop/api/useCheckoutAction">
    Mutate the checkout: add/remove items, update quantities, coupons, addresses, payments
  </Card>

  <Card title="useStoreInfo" icon="house" href="/ollie-shop/api/use-store-info">
    Store metadata, theme tokens, props/settings, and injected components
  </Card>

  <Card title="useMessages" icon="bell" href="/ollie-shop/api/useMessages">
    Add, remove, and clear notification messages
  </Card>

  <Card title="usePendingActions" icon="spinner" href="/ollie-shop/api/use-pending-actions">
    Track in-flight checkout actions to drive loading states
  </Card>

  <Card title="useCheckoutOrder" icon="receipt" href="/ollie-shop/api/use-checkout-order">
    Access the finalized order after checkout completes
  </Card>
</CardGroup>

<Warning>
  Custom components must import only from `@ollie-shop/sdk`. It is externalized at
  build time; importing from internal packages (e.g. `@ollie-shop/react`) bundles
  them into your component and is not supported.
</Warning>

## useCheckoutSession

The primary hook for **reading** checkout data. To **change** the cart, use [`useCheckoutAction`](/ollie-shop/api/useCheckoutAction) — the session hook is read-only and does not expose mutation functions.

It returns `{ session, rawSession, updateSession, sessionValidity, ... }`. The parsed, platform-agnostic data lives on `session`.

<Tabs>
  <Tab title="📊 Cart Data">
    **Access cart contents and totals**

    ```tsx theme={"system"}
    import { useCheckoutSession } from '@ollie-shop/sdk';

    function CartDisplay() {
      const { session } = useCheckoutSession();
      const { cartItems, totals, locale } = session;

      const format = (cents: number) =>
        new Intl.NumberFormat(locale.language, {
          style: 'currency',
          currency: locale.currency,
        }).format(cents / 100);

      return (
        <div>
          <h3>Cart Summary</h3>
          <p>Items: {cartItems.length}</p>
          <p>Subtotal: {format(totals.items)}</p>
          <p>Shipping: {format(totals.shipping ?? 0)}</p>
          <p>Total: {format(totals.total)}</p>

          {cartItems.map((item) => (
            <div key={item.uniqueId}>
              {item.name} — Qty: {item.quantity} — {format(item.price)}
            </div>
          ))}
        </div>
      );
    }
    ```

    **`session.totals` (all amounts in minor units / cents):**

    | Property     | Type     | Description                             |
    | ------------ | -------- | --------------------------------------- |
    | `items`      | `number` | Total cost of items in the cart         |
    | `shipping?`  | `number` | Total shipping cost                     |
    | `tax?`       | `number` | Total tax amount                        |
    | `discounts?` | `number` | Total discount amount                   |
    | `giftCard?`  | `number` | Total gift card amount                  |
    | `interest?`  | `number` | Total interest (e.g. from installments) |
    | `total`      | `number` | Grand total for the checkout            |

    **`session.cartItems[]`:**

    | Property          | Type                     | Description                          |
    | ----------------- | ------------------------ | ------------------------------------ |
    | `id`              | `string`                 | Item identifier (e.g. SKU code)      |
    | `sellerId?`       | `string`                 | Marketplace seller/vendor identifier |
    | `name`            | `string`                 | Display name                         |
    | `variant?`        | `string`                 | Variant name (e.g. "Size Large")     |
    | `brand?`          | `string`                 | Brand name                           |
    | `category?`       | `string`                 | Primary product category             |
    | `price`           | `number`                 | Current (sale) price in cents        |
    | `originalPrice`   | `number`                 | Original (non-sale) price in cents   |
    | `quantity`        | `number`                 | Quantity of this item                |
    | `available`       | `boolean`                | Whether the item is in stock         |
    | `index`           | `number`                 | Position index in the cart           |
    | `image`           | `string`                 | Image URL                            |
    | `uniqueId`        | `string`                 | Unique id of the cart line           |
    | `url?`            | `string`                 | URL to the product details           |
    | `variantDetails?` | `Record<string, string>` | Variant info (color, size…)          |
  </Tab>

  <Tab title="👤 Customer Data">
    **Access customer information**

    `session.customer` is **optional** — guard for `undefined`. To tell whether the
    operator is a guest, use `session.user.isGuest`.

    ```tsx theme={"system"}
    import { useCheckoutSession } from '@ollie-shop/sdk';

    function CustomerInfo() {
      const { session } = useCheckoutSession();
      const { customer, user } = session;

      if (user.isGuest) {
        return (
          <div>
            <h3>Welcome, Guest!</h3>
            <button>Sign in for faster checkout</button>
          </div>
        );
      }

      return (
        <div>
          <h3>Welcome back, {customer?.firstName}!</h3>
          {customer?.email && <p>Email: {customer.email}</p>}
        </div>
      );
    }
    ```

    **`session.customer` (`CustomerData`, optional):**

    | Property     | Type                | Description                          |
    | ------------ | ------------------- | ------------------------------------ |
    | `id?`        | `string`            | Platform identifier for the customer |
    | `email?`     | `string`            | Email address                        |
    | `firstName?` | `string`            | First name                           |
    | `lastName?`  | `string`            | Last name                            |
    | `document?`  | `string`            | Document / tax ID (e.g. CPF)         |
    | `phone?`     | `string`            | Phone number                         |
    | `addresses?` | `CustomerAddress[]` | Saved addresses                      |

    **`session.user` (`User`, who operates the session):**

    | Property  | Type                   | Description                       |
    | --------- | ---------------------- | --------------------------------- |
    | `id?`     | `string`               | User id (shopper or operator)     |
    | `role`    | `"user" \| "operator"` | Whether a customer or an operator |
    | `isGuest` | `boolean`              | Whether the user is not logged in |
  </Tab>

  <Tab title="🛠️ Modifying the Cart">
    **Cart changes go through `useCheckoutAction`, not `useCheckoutSession`.**

    ```tsx theme={"system"}
    import { useCheckoutAction } from '@ollie-shop/sdk';

    function CartActions() {
      const { execute: addItems } = useCheckoutAction('ADD_ITEMS');
      const { execute: removeItems } = useCheckoutAction('REMOVE_ITEMS');
      const { execute: updateQuantity } = useCheckoutAction('UPDATE_ITEMS_QUANTITY');
      const { execute: updateCoupons } = useCheckoutAction('UPDATE_COUPONS');

      return (
        <div>
          <button onClick={() => addItems([{ id: 'upsell-123', quantity: 1 }])}>
            Add Extended Warranty
          </button>
          <button onClick={() => removeItems([0])}>Remove first item</button>
          <button onClick={() => updateQuantity([{ index: 0, quantity: 3 }])}>
            Set first item qty to 3
          </button>
          <button onClick={() => updateCoupons(['SAVE10'])}>Apply SAVE10</button>
        </div>
      );
    }
    ```

    | Action                  | Input                           | Description           |
    | ----------------------- | ------------------------------- | --------------------- |
    | `ADD_ITEMS`             | `{ id; quantity; sellerId? }[]` | Add items to the cart |
    | `REMOVE_ITEMS`          | `number[]` (item indexes)       | Remove items          |
    | `UPDATE_ITEMS_QUANTITY` | `{ index; quantity }[]`         | Update quantities     |
    | `UPDATE_COUPONS`        | `string[]` (coupon codes)       | Apply/remove coupons  |

    See [`useCheckoutAction`](/ollie-shop/api/useCheckoutAction) for the full list of actions and inputs.
  </Tab>
</Tabs>

## useStoreInfo

Access store metadata, theme tokens, and configuration.

```tsx theme={"system"}
import { useStoreInfo } from '@ollie-shop/sdk';

function ThemedComponent() {
  const { platformStoreId, logo, theme, props } = useStoreInfo();

  // `theme` is a flat Record<string, string> of design tokens
  // (CSS-variable-style keys), not a nested object.
  return (
    <div
      style={{
        backgroundColor: theme?.['--color-primary'],
        color: theme?.['--color-text'],
      }}
    >
      <h2>{platformStoreId}</h2>
      {logo && <img src={logo} alt="Store logo" />}

      {props?.flags?.showCouponCodeInputOpened && (
        <input placeholder="Enter coupon code" />
      )}
    </div>
  );
}
```

**Returned properties (`Omit<StoreInfo, "messages">`):**

| Property          | Type                      | Description                                |
| ----------------- | ------------------------- | ------------------------------------------ |
| `platform`        | `string`                  | E-commerce platform (e.g. "vtex")          |
| `platformStoreId` | `string`                  | Store id on the platform                   |
| `storeId?`        | `string`                  | Ollie store id                             |
| `logo?`           | `string`                  | Store logo URL                             |
| `versionId?`      | `string`                  | Active store version id                    |
| `correlationId?`  | `string`                  | Request correlation id                     |
| `template?`       | `TemplateType`            | Active template                            |
| `theme?`          | `Record<string, string>`  | Flat design tokens                         |
| `props?`          | `object`                  | Version props and feature flags            |
| `settings?`       | `Record<string, unknown>` | Store settings                             |
| `components?`     | `CustomComponent[]`       | Custom components injected into this store |

## Combining Hooks

```tsx theme={"system"}
import {
  useCheckoutSession,
  useCheckoutAction,
  usePendingActions,
  useStoreInfo,
} from '@ollie-shop/sdk';

function CheckoutSummary() {
  const { session } = useCheckoutSession();
  const { platformStoreId } = useStoreInfo();
  const { hasPendingActions } = usePendingActions();
  const { execute: removeItems } = useCheckoutAction('REMOVE_ITEMS');

  const { cartItems, totals, locale, user } = session;
  const format = (cents: number) =>
    new Intl.NumberFormat(locale.language, {
      style: 'currency',
      currency: locale.currency,
    }).format(cents / 100);

  return (
    <div style={{ opacity: hasPendingActions ? 0.5 : 1 }}>
      <h2>Order Summary — {platformStoreId}</h2>
      <p>{user.isGuest ? 'Guest order' : 'Signed-in order'}</p>

      {cartItems.map((item) => (
        <div key={item.uniqueId}>
          <span>{item.name} — {format(item.price)}</span>
          <button onClick={() => removeItems([item.index])}>Remove</button>
        </div>
      ))}

      <p><strong>Total: {format(totals.total)}</strong></p>
    </div>
  );
}
```

<Note>
  Use [`usePendingActions`](/ollie-shop/api/use-pending-actions) to disable buttons or
  show skeletons while a [`useCheckoutAction`](/ollie-shop/api/useCheckoutAction) call
  is in flight — the pending list is updated automatically by the action hook.
</Note>
