---
title: "Ecommerce — Advanced / Piecemeal Collections API"
aliases: [ecommerce-piecemeal, ecommerce-collection-factories]
tags: [payloadcms, ecommerce, stripe, typescript]
sources: [raw/ecommerce__advanced.md]
created: 2026-05-15
updated: 2026-05-15
---

# Ecommerce — Advanced / Piecemeal Collections API

The plugin exposes individual collection factory functions so you can adopt only the pieces you need without registering the full plugin. Useful when building a custom ecommerce flow on top of Payload.

## Collection Factory Functions

| Factory | Collection | Purpose |
|---------|-----------|---------|
| `createAddressesCollection` | `addresses` | Customer shipping/billing addresses |
| `createCartsCollection` | `carts` | Guest + authenticated carts; retained after purchase for analytics |
| `createOrdersCollection` | `orders` | Customer-facing order records; linked to ≥1 Transaction |
| `createTransactionsCollection` | `transactions` | Payment data — admin-only |
| `createProductsCollection` | `products` | Product catalog with prices, variant links |
| `createVariantsCollection` | `variants` | Unique purchasable variants linked to a product + options |
| `createVariantTypesCollection` | `variantTypes` | Taxonomy grouping (e.g. "size") |
| `createVariantOptionsCollection` | `variantOptions` | Individual values of a type (e.g. "small") |

## createAddressesCollection

```ts
import { createAddressesCollection } from 'payload-plugin-ecommerce'

const Addresses = createAddressesCollection({
  access: { isAdmin, isAuthenticated, isCustomer, isDocumentOwner },
  addressFields: [{ name: 'company', type: 'text', label: 'Company' }],
  // customersSlug: 'customers'  (default)
  // supportedCountries: CountryType[]  (default: all)
})
```

**Access object:**

| Key | Type | Used for |
|-----|------|----------|
| `isAdmin` | `Access` | Full admin access |
| `isAuthenticated` | `Access` | Allow any customer to `create` |
| `isCustomer` | `FieldAccess` | Auto-assign `customer` ID on create |
| `isDocumentOwner` | `Access` | Limit read/update/delete to owner |

## createCartsCollection

```ts
const Carts = createCartsCollection({
  access: { isAdmin, isAuthenticated, isDocumentOwner, publicAccess },
  enableVariants: true,
  currenciesConfig: {
    defaultCurrency: 'usd',
    currencies: [{ code: 'usd', symbol: '$' }, { code: 'eur', symbol: '€' }],
  },
})
```

- `publicAccess` — optional; allows guest (unauthenticated) cart creation
- `isDocumentOwner` — limits read/update/delete to cart owner only

## createOrdersCollection

```ts
const Orders = createOrdersCollection({
  access: { isAdmin, isDocumentOwner, adminOnlyFieldAccess },
  enableVariants: true,
  currenciesConfig: { ... },
  addressFields: [{ name: 'deliveryInstructions', type: 'text', label: 'Delivery Instructions' }],
})
```

- `adminOnlyFieldAccess` — restricts `transactionId` field to admins
- `addressFields` — injected as shipping address sub-fields

## createTransactionsCollection

```ts
const Transactions = createTransactionsCollection({
  access: { isAdmin },   // admin-only for all operations
  enableVariants: true,
  currenciesConfig: { ... },
  addressFields: [...],  // billing address fields
  paymentMethods: [],    // PaymentAdapter[]
})
```

Only `isAdmin` is available — transactions are never exposed to customers.

## createProductsCollection

```ts
const Products = createProductsCollection({
  access: { isAdmin, adminOrPublishedStatus },
  enableVariants: true,
  currenciesConfig: { ... },
  inventory: {
    enabled: true,
    trackByVariant: true,
    lowStockThreshold: 5,
  },
})
```

- `adminOrPublishedStatus` — non-admins can only read published products
- `inventory` accepts `boolean` (on/off) or `InventoryConfig`

## createVariantsCollection

```ts
const Variants = createVariantsCollection({
  access: { isAdmin, adminOrPublishedStatus },
  currenciesConfig: { ... },
  inventory: { enabled: true, lowStockThreshold: 5 },
})
```

- `adminOrPublishedStatus` here checks the *related product's* published status

## createVariantTypesCollection

```ts
const VariantTypes = createVariantTypesCollection({
  access: { isAdmin, publicAccess },
  // variantOptionsSlug: 'variantOptions'
})
```

- `publicAccess` — allow anyone to read variant types (e.g. "size", "color")

## createVariantOptionsCollection

```ts
const VariantOptions = createVariantOptionsCollection({
  access: { isAdmin, publicAccess },
  // variantTypesSlug: 'variantTypes'
})
```

- `publicAccess` — allow anyone to read variant options (e.g. "small", "red")

---

## TypeScript Types

### CurrenciesConfig

```ts
type CurrenciesConfig = {
  defaultCurrency: string        // must match a code in currencies[]
  currencies: CurrencyType[]
}
```

### Currency (CurrencyType)

```ts
type CurrencyType = {
  code: string      // ISO 4217, e.g. 'usd'
  symbol: string    // e.g. '$'
  label?: string    // e.g. 'USD'
  decimals?: number // e.g. 2 — IMPORTANT: prices stored as integers
}
```

> **Critical:** `decimals` controls how integer prices are formatted. USD stores `1000` → display `$10.00`. JPY uses `0` decimals.

### CountryType

```ts
type CountryType = {
  value: string   // ISO 3166-1 alpha-2, e.g. 'US'
  label: string   // e.g. 'United States'
}
```

### InventoryConfig

```ts
type InventoryConfig = {
  fieldName?: string           // default: 'inventory'
  // other fields depend on plugin version
}
```

---

## Key Takeaways

- **No plugin needed** — import individual `create*Collection` factories and add them directly to Payload config
- **Access objects differ per collection** — check the table for each factory; not all access keys are available everywhere
- **Transactions are always admin-only** — `isAdmin` is the only access key available
- **`publicAccess` on carts enables guest shopping** — carts without auth; use localStorage to persist cart ID
- **Prices are stored as integers** — always set `decimals` in `CurrencyType` to format correctly
- **`inventory` accepts bool or config** — `true` enables defaults; pass `InventoryConfig` to customise field name or threshold
- **All `*Slug` params are optional** — override only if you renamed the default collection slugs

---

## Related

- [[wiki/payloadcms/ecommerce|Ecommerce Overview]] — full plugin setup, Stripe flow, cart API, frontend hooks
- [[wiki/payloadcms/access-control|Access Control]] — `Access` and `FieldAccess` function signatures
- [[wiki/payloadcms/plugins|Plugins]] — how to use and build Payload plugins
- [[wiki/payloadcms/collection-config|Collection Config]] — base collection config options

## Sources

- `raw/ecommerce__advanced.md` — payloadcms.com/docs/ecommerce/advanced
