Shop
Products, categories, stock, orders and pluggable shipping — a full commerce engine other verticals build on.

Commerce engine
The shop owns products, categories, warehouses/stock and orders. It integrates with core through the line-item registry (its order lines become invoice lines) and the event bus (stock blocking, order state). Pricing flows through the shared PriceFactory, so per-rate tax and discounts reconcile on the invoice.
Shipping providers
Shipping is a capability: implement a provider, register it, and it appears at checkout. A flat-rate provider ships as an example. This is the same open/closed pattern used for payments — add a provider without touching the shop core.
Product types
A product type is a named, additive cluster of custom fields layered on the universal base product. It carries no behaviour — fields only. A product references at most one type via product_type_slug (NULL = the plain default product) and stores its answers in type_field_values. Types live in the shop_product_type table; the shop self-registers a digital type as the reference example.
There are two ways to define one, no config file involved:
- In the admin — a full CRUD API (
/api/v1/admin/shop/product-types) and the fe-admin Product Types view. These aresource="admin": fully editable and deletable. Post{name, slug, description?, product_type_fields[]}; each field is{slug, type, label, required, options, sort_order}overstring / url / integer / number / boolean / select / multiselect. - From plugin code — a plugin's
on_enablecallsregister_product_type(descriptor); shop's enablereconcile_product_types()upserts it idempotently assource="plugin"(read-only in the UI; the owning plugin owns the cluster). Adding a type never edits shop.
On save, values are validated against the type's schema — required fields present, value types matched, select values drawn from their options. Product types are additive metadata; they are not product variants (priced/stocked SKUs) and not the pharma product-class gate.
Verticals on top
The shop is itself a substrate: the merchant / software store and the pharma module are full verticals layered on the shop engine, reusing its catalogue, cart, checkout, stock and orders.