WooCommerce购物车自定义产品价格计算更新及旧商品价格归零问题求助
问题根源
你当前代码的WC_Session中foam_price变量仅支持存储单条商品的ID与价格,每次新商品触发Ajax请求时会直接覆盖之前存储的旧商品数据。遍历购物车修改价格时,仅与Session中最新存储ID匹配的商品会被设置自定义价格,其余未匹配的商品会沿用后台设置的基础价格(若你将泡沫类产品的基础价格设为0,旧商品就会显示为0)。
修复方案
方案1:修改现有Session存储逻辑(适配同产品统一自定义价格场景)
1. 调整Ajax存储Session逻辑,改为多商品价格映射
function get_custom_product_price_set_to_session(){ if (isset($_POST['foamProductId']) && isset($_POST['foamPrice'])) { if (!WC()->session->has_session()) { WC()->session->set_customer_session_cookie(true); } // 读取已有的价格映射,不存在则初始化为空数组 $foam_prices = WC()->session->get('foam_prices', []); // 存入当前商品价格,不会覆盖其他商品数据 $foam_prices[(int)wc_clean($_POST['foamProductId'])] = (float)wc_clean($_POST['foamPrice']); WC()->session->set('foam_prices', $foam_prices); } } add_action('wp_ajax_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session'); add_action('wp_ajax_nopriv_get_custom_product_price_set_to_session', 'get_custom_product_price_set_to_session');
2. 调整购物车价格更新逻辑
add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 20, 1); function custom_cart_item_price($cart){ if (is_admin() && !defined('DOING_AJAX')) return; if (did_action('woocommerce_before_calculate_totals') >= 2) return; // 读取所有泡沫商品的价格映射 $foam_prices = WC()->session->get('foam_prices', []); foreach ($cart->get_cart() as $cart_item) { $product_id = $cart_item['data']->get_id(); if (isset($foam_prices[$product_id])) { $cart_item['data']->set_price($foam_prices[$product_id]); } } }
方案2:自定义价格绑定购物车项(推荐,适配同产品不同尺寸不同价格场景)
该方案将自定义价格直接存入购物车项字段,不依赖全局Session,不会出现数据覆盖问题,也支持同产品不同参数对应不同价格的需求:
// 商品加入购物车时保存自定义价格到购物车项 add_filter('woocommerce_add_cart_item_data', 'save_custom_price_to_cart_item', 10, 2); function save_custom_price_to_cart_item($cart_item_data, $product_id) { if (isset($_POST['foamPrice'])) { $cart_item_data['custom_foam_price'] = (float)wc_clean($_POST['foamPrice']); // 生成唯一标识,避免同产品不同价格的购物车项被合并 $cart_item_data['unique_key'] = md5(microtime().rand()); } return $cart_item_data; } // 读取购物车项绑定的自定义价格设置 add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price_from_item_data', 20, 1); function custom_cart_item_price_from_item_data($cart) { if (is_admin() && !defined('DOING_AJAX')) return; if (did_action('woocommerce_before_calculate_totals') >= 2) return; foreach ($cart->get_cart() as $cart_item) { if (isset($cart_item['custom_foam_price'])) { $cart_item['data']->set_price($cart_item['custom_foam_price']); } } }
使用该方案需要调整前端逻辑,将计算得到的foamPrice参数随加入购物车的请求一起提交即可,无需单独调用Ajax存Session。
内容的提问来源于stack exchange,提问作者Valeria Melinte
相关产品推荐
相关产品推荐

