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

WooCommerce中代码添加指定商品后设置价格为0的问题

解决WooCommerce Ajax添加商品后无法设置自定义价格的问题

问题核心原因

  • Ajax请求并行冲突:两个Ajax请求同时发起,设置价格的请求可能在商品尚未添加到购物车时执行,导致找不到目标商品。
  • 钩子逻辑混用错误:custom_set_cart_item_price同时绑定了Ajax钩子和woocommerce_before_calculate_totals,但Ajax调用时不会传入$cart对象,函数无法正常处理购物车数据。
  • 价格修改方式不符合规范:直接修改$cart->cart_contents不是WooCommerce推荐的价格修改方式,且未触发购物车重新计算流程。

修复方案

1. 调整JavaScript代码:合并请求避免并行问题

将自定义价格参数直接传入添加商品的Ajax请求,确保商品添加与价格设置逻辑同步:

<script>
const selectedProductId = getProdVal(randomDegree);
const isProductInCart = isProductAlreadyInCart(selectedProductId);

if (!productAdded && !isProductInCart) {
  jQuery.ajax({
    url: <?php echo json_encode(admin_url('admin-ajax.php')) ?>,
    type: 'POST',
    data: {
      action: 'add_product_to_cart_with_custom_price',
      product_id: selectedProductId,
      custom_price: 0.00 // 传递要设置的自定义价格
    },
    success: function(response) {
      console.log(response);
      productAdded = true;
      spinBtn.disabled = false;
    },
    error: function(error) {
      console.error(error);
      spinBtn.disabled = false;
    }
  });
}
</script>

2. 修改PHP代码:使用WooCommerce官方钩子处理价格

移除错误的Ajax绑定,改用WooCommerce专用钩子存储并应用自定义价格:

// 处理带自定义价格的商品添加请求
function add_product_to_cart_with_custom_price()
{
  if (isset($_POST['product_id']) && isset($_POST['custom_price'])) {
    $product_id = intval($_POST['product_id']);
    $custom_price = floatval($_POST['custom_price']);
    
    if (!in_array($product_id, get_product_ids_from_cart())) {
      // 添加商品时携带自定义价格数据
      WC()->cart->add_to_cart($product_id, 1, 0, [], ['custom_price' => $custom_price]);
    }
    
    echo json_encode(['success' => true, 'message' => '商品已添加到购物车并设置自定义价格']);
  } else {
    echo json_encode(['success' => false, 'message' => '商品ID或自定义价格缺失']);
  }

  exit;
}
add_action('wp_ajax_add_product_to_cart_with_custom_price', 'add_product_to_cart_with_custom_price');
add_action('wp_ajax_nopriv_add_product_to_cart_with_custom_price', 'add_product_to_cart_with_custom_price');

// 存储自定义价格到购物车项数据
function save_custom_cart_item_data($cart_item_data, $product_id, $variation_id)
{
  if (isset($_POST['custom_price'])) {
    $cart_item_data['custom_price'] = floatval($_POST['custom_price']);
    // 添加唯一标识,确保WooCommerce识别为独立购物车项(避免同商品价格冲突)
    $cart_item_data['unique_key'] = md5(microtime() . rand());
  }
  return $cart_item_data;
}
add_filter('woocommerce_add_cart_item_data', 'save_custom_cart_item_data', 10, 3);

// 在购物车计算总价前应用自定义价格
function apply_custom_cart_item_price($cart)
{
  // 后台非Ajax场景跳过
  if (is_admin() && !defined('DOING_AJAX')) return;
  
  foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
    if (isset($cart_item['custom_price'])) {
      $cart_item['data']->set_price($cart_item['custom_price']);
    }
  }
}
add_action('woocommerce_before_calculate_totals', 'apply_custom_cart_item_price');

3. 备选方案:保留双Ajax请求的顺序控制

如果必须分开两个请求,需确保设置价格的请求在商品添加成功后执行:

// 修改后的JS代码
<script>
const selectedProductId = getProdVal(randomDegree);
const isProductInCart = isProductAlreadyInCart(selectedProductId);

if (!productAdded && !isProductInCart) {
  jQuery.ajax({
    url: <?php echo json_encode(admin_url('admin-ajax.php')) ?>,
    type: 'POST',
    data: {
      action: 'add_product_to_cart',
      product_id: selectedProductId,
    },
    success: function(response) {
      console.log(response);
      productAdded = true;
      spinBtn.disabled = false;
      
      // 商品添加成功后再发起设置价格的请求
      jQuery.ajax({
        url: <?php echo json_encode(admin_url('admin-ajax.php')) ?>,
        type: 'POST',
        data: {
          action: 'set_cart_item_price',
          product_id: selectedProductId,
          custom_price: 0.00
        },
        success: function(res) {
          console.log(res);
        },
        error: function(err) {
          console.error(err);
        }
      });
    },
    error: function(error) {
      console.error(error);
      spinBtn.disabled = false;
    }
  });
}
</script>

对应的PHP设置价格函数:

function set_cart_item_price()
{
  if (isset($_POST['product_id']) && isset($_POST['custom_price'])) {
    $product_id = intval($_POST['product_id']);
    $custom_price = floatval($_POST['custom_price']);
    
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
      if ($cart_item['product_id'] === $product_id) {
        $cart_item['data']->set_price($custom_price);
        // 更新购物车会话
        WC()->cart->set_session();
        break;
      }
    }
    
    echo json_encode(['success' => true, 'message' => '价格已更新']);
  } else {
    echo json_encode(['success' => false, 'message' => '参数缺失']);
  }
  exit;
}
add_action('wp_ajax_set_cart_item_price', 'set_cart_item_price');
add_action('wp_ajax_nopriv_set_cart_item_price', 'set_cart_item_price');

内容的提问来源于stack exchange,提问作者Tom Hank

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:24:50