Диагностика задачи: зачем менять цену товара в корзине
В стандартном WooCommerce цена товара берётся из прайс-листа и не меняется динамически. Однако бывают задачи, когда нужно изменить стоимость конкретного товара в корзине по условиям: скидка за количество, специальное предложение, добавление наценки за опции или индивидуальная цена для определённых пользователей.
Если вы столкнулись с необходимостью программно изменить цену товара именно в корзине (без изменения основной цены товара в каталоге), то нужно работать с соответствующими хуками WooCommerce.
Какие хуки использовать для изменения цены товара в корзине
Для изменения цены в корзине применяются хуки:
woocommerce_before_calculate_totals— основной хук для изменения цены товара в корзине перед пересчётом итогов.woocommerce_cart_item_price— для изменения отображаемой цены товара в корзине (если нужно кастомизировать вывод).
Самое главное — изменить цену через объект WC_Cart_Item до пересчёта итогов, иначе изменения не применятся.
Пример: скидка 10% на товар с ID 123 при количестве больше 3
add_action('woocommerce_before_calculate_totals', 'custom_change_cart_item_price', 10, 1);
function custom_change_cart_item_price( $cart ) {
if ( is_admin() && ! defined('DOING_AJAX') )
return;
// Перебираем все товары в корзине
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$product_id = $product->get_id();
$quantity = $cart_item['quantity'];
// Проверяем условия
if ( $product_id == 123 && $quantity > 3 ) {
$original_price = $product->get_regular_price();
$discounted_price = $original_price * 0.9; // скидка 10%
// Устанавливаем новую цену
$product->set_price( $discounted_price );
}
}
}Проверка результата после внедрения
Чтобы убедиться, что цена изменена корректно:
- Добавьте в корзину товар с ID 123 в количестве больше 3.
- Обновите страницу корзины и посмотрите цену товара — она должна быть на 10% ниже обычной.
- Проверьте итоговые суммы и оформление заказа, чтобы скидка применялась.
- При изменении количества меньше 4 цена должна вернуться к стандартной.
Частые ошибки при изменении цены в корзине
- Изменение цены вне хука
woocommerce_before_calculate_totals: цена не обновится, итоговые суммы останутся прежними. - Изменение цены объекта
$cart_itemвместо объекта$product: цена не применяется — нужно менять цену у объекта продукта. - Не проверена область видимости (админка, AJAX): изменения могут сработать в админке и вызвать ошибки, поэтому нужна проверка
is_admin()иDOING_AJAX. - Отсутствие сброса цены при несоответствии условий: если не вернуть цену к исходной при несоответствии условиям, цена останется изменённой.
Практические советы для безопасности и производительности
- Используйте кэширование, если условия сложные и требуют запросов к базе или внешним сервисам — чтобы не замедлять загрузку корзины.
- Избегайте массового изменения цен без условий — это может привести к путанице и ошибкам в заказах.
- Тестируйте изменения на тестовом сайте и с разными способами оплаты — чтобы исключить конфликты.
Дополнительный пример: добавление наценки за пользовательскую опцию
add_action('woocommerce_before_calculate_totals', 'add_custom_fee_to_cart_item', 20, 1);
function add_custom_fee_to_cart_item( $cart ) {
if ( is_admin() && ! defined('DOING_AJAX') )
return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( isset( $cart_item['custom_option'] ) && $cart_item['custom_option'] === 'extra' ) {
$product = $cart_item['data'];
$price = $product->get_price();
$new_price = $price + 50; // добавляем 50 рублей
$product->set_price( $new_price );
}
}
}Сравнение вариантов изменения цены в корзине
| Метод | Преимущества | Недостатки |
|---|---|---|
Хук woocommerce_before_calculate_totals | Полный контроль над ценой, применяется перед расчетом итогов | Требует точного программирования, может вызвать ошибки при неправильной работе |
| Использование плагинов скидок | Простота, готовые решения для типовых задач | Могут быть избыточны, не всегда гибко настраиваются |
| Изменение цены товара через API / фильтры отображения | Меняет только отображение, не влияет на итоговые суммы | Не подходит для реальных изменений стоимости заказа |