You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce AJAX加购后cart fragments未更新问题排查

原有实现代码

商品页购物车总额展示模板

<p>Your total: <span class="r_cart_total"><?= WC()->cart->get_cart_total(); ?></span></p>

无刷新更新片段挂载代码

add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_cart_fragments', 50, 1 );
function wc_refresh_cart_fragments( $fragments ){

    $cart_count = WC()->cart->get_cart_contents_count();
    $cart_total = WC()->cart->get_cart_total();
    // Normal version
    $count_normal = '<span class="r_cart_total">' .  $cart_total . '</span>';
    $fragments['.r_cart_total'] = $count_normal;

    return $fragments;
}

自定义AJAX加购代码

/**
* Add to cart product using ajax
**/
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
function woocommerce_ajax_add_to_cart() {

    $product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
    $quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
    $variation_id = absint($_POST['variation_id']);
    $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
    $product_status = get_post_status($product_id);
    $is_buy_all = filter_var($_POST['is_buy_all'], FILTER_VALIDATE_BOOLEAN);
    
    //if buy all product then remove all other products in the cart
    if($is_buy_all){
        foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
             WC()->cart->remove_cart_item( $cart_item_key );
        }
    }
    
    if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {
        
        do_action('woocommerce_ajax_added_to_cart', $product_id);
        
        //show success message add to cart
        if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
            wc_add_to_cart_message(array($product_id => $quantity), true);
        }
        
        if($is_buy_all && !empty($_POST['sub_products'])){
            $sub_products = json_decode(stripslashes($_POST['sub_products']));
            foreach($sub_products as $sub_product){
                $sub_product = trim($sub_product);
                $sub_product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($sub_product));
                $quantity = 1;
                $variation_id = absint($variation_id);
                $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $sub_product_id, $quantity);
                $sub_product_status = get_post_status($sub_product_id);
                if($passed_validation && WC()->cart->add_to_cart($sub_product_id, $quantity) && 'publish' === $sub_product_status) {
                    do_action('woocommerce_ajax_added_to_cart', $sub_product_id);
                }
            }
        }
        
        WC_AJAX :: get_refreshed_fragments();
        wp_die();
    } else {

        $data = array(
            'error' => true,
            'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));

        echo wp_send_json($data);
        wp_die();
    }

}

故障现象

移除购物车商品时,总额片段可正常无刷新更新;添加商品到购物车时,虽然已经在加购逻辑末尾调用WC_AJAX::get_refreshed_fragments(),但总额片段无法正常更新。

故障原因
  • 核心问题是购物车总额计算时机错误:WooCommerce的WC_Cart::add_to_cart()方法为了优化性能,不会在每次加购操作后立即重新计算购物车总额,尤其是代码中存在连续加购主商品、批量加购子商品的场景,购物车totals数据处于缓存状态,此时直接调用片段刷新方法,过滤器中拿到的get_cart_total()是加购操作前的旧值,前端替换后和更新前数值一致,表现为fragments不刷新。
  • 移除商品时功能正常的原因是WC_Cart::remove_cart_item()方法内部会自动触发购物车总额重算,所以移除场景下能拿到最新值。
  • 额外问题:直接输出get_cart_total()的原始值,没有经过WooCommerce价格格式化,返回的内容不带货币符号、千位分隔符,和全站价格显示规则不一致;WC_AJAX :: get_refreshed_fragments()的类名和方法中间多了空格,存在语法兼容风险;get_refreshed_fragments()方法本身会输出JSON后自动终止程序,后面多余的wp_die()属于无效代码。
修复步骤
  1. 所有购物车增删操作完成后,手动触发购物车总额重算,再调用fragments刷新方法
  2. 优化fragments返回的价格内容,使用原生wc_price()方法格式化输出,保持价格显示规则一致
  3. 修正代码语法问题,移除多余空格和无效终止逻辑
  4. 确保前端自定义AJAX逻辑没有覆盖WooCommerce原生的fragments替换机制,后端返回的片段数据由WooCommerce前端脚本自动完成DOM替换即可,不需要额外写JS修改节点内容。
修复后代码

1. 购物车总额片段过滤器代码

add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_cart_fragments', 50, 1 );
function wc_refresh_cart_fragments( $fragments ){
    // 强制重算购物车数据,避免读取缓存旧值
    WC()->cart->calculate_totals();
    // 格式化价格,匹配全站价格显示规则
    $cart_total_html = wc_price( WC()->cart->get_total() );
    $fragments['.r_cart_total'] = '<span class="r_cart_total">' . $cart_total_html . '</span>';

    return $fragments;
}

2. 自定义AJAX加购成功分支修改

找到自定义加购方法中加完所有商品(主商品+子商品)后的代码段,替换为以下内容:

// 所有增删购物车操作完成后,强制重算购物车总额
WC()->cart->calculate_totals();
// 输出刷新后的fragments,方法内部会自动终止程序
WC_AJAX::get_refreshed_fragments();

内容的提问来源于stack exchange,提问作者milind prajapati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:24:21