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

# Catalog

> Browse products, variants, and prices from your store

# Catalog

The catalog module lets you fetch products, variants, and prices from your TagadaPay store. Use it to build product listing pages, product detail pages, and dynamic carts.

***

## List Products

```typescript theme={null}
const products = await tagada.catalog.getProducts();
```

### Filter by IDs

```typescript theme={null}
const filtered = await tagada.catalog.getProducts({
  productIds: ['prod_xxx'],
  variantIds: ['var_xxx'],
});
```

***

## Get a Single Product

```typescript theme={null}
const product = await tagada.catalog.getProduct('prod_xxx');
// Returns CatalogProduct or null if not found
```

***

## Types

### `CatalogProduct`

```typescript theme={null}
interface CatalogProduct {
  id: string;
  name: string;
  description?: string;
  active: boolean;
  variants: CatalogVariant[];
}
```

### `CatalogVariant`

```typescript theme={null}
interface CatalogVariant {
  id: string;
  productId: string;
  name: string;
  description?: string;
  sku?: string;
  price?: number;
  currency?: string;
  compareAtPrice?: number;
  imageUrl?: string;
  active: boolean;
  inStock: boolean;
  prices: CatalogPrice[];
}
```

### `CatalogPrice`

```typescript theme={null}
interface CatalogPrice {
  id: string;
  variantId?: string;
  default: boolean;
  currencyOptions: Record<string, { amount: number; compareAtAmount?: number }>;
  recurring: boolean;
  interval?: string;       // 'day', 'month', 'year'
  intervalCount?: number;
}
```

<Note>
  Prices use `currencyOptions` — a map of currency codes to amounts in cents. For example, `{ USD: { amount: 3900 }, EUR: { amount: 3500 } }` means \$39.00 / 35.00.
</Note>

***

## React Hook

```tsx theme={null}
import { useCatalog } from '@tagadapay/headless-sdk/react';

function ProductList() {
  const { products, isLoading, error, loadProducts, loadProduct } = useCatalog();

  useEffect(() => {
    loadProducts();
  }, [loadProducts]);

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      {products.map((product) => (
        <div key={product.id}>
          <h2>{product.name}</h2>
          {product.variants.map((v) => (
            <div key={v.id}>
              {v.imageUrl && <img src={v.imageUrl} alt={v.name} />}
              <span>{v.name}</span>
              <span>{(v.prices[0]?.currencyOptions.USD?.amount ?? 0) / 100} USD</span>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}
```

### Full Hook API

| Property / Method        | Description                                                         |
| ------------------------ | ------------------------------------------------------------------- |
| `products`               | Array of loaded products (empty until `loadProducts` is called)     |
| `isLoading`              | True during any async operation                                     |
| `error`                  | Last error, if any                                                  |
| `loadProducts(opts?)`    | Fetch all products. Optional filter: `{ productIds?, variantIds? }` |
| `loadProduct(productId)` | Fetch a single product by ID                                        |
