Skip to main content

Product Bundles (Enhanced)

Overview​

Product Bundles (Enhanced) attaches a bundle to an existing WooCommerce product and lets the customer configure it before adding it to the cart. Pricing is either dynamic — the sum of what was chosen, with optional percentage discounts — or a fixed price for the whole bundle regardless of contents.

What separates it from the simpler Product Bundles module is its rule table: a bundle carries rules that constrain what may be configured, evaluated by a builder service before the configuration is accepted.

The bundle can be placed with a shortcode as well as on the product page, so it does not have to live in the normal product template.

It is for stores where a bundle is configured rather than simply bought.

Availability​

ItemValue
Module keybundles-enhanced
TierPremium
Entitlement keybundles-enhanced
Admin tabbundles-enhanced
Enabled optionaiowc_module_enabled_bundles-enhanced (off until turned on)
REST namespaceaiowc/v1

Enabling the module creates the three tables below, seeds the defaults and schedules the inventory sync.

registerHooks() returns early twice: once when the licence does not grant bundles-enhanced, and again when enable_bundles is off — so switching that setting off takes the REST routes and every hook out of the request entirely. It also reconciles the sync job on every request: if sync_inventory_hourly is on the job is scheduled, and if it is off the job is unscheduled, so changing the setting takes effect without any further action.

Settings​

Stored in the bundled option row aiowc_pb_settings.

Stored keyDefaultMeaning
enable_bundlestrueMaster switch. Off means no hooks, no routes and no bundle UI.
sync_inventory_hourlytrueWhether the hourly inventory sync runs. Reconciled on every request.

Bundles​

FieldMeaning
nameWhat the bundle is called.
product_idThe WooCommerce product the bundle is attached to.
pricing_modedynamic (the default) or a fixed price.
fixed_priceThe whole-bundle price, used when the pricing mode is fixed.
discount_percentA percentage off, applied in dynamic mode.
allow_variable_quantityWhether the customer may change item quantities. On by default.
track_inventoryWhether the bundle's availability is derived from component stock.
is_activeWhether the bundle is offered.

Each item names a product and optionally a variation, with a default, minimum and maximum quantity, an optional flag, its own discount percentage, and a sort order.

Rules​

A bundle may carry rules in its own table, each a rule type with a stored value. They are evaluated by the builder service when a configuration is submitted, so a configuration that breaks a rule is refused before it reaches the cart rather than being corrected afterwards.

Admin screen​

The Bundles (Enhanced) tab lists the bundles with paging, creates and edits them, and manages each bundle's items. Deletions are confirmed before they happen, and the list has explicit empty, pending and error states rather than a blank table while loading.

The module also adds a panel to the WooCommerce product edit screen, so a bundle can be configured from the product it belongs to.

REST API endpoints​

All routes are on aiowc/v1 and answer with the { success, data, message } envelope.

MethodPathPurposePermissionRequired args
GET/bundles-enhancedEvery bundle.manage_woocommerce–
POST/bundles-enhancedCreate a bundle.manage_woocommercename, pricing_mode
GET/bundles-enhanced/{id}One bundle, with its items. Read by the storefront.Public, rate-limitedid
PATCH/bundles-enhanced/{id}Update a bundle.manage_woocommerce–
DELETE/bundles-enhanced/{id}Delete a bundle.manage_woocommerceid
POST/bundles-enhanced/{id}/configurePrice and validate a configuration without adding it.Nonce, rate-limitedid, selections
POST/bundles-enhanced/add-to-cartAdd a configured bundle to the cart.Nonce, rate-limitedbundle_id, selections

/configure is what lets the builder show a running price as the customer chooses, without committing anything to the cart.

WooCommerce integration​

HookWhat the module does
woocommerce_single_product_summaryDraws the bundle builder on the product page.
woocommerce_add_to_cart_validationRefuses a configuration that breaks the bundle's rules.
woocommerce_add_cart_item_dataCaptures the configuration into the cart item.
woocommerce_get_cart_item_from_sessionRestores it when the cart is rebuilt from the session.
woocommerce_before_calculate_totalsPrices the bundle according to its pricing mode.
woocommerce_get_item_dataLists the chosen contents under the cart line.
woocommerce_checkout_create_order_line_itemWrites the configuration onto the order line.
woocommerce_product_data_tabs / _panelsAdds the bundle panel to the product edit screen.

Shortcode [aiowc_bundle] renders a bundle builder anywhere on the site.

Database schema​

TableHolds
{prefix}aiowc_pb_bundlesThe bundle: name, the product it is attached to, pricing mode, fixed price, discount percentage, quantity and inventory flags, active flag.
{prefix}aiowc_pb_bundle_itemsThe contents: product and variation, default, minimum and maximum quantity, optional flag, per-item discount, sort order.
{prefix}aiowc_bundle_rulesThe constraints on a bundle: rule type and its stored value.

The first two carry a pb_ prefix because the plainer names belong to the separate Product Bundles module. Each module owns its own tables and neither reads the other's.

Background jobs​

HookIntervalWork
aiowc_bundles_sync_inventoryhourlyBrings bundle availability back in step with component stock.

The job runs on WP-Cron, and is scheduled or unscheduled to match sync_inventory_hourly on every request.

Action hooks for integrators​

HookFired when
aiowc_track_eventThe module is enabled or disabled.

The module exposes no filter for bundle pricing or for adding a rule type.

Entitlement limits​

bundles-enhanced is an on/off grant with no cap on the number of bundles, items or rules.

Health check​

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

Known gaps​

  • Two bundle modules ship, and both can be on at once. This one and Product Bundles both hook the cart and both price bundles. Nothing detects that both are active, so a store should pick one.
  • The rule types a bundle may carry are stored as free-form type-and-value rows with no filter for extending them, so a constraint the builder does not already implement cannot be added without modifying the module.
  • track_inventory is a per-bundle flag but the sync runs for the module as a whole on a fixed hourly cycle, so availability can lag real stock by up to an hour.
  • There is no duplicate action on a bundle, so a similar bundle is built from scratch.