Developer Reference
Technical facts for developers integrating with the plugin. Nothing on this page is needed for day-to-day store management.
Product type
The plugin registers the product type slug bundle_product, backed by a WC_Product_Bundle class extending WC_Product. The type appears in the standard product_type_selector and is stored via the normal WooCommerce product-type taxonomy.
Product meta keys
Bundle configuration is stored as post meta on the bundle product:
| Meta key | Content |
|---|---|
_bundle_products | Array of items: product_id, quantity (order defines mandatory/optional split) |
_bundle_pricing_mode | fixed | dynamic (defaults to fixed) |
_bundle_fixed_price | Decimal; used in fixed mode; falls back to _regular_price when absent |
_bundle_discount_enabled | yes | no |
_bundle_discount_type | percent | fixed |
_bundle_discount_value | Decimal |
_bundle_purchase_limit | Positive integer; absent = no limit |
_bundle_compulsory_count | Positive integer; absent/0 = all items mandatory |
Order line items receive _bundle_items (the selected contents with quantities and optional flags) plus one visible meta row per included product ("Product x N → Included inside bundle").
REST API
Namespace: product-bundle/v1
| Route | Method | Auth | Purpose |
|---|---|---|---|
/bundle/{id} | GET | public | Read a bundle's pricing mode and items (name, price, quantity, optional flag) |
/bundle/get-bundle?id={id} | GET | manage_woocommerce or edit_products | Same payload, admin-oriented |
/bundle/get-products?search={term} | GET | manage_woocommerce or edit_products | Product search for admin tooling (20 results) |
/bundle/update-bundle | POST/PUT | manage_woocommerce or edit_products | Update pricing_mode, fixed_price and the items array |
Example — read a bundle:
curl https://example.com/wp-json/product-bundle/v1/bundle/523
{
"pricing_mode": "dynamic",
"items": [
{ "product_id": 435, "name": "Washing Machine", "price": "1300", "quantity": 1, "optional": false }
]
}
Example — update a bundle:
curl -X POST https://example.com/wp-json/product-bundle/v1/bundle/update-bundle \
-u admin:app_password \
-H "Content-Type: application/json" \
-d '{"id":523,"pricing_mode":"dynamic","items":[{"product_id":435,"quantity":1}]}'
Invalid bundle IDs return 404; an invalid pricing mode returns 400.
Hooks
The plugin builds on standard WooCommerce hooks rather than introducing its own filter surface:
- The storefront bundle UI renders on
woocommerce_bundle_product_add_to_cart(WooCommerce's per-type add-to-cart action) and wraps the form with the standardwoocommerce_before_add_to_cart_button/woocommerce_after_add_to_cart_buttonactions. - Pricing, validation, cart display and order meta use the usual
woocommerce_*filters (add_cart_item_data,add_to_cart_validation,before_calculate_totals,get_item_data,checkout_create_order_line_item,is_purchasable,get_price_html, Store API quantity/validation hooks).
Custom code can therefore interact with bundles through the same WooCommerce hooks it already uses for other product types.
Store API / blocks
Purchase-limit enforcement is wired into the WooCommerce Store API (woocommerce_store_api_product_quantity_limit and cart-item validation throwing a 409 bundle_purchase_limit error), which is what keeps the block cart and checkout consistent with the classic pages.
Templates and translations
- The admin panel and storefront bundle box are rendered from the plugin's own
templates/directory (they are not theme-overridable template parts in v1.0.0). - Text domain:
product-bundle, Domain Path/languages— all customer-facing strings are translatable with standard tools such as Loco Translate or Poedit.
