Two Companion Modes
Required Companions
Force a selection before add-to-cart. The customer picks one product (or multiple, if their role has multi-select access) from a configured list before they can add the parent to the cart.
Add-on Sections
Optional companions are grouped into named sections, in the order you choose. Each section is checkbox mode (pick any) or radio mode (pick at most one, including none). For example, "Wall Panels" and "Mounting Hardware" can be separate sections on the same product, each with its own rules.
Automatic Quantity Matching
When the customer adds N of the parent, N of the required companion are added automatically:
If the customer separately adds the same product as a standalone item (or it was already in cart), the plugin tracks the split:
The cart shows the breakdown so the customer understands why the quantity isn't directly editable.
Incompatibility Rules
Mark any two add-ons as incompatible, or have a required option rule out specific add-ons. On the product page, selecting an item dims everything incompatible with it and shows a "Not compatible with" explanation. Switching the required selection automatically removes add-ons that no longer fit, with a polite notice.
aria-disabled and are skipped by keyboard navigationDisplay Label Overrides
Long product names wreck layouts. Give any companion a shorter "Display as" label that shows on the product page widget only. The real product name still appears in cart, checkout, emails, and orders. A global option truncates long titles to one line with the full name on hover.
Thumbnail Lightbox
Companion thumbnails open a larger photo in an accessible lightbox on the single product page, so customers can see what they are picking without leaving the page.
Pricing Display and Running Total
Per-product display options for the companion selection UI:
The running total updates live as the customer changes their selection, formatted with your store currency and WooCommerce tax display setting. You can rename or hide it under WooCommerce → Settings → Companion Products.
Section Label Snapshots
Order line items record the section name and any "Display as" label as they were at purchase time, like "Wall Panels for [parent product]". Renaming a section later never rewrites existing order history, so customer records stay accurate.
Separate Line Items, Separate SKUs
This is the operational backbone of the plugin and the reason it works for fulfillment teams.
_mcp_is_required / _mcp_is_optional / _mcp_parent_product_id / _mcp_group_id) and rendered as a label in cart and admin order detailYour warehouse picks two SKUs, not one. Your accounting books two products at their actual prices. Your reporting sees real volume on the companion.
HPOS Compatibility
The plugin declares HPOS compatibility on activation via FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true) and uses WooCommerce order APIs ($order->get_meta(), $order->update_meta_data(), $item->add_meta_data()) throughout — never get_post_meta() against the order ID.
Both legacy storage and the new HPOS tables are supported with no configuration.
Caching
The requirements lookup (which companions does this parent have configured) is cached in a 1-hour WordPress transient. The cache is automatically invalidated when:
Manual cache flush is available in Tools if you need it.
Translation Support
The plugin is translation-ready with the maxtdesign-companion-products text domain and a .pot template at languages/maxtdesign-companion-products.pot.