ECM-1Recommended
Give every variant its own SKU
Model each product as a parent with one variant per sellable combination of options, such as size and colour. Give each variant its own SKU, stable internal ID, price per currency and stock count.
How to do it
A customer buys a variant, not a product. A blue shirt in size M is one variant with one SKU, one barcode such as a GTIN, and one stock count. Keep the internal ID for joins and foreign keys, and the SKU as the code people and warehouses read. Put shared text and pictures on the parent, and only what differs on the variant. Store each price in minor units with its currency, as Hold money as integer minor units everywhere says. Keep one fixed price per currency, as Set a price in each currency instead of converting at checkout says. Cart lines, order lines and stock rows point at the variant ID, never at the parent.
Examples
TypeScript example
type Variant = {
id: string; // internal, never shown
sku: string; // "TEE-BLU-M", unique for ever
gtin?: string;
options: Record<string, string>; // { colour: "blue", size: "M" }
prices: Record<string, number>; // { EUR: 2500, SEK: 29900 } in minor units
};
type Product = { id: string; title: string; variants: Variant[] };
Python example
from dataclasses import dataclass, field
@dataclass(frozen=True)
class Variant:
id: str
sku: str
options: dict[str, str]
prices_minor: dict[str, int] = field(default_factory=dict)
gtin: str | None = None
How to check
A schema test finds a foreign key from every cart line, order line and stock row to the variant table. A query finds no variant without a SKU, a price in each sold currency and a stock row.
Related rules
- PAY-10 Hold money as integer minor units everywhere in Payments and billing
- PAY-66 Set a price in each currency instead of converting at checkout in Payments and billing
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/ecommerce/catalog-and-prices/variant-skus">Agent Wranglers e-commerce and fulfilment playbook</a>. In code you write, add a comment next to it with the same link.