Skip to main content
Some POS systems keep a separate PLU for each configuration of an item. In this example every pizza size and crust combination is its own product, but customers see one card per pizza and answer two questions. The answers decide which product id goes on the order. See Products — variants for the concepts.

What this example includes

  • Both bases share the same size and crust groups. Each option lists the products of both pizzas in product_ids.
  • Large pizzas have an extra-toppings modifier group. Medium pizzas have none. Modifier groups live on the variant products, never on the base.
  • Size options have an image and a description; crust options don’t.

What the customer sees

Taking the Hawaiian pizza as an example:
  1. The card shows From $12.99. The starting price was omitted, so the sync computed it from the cheapest selectable variant (haw-m-thin).
  2. The detail view asks Size first, then Crust, and shows modifier groups only after a variant is resolved.
  3. After Large is picked, Thin disappears because there is no large thin Hawaiian. Thick is then the only option left, so it’s selected automatically.
  4. After Medium is picked, Thick stays visible but disabled because haw-m-thick is out of stock.
  5. The cart line is haw-l-thick at $17.99, plus any extra toppings. The hawaiian base never appears in an order.

Request

variants.json

Key points

  • The base opens the questions. hawaiian sets pricing.variant_group_ids: ["size", "crust"] and has empty modifier_group_ids.
  • The base price is never charged. Bases use price: 0 here, so the card shows the computed From price (cards show it whenever starting_price is higher than price).
  • Each variant product says how it’s selected. haw-l-thick sets pricing.variants: [{ "product_id": "hawaiian", "variant_group_option_ids": ["large", "thick"] }], with one option from each of the base’s groups.
  • Each option lists its products. The large option lists every large pizza of both bases. The sync rejects the payload if an option and a product’s pricing.variants disagree.
  • Missing combinations are just omitted. There’s no haw-l-thin, so customers can’t reach that combination.
  • Only categories list the base. The variant products aren’t in any category; they’re included in the menu because a base in the menu points to them.
  • A product can be a variant of several bases. Add one pricing.variants entry per base, each with its own options.

Products — variants

Concepts and validation rules

Multi-level modifier groups

Extras that stack on top of a product