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

购物车含分类A商品时为分类B商品打9折的功能故障排查

购物车分类折扣不生效问题排查与修复

问题描述

我需要实现:当购物车中有分类A的商品时,给所有分类B的商品打10%折扣(支持按总金额折扣或单品分别折扣)。但我编写的代码未生效,请求排查问题:

add_action( 'woocommerce_before_calculate_totals', 'apply_category_discount_in_cart', 10, 1 );

function apply_category_discount_in_cart( $cart ) {

  if ( is_admin() && ! defined( 'DOING_AJAX' ) )
    return;

  if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
    return;

  $discount_amount = 0;
  $category_A_in_cart = false;

  // Loop through each item in the cart
  foreach ( $cart->get_cart() as $cart_item ) {
    $product = $cart_item['data'];

    // Check if the product has category A
    if ( has_term( 'categorya', 'product_cat', $product->get_id() ) ) {
      $category_A_in_cart = true;
      break;
    }
  }

  // If a product with category A is found in the cart
  if ( $category_A_in_cart ) {
    // Loop through each item in the cart again
    foreach ( $cart->get_cart() as $cart_item ) {
      $product = $cart_item['data'];

      // Check if the product has category B
      if ( has_term( 'categoryb', 'product_cat', $product->get_id() ) ) {
        $discount_amount += $cart_item['line_total'] * 0.1;
        $cart_item['data']->set_price( $cart_item['data']->get_price() * 0.9 );
      }
    }

    // Add the discount amount as a fee
    $cart->add_fee( 'Discount', -$discount_amount, true );
  }

}

问题根源分析

  1. 重复折扣逻辑冲突:你同时执行了单品降价和添加负费用折扣两种操作,导致计算逻辑混乱,且line_total在woocommerce_before_calculate_totals钩子执行阶段还未完成最终计算,直接取值会得到错误结果。
  2. 分类检查对象错误:使用$product->get_id()获取ID时,若商品是可变产品(带属性的商品),该ID是子产品ID,而分类通常设置在父产品上,应该用$cart_item['product_id']来检查分类归属。
  3. 价格修改可靠性不足:直接修改$cart_item['data']->get_price()的方式,在部分场景下会因对象引用问题导致修改不生效。

修复方案

方案1:单品分别折扣(直接修改商品单价)

add_action( 'woocommerce_before_calculate_totals', 'apply_category_discount_in_cart', 20, 1 );

function apply_category_discount_in_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    $category_a_exists = false;
    $category_a_slug = 'categorya'; // 替换为你的分类A别名
    $category_b_slug = 'categoryb'; // 替换为你的分类B别名

    // 检查购物车是否存在分类A商品
    foreach ( $cart->get_cart() as $cart_item ) {
        if ( has_term( $category_a_slug, 'product_cat', $cart_item['product_id'] ) ) {
            $category_a_exists = true;
            break;
        }
    }

    if ( $category_a_exists ) {
        // 为分类B商品设置10%折扣
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( has_term( $category_b_slug, 'product_cat', $cart_item['product_id'] ) ) {
                $original_price = $cart_item['data']->get_regular_price();
                $discounted_price = $original_price * 0.9;
                $cart_item['data']->set_price( $discounted_price );
            }
        }
    }
}
  • 说明:该方案直接修改分类B商品的单价,购物车中每个单品会显示折扣后价格,总价自动计算。

方案2:总金额折扣(通过负费用实现)

add_action( 'woocommerce_cart_calculate_fees', 'apply_category_b_total_discount', 10, 1 );

function apply_category_b_total_discount( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $category_a_slug = 'categorya';
    $category_b_slug = 'categoryb';
    $discount_rate = 0.1;
    $category_a_exists = false;
    $category_b_total = 0;

    // 检查分类A商品是否存在
    foreach ( $cart->get_cart() as $cart_item ) {
        if ( has_term( $category_a_slug, 'product_cat', $cart_item['product_id'] ) ) {
            $category_a_exists = true;
            break;
        }
    }

    if ( $category_a_exists ) {
        // 计算分类B商品的总金额
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( has_term( $category_b_slug, 'product_cat', $cart_item['product_id'] ) ) {
                $category_b_total += $cart_item['line_total'];
            }
        }

        // 添加折扣费用项
        if ( $category_b_total > 0 ) {
            $discount_amount = $category_b_total * $discount_rate;
            $cart->add_fee( '分类B专属折扣', -$discount_amount, true );
        }
    }
}
  • 说明:该方案不修改单品价格,而是在购物车底部添加一个负费用项,显示分类B商品的总折扣金额。

内容的提问来源于stack exchange,提问作者Richard Mišenčík

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:10:28