WooCommerce购物车页:Double Pitch勾选时Stall Added费用翻倍问题
解决方案:同步Double Pitch复选框与Stall Added费用的价格调整
核心问题分析
你的问题出在Stall Added费用的计算逻辑没有关联Double Pitch复选框的状态,且可能未通过WooCommerce会话持久化复选框状态,导致AJAX更新时状态丢失。以下是完整的修复代码及关键说明:
完整代码实现
// 渲染购物车页的Double Pitch复选框 add_action('woocommerce_cart_totals_before_order_total', 'render_double_pitch_checkbox'); add_action('woocommerce_before_cart_table', 'render_double_pitch_checkbox'); function render_double_pitch_checkbox() { // 从会话读取持久化的复选框状态 $is_checked = WC()->session->get('double_pitch') ? 'checked' : ''; ?> <div class="cart-extra-option"> <label for="double_pitch"> <input type="checkbox" name="double_pitch" id="double_pitch" <?php echo $is_checked; ?>> Double Pitch (价格翻倍) </label> </div> <?php } // 持久化复选框状态到WooCommerce会话 add_action('woocommerce_cart_updated', 'update_double_pitch_session'); function update_double_pitch_session() { $checked = isset($_POST['double_pitch']) ? true : false; WC()->session->set('double_pitch', $checked); } // 同步计算产品价格与Stall Added费用 add_action('woocommerce_cart_calculate_fees', 'calculate_double_pitch_and_stall_fee'); function calculate_double_pitch_and_stall_fee() { if (is_admin() && !defined('DOING_AJAX')) return; $double_pitch_enabled = WC()->session->get('double_pitch'); $cart = WC()->cart; // 1. 处理产品价格翻倍/恢复 foreach ($cart->get_cart() as $item_key => $item) { $product = $item['data']; // 保存原价到会话,避免重复翻倍 if (!$double_pitch_enabled && !WC()->session->get('original_price_' . $item_key)) { WC()->session->set('original_price_' . $item_key, $product->get_price()); } if ($double_pitch_enabled) { $original_price = WC()->session->get('original_price_' . $item_key) ?: $product->get_price(); $product->set_price($original_price * 2); } else { $original_price = WC()->session->get('original_price_' . $item_key); if ($original_price) $product->set_price($original_price); } } // 2. 处理Stall Added费用调整 $base_stall_fee = 10; // 基础费用£10 $final_stall_fee = $double_pitch_enabled ? $base_stall_fee * 2 : $base_stall_fee; // 先移除已存在的Stall Added费用,避免重复累加 foreach ($cart->get_fees() as $fee_key => $fee) { if ($fee->name === 'Stall Added') { $cart->remove_fee($fee_key); } } // 添加调整后的费用 $cart->add_fee('Stall Added', $final_stall_fee); } // AJAX更新时同步复选框状态显示 add_filter('woocommerce_add_to_cart_fragments', 'sync_double_pitch_checkbox_fragment'); function sync_double_pitch_checkbox_fragment($fragments) { $is_checked = WC()->session->get('double_pitch') ? 'checked' : ''; ob_start(); ?> <input type="checkbox" name="double_pitch" id="double_pitch" <?php echo $is_checked; ?>> <?php $fragments['#double_pitch'] = ob_get_clean(); return $fragments; }
关键修复点说明
- 会话持久化状态:使用
WC()->session存储复选框状态,替代仅依赖$_POST,解决AJAX更新时状态丢失的问题。 - 费用去重逻辑:添加费用前先移除同名的已存在费用,避免重复累加。
- 原价保护机制:将产品原价存储到会话,确保取消复选框时能精准恢复原价,不会出现多次翻倍的错误。
- AJAX片段同步:确保购物车更新后,复选框的勾选状态能实时同步显示。
调试建议
- 若仍有问题,可在
calculate_double_pitch_and_stall_fee函数中添加error_log('Double Pitch status: ' . var_export($double_pitch_enabled, true));,查看状态是否正确传递。 - 确认Stall Added费用的名称与代码中
'Stall Added'完全一致,避免移除费用时匹配失败。
内容的提问来源于stack exchange,提问作者JWCreative
相关产品推荐
相关产品推荐

