WooCommerce用PHP隐藏特定品类配送选项后无法结账的解决办法
解决WooCommerce特定分类产品禁用配送的问题
直接上干货,针对你遇到的两个需求,分逻辑处理和视觉隐藏两部分解决:
一、彻底禁用Events分类产品的配送(解决结账提示问题)
把下面的代码加到当前主题的functions.php里,或者用代码片段插件(避免主题更新丢失代码):
// 标记Events分类的产品为无需配送的虚拟产品 add_filter('woocommerce_product_is_virtual', 'events_category_mark_virtual', 10, 2); function events_category_mark_virtual($is_virtual, $product) { // 这里的'events'是你的产品分类slug,后台分类页面可查看,不对就修改 if (has_term('events', 'product_cat', $product->get_id())) { return true; } return $is_virtual; } // 判断购物车是否需要配送:全是票品就取消配送要求 add_filter('woocommerce_cart_needs_shipping', 'events_cart_check_shipping'); function events_cart_check_shipping($needs_shipping) { $all_tickets = true; foreach (WC()->cart->get_cart() as $item) { if (!has_term('events', 'product_cat', $item['product_id'])) { $all_tickets = false; break; } } return $all_tickets ? false : $needs_shipping; } // 混合购物车时保留实体产品的配送选项,纯票品就移除所有配送方式 add_filter('woocommerce_package_rates', 'events_remove_shipping_rates', 10, 2); function events_remove_shipping_rates($rates, $package) { $has_tickets = false; $has_physical = false; foreach ($package['contents'] as $item) { if (has_term('events', 'product_cat', $item['product_id'])) { $has_tickets = true; } else { $has_physical = true; } } // 只有票品的话,清空所有配送方式 if ($has_tickets && !$has_physical) { return array(); } return $rates; }
这段代码的作用:
- 自动把Events分类的票品标记为虚拟产品,WooCommerce会默认跳过配送流程
- 购物车里全是票品时,直接不显示配送选项,也不会弹出“未选择配送方式”的提示
- 如果混合了实体产品和票品,正常保留实体产品的配送选项,不影响原有流程
二、条件隐藏配送区域(仅针对纯票品的购物车/结账页)
如果需要在视觉上彻底隐藏配送相关模块,先加PHP代码给页面body加标识类,再用CSS控制:
1. 添加标识类的PHP代码(同样放functions.php)
// 给购物车/结账页的body加类,标记是否全是Events产品 add_filter('body_class', 'events_cart_add_body_class'); function events_cart_add_body_class($classes) { if (is_cart() || is_checkout()) { $all_tickets = true; foreach (WC()->cart->get_cart() as $item) { if (!has_term('events', 'product_cat', $item['product_id'])) { $all_tickets = false; break; } } if ($all_tickets) { $classes[] = 'cart-only-events'; } } return $classes; }
2. 添加条件CSS(主题自定义CSS或附加CSS里)
/* 只有票品的购物车/结账页,隐藏配送相关模块 */ .cart-only-events .woocommerce-shipping-fields, .cart-only-events .woocommerce-shipping-totals, .cart-only-events .shipping_calculator, .cart-only-events #shipping_method { display: none !important; }
这样只会在纯票品的页面隐藏配送区域,实体产品的页面完全不受影响。
注意事项
- 记得把代码里的
events换成你实际的产品分类slug(后台产品分类页面查看,slug是分类的英文标识) - 改动后清空WooCommerce的配送缓存:WooCommerce设置→配送→页面底部的“清空缓存”按钮
- 不要直接修改WooCommerce核心文件,用主题
functions.php或代码片段插件,避免更新丢失
内容的提问来源于stack exchange,提问作者NootNoobJoe
相关产品推荐
相关产品推荐

