如何在WordPress结账页通过代码及AJAX移除特定商品类型订单运费并更新UI?
解决方案:通过AJAX移除WooCommerce结账页运费选项及总计行
一、后端逻辑(PHP)
在自定义插件中添加以下代码,实现AJAX请求处理、配送方法过滤及总计行移除:
// 注册AJAX动作(支持登录/未登录用户) add_action('wp_ajax_toggle_shipping_option', 'toggle_shipping_option_callback'); add_action('wp_ajax_nopriv_toggle_shipping_option', 'toggle_shipping_option_callback'); function toggle_shipping_option_callback() { // 验证请求合法性 check_ajax_referer('toggle_shipping_nonce', 'security'); $action_type = isset($_POST['action_type']) ? sanitize_text_field($_POST['action_type']) : ''; // 设置会话标记,控制运费显示状态 if ($action_type === 'store_vault') { WC()->session->set('hide_shipping', true); WC()->session->set('chosen_shipping_methods', array()); // 清空已选配送方式 } else { WC()->session->set('hide_shipping', false); } wp_send_json_success(array( 'hide_shipping' => WC()->session->get('hide_shipping') )); } // 过滤可用配送方法:标记为隐藏时移除所有配送选项 add_filter('woocommerce_package_rates', 'hide_shipping_methods_for_vault', 10, 2); function hide_shipping_methods_for_vault($rates, $package) { if (WC()->session->get('hide_shipping')) { return array(); } return $rates; } // 移除结账页订单总计中的运费行 add_filter('woocommerce_get_order_item_totals', 'remove_shipping_total_row_from_checkout', 10, 3); function remove_shipping_total_row_from_checkout($total_rows, $order, $tax_display) { if (is_checkout() && WC()->session->get('hide_shipping')) { unset($total_rows['shipping']); } return $total_rows; } // 加载前端脚本并传递必要参数 add_action('wp_enqueue_scripts', 'enqueue_vault_shipping_frontend_scripts'); function enqueue_vault_shipping_frontend_scripts() { if (!is_checkout()) return; wp_enqueue_script( 'vault-shipping-handler', plugins_url('assets/js/vault-shipping.js', __FILE__), // 替换为你的JS文件实际路径 array('jquery'), '1.0.0', true ); // 传递AJAX地址、nonce及初始状态 wp_localize_script('vault-shipping-handler', 'VaultShippingParams', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('toggle_shipping_nonce'), 'initial_hide' => WC()->session->get('hide_shipping') ? true : false )); }
二、前端逻辑(JavaScript)
创建对应的JS文件(如vault-shipping.js),处理单选框交互、AJAX请求及UI更新:
jQuery(document).ready(function($) { // 页面加载时初始化UI状态 if (VaultShippingParams.initial_hide) { toggleShippingUI(true); } // 监听单选框切换事件 $('input[name="shipping_vault_choice"]').on('change', function() { const actionType = $(this).val(); // 假设单选框值为'store_vault'或'deliver' $.ajax({ url: VaultShippingParams.ajax_url, type: 'POST', data: { action: 'toggle_shipping_option', action_type: actionType, security: VaultShippingParams.nonce }, success: function(res) { if (res.success) { toggleShippingUI(res.data.hide_shipping); // 触发WooCommerce结账更新,同步总价 $(document.body).trigger('update_checkout'); } } }); }); // 结账更新后保持UI状态 $(document.body).on('updated_checkout', function() { if (VaultShippingParams.initial_hide) { toggleShippingUI(true); } }); // 统一处理UI显示/隐藏 function toggleShippingUI(hide) { if (hide) { $('.woocommerce-shipping-fields').hide(); $('.woocommerce-shipping-methods').hide(); } else { $('.woocommerce-shipping-fields').show(); $('.woocommerce-shipping-methods').show(); } } });
三、关键说明
- 会话标记控制:通过
WC()->session存储用户选择状态,确保页面刷新或AJAX更新后状态一致。 - 配送方法过滤:
woocommerce_package_rates过滤器直接移除所有可用配送方式,比修改标签更彻底。 - 总计行移除:
woocommerce_get_order_item_totals过滤器精准移除结账页的运费总计行。 - UI同步:结合WooCommerce原生的
update_checkout事件,确保总价和UI状态同步更新。
内容的提问来源于stack exchange,提问作者howtogeek24
相关产品推荐
相关产品推荐

