WooCommerce Product Bundles(产品捆绑)本质上是“父商品 + 子商品集合”的复合产品类型。底层实现通常不是简单把几个商品拼在一起展示,而是扩展 WooCommerce 的 product_type 与购物车/订单计算流程,让一个 bundle 订单能携带多个子项,并且在库存、折扣、税费、运费上保持一致。
在数据层,插件会在父商品(bundle)上保存一组“绑定子商品”配置,常见形式是 post_meta 数组:子商品 ID、默认数量、最小/最大数量、是否可选、折扣类型(固定/百分比)、定价模式(父价/子价叠加/动态价)等。前端渲染时,通过读取这些 meta 生成一个 bundle schema,再输出到模板中。用户选项变化会驱动 JS 重新计算价格预估,但最终权威价格仍由服务器端重新汇总(防止篡改)。
价格链路上,bundle 插件一般会挂钩:
woocommerce_before_calculate_totals 中遍历 bundle 父行项目,按配置动态生成子项价格并写入 cart item data;下面用一个“简化版 bundle 核心流程”示例说明 Product Bundles 的底层思路(关键点与真实插件一致):
// 1) 保存 bundle 子项配置(后台自定义面板略)
function get_bundle_items($bundle_id){
// meta: [ ['id'=>123,'min'=>1,'max'=>5,'discount'=>10,'type'=>'percent'], ... ]
return (array) get_post_meta($bundle_id, '_bundle_items', true);
}
// 2) 加入购物车时注入 bundle 选择
add_filter('woocommerce_add_cart_item_data', function($cart_item_data, $product_id){
if (get_post_type($product_id) !== 'product') return $cart_item_data;
$product = wc_get_product($product_id);
if ($product->get_type() !== 'bundle') return $cart_item_data;
$items = get_bundle_items($product_id);
$chosen = [];
foreach ($items as $it){
$qty = isset($_POST['bundle_qty'][$it['id']]) ? intval($_POST['bundle_qty'][$it['id']]) : 0;
if ($qty < $it['min'] || $qty > $it['max']) {
wc_add_notice('Bundle item quantity invalid.', 'error');
return false;
}
if ($qty > 0) $chosen[] = ['id'=>$it['id'], 'qty'=>$qty, 'conf'=>$it];
}
$cart_item_data['bundle_items'] = $chosen; // 写入 cart data
return $cart_item_data;
}, 10, 2);
// 3) 购物车动态计价(服务端权威)
add_action('woocommerce_before_calculate_totals', function($cart){
foreach ($cart->get_cart() as $key => $item){
if (empty($item['bundle_items'])) continue;
$parent = $item['data'];
$total = 0;
foreach ($item['bundle_items'] as $child){
$p = wc_get_product($child['id']);
$price = (float) $p->get_price() * $child['qty'];
// 折扣示例
if ($child['conf']['type'] === 'percent'){
$price *= (1 - $child['conf']['discount']/100);
}
$total += $price;
}
// 动态价模式:父价=子项汇总
$parent->set_price($total);
}
});这个骨架体现了三件事:
如果你的业务需要“可选子项”“动态定价”“统一库存规则”,Product Bundles 的这种底层设计能避免手工组合带来的价格漂移、库存错扣和售后不可追溯的问题。