Skip to main content

Composite Products (Advanced)

Overview​

The Composites module builds a product out of chosen parts. A composite defines components — each with a name, a required flag, a minimum and maximum quantity, a list of allowed products and an optional dependency on another component — and the shopper picks a product for each. The pick set is priced, carried into the cart and stored on the order line.

It is for configurable goods: a bike built from a frame, wheels and a saddle, a hamper assembled from a fixed list, a machine with required and optional parts.

Availability​

ItemValue
Module keycomposites-advanced
TierPremium
Entitlement keycomposites-advanced
Admin tabcomposite, under Product Experience
Enabled optionaiowc_module_enabled_composites-advanced (off until turned on)
REST namespaceaiowc/v1

registerHooks() re-checks the entitlement and returns immediately when it is absent, and onEnable() does the same before creating tables. Uninstalling drops the three tables and deletes the settings row.

Settings​

Stored in the bundled option row aiowc_cp_settings.

Stored keyDefaultMeaning
enable_compositestrueStored flag for the composite builder.

It is editable from the Settings tab over GET/PATCH /composites/settings since 2026-09-14.

⚠️ This page previously listed three settings and said none of them had a route. Both halves were wrong. There is one setting, not three — allow_save_configs and allow_share_configs are declared nowhere in the module and referenced by no code, so they were almost certainly removed in the 2026-09-02 sweep that cleared 51 inert settings, and this page kept describing them. Documenting a setting a store cannot find is worse than documenting none.

Pricing modes​

A composite carries a pricing_mode, a base_price and a discount_percent.

ModeTotal
fixedbase_price, ignoring what was picked.
sumThe sum of each pick's unit price multiplied by its quantity.
sum_with_discountThat sum, less discount_percent of it.

Anything other than fixed is treated as a sum; the discount is applied only for sum_with_discount and only when the percentage is above zero.

Admin screens​

Plugin admin tab​

The Composites tab lists composites with their pricing mode, base price, discount and status, and offers a delete action and a link to edit the underlying product. It has no create form — the empty state directs the user to create a product and add components.

Product edit screen​

The module adds a Composite tab to the WooCommerce product data panel. It renders a "Composite product?" checkbox and, once the product is marked, a read-only table of its components (name, required, min/max, allowed products, depends-on).

The checkbox is rendered but not saved: the module registers no woocommerce_process_product_meta handler, so ticking it and saving the product leaves _aiowc_is_composite unchanged. Since the storefront builder only renders when that meta is yes, the builder cannot currently be switched on from this screen.

REST API endpoints​

All routes are on aiowc/v1.

MethodPathPurposeRequired argsPermission
GET/compositesList composites.–Manage
POST/compositesCreate a composite; accepts product_id, base_price, discount_percent, allow_save_config, is_active, components.name, pricing_modeManage
GET/composites/{id}Read a composite with its components.idOpen read, rate limited
PATCH/composites/{id}Update a composite and its components.–Manage
DELETE/composites/{id}Delete a composite.idManage
POST/composites/{id}/configureValidate a pick set and price it, without saving.id, selectionsPublic write
POST/configurations/saveSave a pick set for the current user or guest session; accepts name.composite_id, selectionsPublic write
GET/configurations/{share_token}Load a saved configuration by its share token.share_tokenOpen read, rate limited

Open reads are limited to 120 requests a minute per caller; public writes to 30 a minute and they require a REST nonce. A saved configuration is keyed by a unique share token, and belongs to a user id or a WooCommerce session id.

configure and configurations/save accept an optional price on each pick and use it in the total they return and store. The total those routes report is therefore a client-influenced preview, not an authoritative price.

WooCommerce integration​

HookPriorityWhat the module does
woocommerce_single_product_summary28Renders the component builder, only when the product's _aiowc_is_composite meta is yes.
woocommerce_add_cart_item_data10Reads the posted composite id and picks, and stores the picks plus a snapshot of the composite on the cart item.
woocommerce_get_cart_item_from_session10Restores that data when the cart is rebuilt from the session.
woocommerce_before_calculate_totals30Recalculates the line price from the stored snapshot and picks, and sets it on the cart item.
woocommerce_get_item_data10Shows the chosen components under the cart and checkout line.
woocommerce_checkout_create_order_line_item10Persists the configuration onto the order line item.
woocommerce_product_data_tabs10Adds the Composite tab to the product data panel.
woocommerce_product_data_panels10Renders that panel.

The cart path reads only product_id and qty from the posted picks and re-resolves every price from the product, so a forged add-to-cart form cannot set a price. It also registers no woocommerce_add_to_cart_validation callback, so a pick that breaks a component's rules is dropped silently rather than refused with a notice.

Shortcode​

ShortcodeRenders
[aiowc_composite id="123"]The builder form for one composite. Renders nothing without a valid id.

Database schema​

TableHolds
{prefix}aiowc_compositesComposite definitions: name, linked product, pricing mode, base price, discount, active flag.
{prefix}aiowc_composite_componentsComponents: required flag, min and max quantity, sort order, allowed product ids, optional dependency on another component.
{prefix}aiowc_configurationsSaved pick sets with their user or session, share token, selections, name and total.

Background jobs​

The module registers none.

Entitlement limits​

composites-advanced is an on/off grant, checked when the module is enabled, again in registerHooks() and again in onEnable(). There is no licence-side cap on composites, components or saved configurations. The only per-composite limits are the component min_quantity and max_quantity values.

Health check​

The module reports a warning when its tables are missing or WooCommerce is inactive, and otherwise reports that it is functioning normally.