WooCommerce商品页自定义复选框实现购物车折扣报致命错误求助
问题分析与修复方案
致命错误的核心原因
- 钩子参数不匹配:
woocommerce_cart_calculate_fees钩子仅向回调函数传递1个参数($cart对象),但你的函数声明了7个参数,这会直接触发PHP致命错误。 $_POST数据不可靠:添加商品到购物车后页面会刷新,$_POST数据不会保留到购物车页面,导致后续无法读取复选框状态。- (非致命)函数名笔误:
ls_automatic_discount_checbox中的checbox应为checkbox。
修正后的完整代码
// 在商品页添加折扣复选框 add_action( 'woocommerce_after_add_to_cart_button', 'ls_automatic_discount_checkbox', 10 ); function ls_automatic_discount_checkbox() { echo '<p><label><input type="checkbox" name="apply_automatic_discount" value="1"/> Apply 5% discount to your subtotal</label></p>'; } // 将复选框状态保存到购物车项数据中 add_filter( 'woocommerce_add_cart_item_data', 'ls_save_discount_checkbox_state', 10, 3 ); function ls_save_discount_checkbox_state( $cart_item_data, $product_id, $variation_id ) { if ( isset( $_POST['apply_automatic_discount'] ) && $_POST['apply_automatic_discount'] == 1 ) { $cart_item_data['apply_discount'] = true; // 添加唯一键确保每次勾选都能触发购物车更新 $cart_item_data['unique_key'] = md5( microtime().rand() ); } return $cart_item_data; } // 在购物车中计算并应用折扣 add_action( 'woocommerce_cart_calculate_fees', 'ls_apply_discount_on_checkbox_check', 10 ); function ls_apply_discount_on_checkbox_check( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; $total_discount = 0; // 遍历购物车项,检查是否有折扣标记 foreach ( $cart->get_cart() as $cart_item ) { if ( isset( $cart_item['apply_discount'] ) && $cart_item['apply_discount'] ) { // 计算当前商品的折扣金额 $item_subtotal = $cart_item['line_subtotal']; $total_discount += $item_subtotal * 0.05; } } // 应用总折扣 if ( $total_discount > 0 ) { $cart->add_fee( __( '5% OFF', 'woocommerce' ) . " (5%)", -$total_discount ); } }
关键修正说明
- 钩子参数修正:
woocommerce_cart_calculate_fees的回调函数仅保留$cart参数,严格匹配钩子定义。 - 持久化复选框状态:通过
woocommerce_add_cart_item_data钩子将折扣选择保存到购物车项数据中,确保在购物车页面能读取到状态。 - 折扣计算逻辑优化:遍历购物车项计算总折扣,支持多商品分别勾选折扣的场景(若需要全局折扣,可直接基于购物车小计计算)。
- 避免重复添加问题:添加
unique_key确保用户勾选/取消复选框时,购物车能正确更新状态。
内容的提问来源于stack exchange,提问作者Learning WooStoreFront
相关产品推荐
相关产品推荐

