Диагностика задачи: зачем менять стоимость товара в корзине через хуки WooCommerce
В стандартном WooCommerce цена товара берётся из настроек товара и не меняется динамически в корзине. Однако в реальных проектах часто требуется менять стоимость товара в корзине по каким-то условиям: скидки, индивидуальные цены для пользователей, изменение цены в зависимости от количества или параметров.
Важно понимать, что простая замена цены в базе не работает — нужно корректно использовать хуки WooCommerce, чтобы цена отображалась и учитывалась при расчёте.
Основные хуки для изменения стоимости товара в корзине
Для изменения цены в корзине есть два основных хука:
woocommerce_before_calculate_totals— срабатывает перед пересчётом итогов корзины, здесь можно изменить цену каждого товара.woocommerce_cart_item_price— фильтр для отображения цены товара в корзине.
Использование этих хуков нужно сочетать, чтобы цена менялась и визуально, и в расчётах.
Пример: изменение цены товара в корзине на 10% скидку
add_action('woocommerce_before_calculate_totals', 'custom_change_price_in_cart', 20, 1);
function custom_change_price_in_cart( $cart ) {
if ( is_admin() && ! defined('DOING_AJAX') ) return;
// Защита от повторного изменения
if ( did_action('woocommerce_before_calculate_totals') >= 2 ) return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$original_price = $cart_item['data']->get_price();
$new_price = $original_price * 0.9; // скидка 10%
$cart_item['data']->set_price( $new_price );
}
}Этот код применит 10% скидку ко всем товарам в корзине.
Обновление отображаемой цены в корзине
Часто для кастомизации нужно изменить и отображаемую цену товара в списке корзины. Для этого используйте фильтр:
add_filter('woocommerce_cart_item_price', 'custom_cart_item_price_display', 10, 3);
function custom_cart_item_price_display($price_html, $cart_item, $cart_item_key) {
$price = $cart_item['data']->get_price();
return wc_price($price); // отобразить обновлённую цену
}Пошаговое решение задачи изменения цены товара в корзине
- Добавьте код изменения цены в файл functions.php вашей темы или в собственный плагин.
- Используйте хук
woocommerce_before_calculate_totalsдля задания нужной цены. - Через фильтр
woocommerce_cart_item_priceизмените отображение цены в корзине. - Проверьте, что при изменении количества в корзине итоговая сумма корректно пересчитывается.
- Опционально: добавьте логику для изменения цены только для определённых товаров, категорий или пользователей.
Проверка результата после внедрения
- Добавьте товар в корзину на сайте.
- Перейдите в корзину и убедитесь, что цена товара уменьшилась на 10% (в соответствии с примером).
- Измените количество товара, проверьте, что итоговая сумма пересчиталась правильно.
- Проверьте, что в админке заказов и в чекауте отображается изменённая цена.
Частые ошибки и как их исправить
- Изменение цены повторно при ajax-обновлении: функция меняет цену несколько раз, итоговая сумма неверная.
Решение: добавить проверкуdid_action('woocommerce_before_calculate_totals') < 2или флаг, чтобы не менять цену повторно. - Цена меняется в корзине, но не в заказе: нужно убедиться, что изменения применяются до создания заказа, иначе цена вернётся к исходной.
- Не учитывается налоговая ставка: при изменении цены вручную убедитесь, что налоговые настройки корректны, иначе итоговые суммы будут некорректны.
- Изменение цены влияет на все места сайта: нужно ограничить действие функции только корзиной и чекаутом, например, через
if (is_admin() && !defined('DOING_AJAX')) return;.
Практические советы по безопасности и производительности
- Не храните изменённую цену в базе данных — меняйте её динамически в корзине.
- Добавляйте проверки условий, чтобы не применять изменение цены ко всем товарам без необходимости.
- При сложной логике вычислений кешируйте результаты, чтобы не нагружать сервер.
- Тестируйте изменение цены с разными платежными шлюзами, чтобы избежать конфликтов.
Сравнение вариантов изменения цены в WooCommerce
| Метод | Пример | Плюсы | Минусы |
|---|---|---|---|
Использование woocommerce_before_calculate_totals | Пример выше | Динамическое, влияет на расчёты и отображение | Нужно аккуратно контролировать повторное применение |
| Изменение цены товара в базе данных | Прямое изменение через SQL | Постоянное изменение | Повреждает данные, не рекомендуется |
| Использование плагинов для скидок | WooCommerce Dynamic Pricing | Простота, гибкость | Зависимость от стороннего кода, нагрузка |