Диагностика проблемы: зачем автоматизировать изменение стоимости товаров в корзине
В WooCommerce часто возникает необходимость динамически менять стоимость товаров в зависимости от условий корзины — например, при достижении определённого количества товаров, суммы заказа или наличия конкретных товаров. Это полезно для реализации скидок, акций, программ лояльности без постоянного ручного обновления цен.
Стандартный функционал WooCommerce не позволяет гибко менять цену на лету без использования плагинов или кастомного кода. При отсутствии автоматизации приходится создавать купоны или вручную редактировать цены, что неудобно и не оптимально.
Пошаговое решение: как изменить цену товаров по условиям корзины с помощью хуков WooCommerce
1. Использование хука woocommerce_before_calculate_totals
Этот хук позволяет изменить цену товаров непосредственно перед подсчётом стоимости корзины. Важно применять изменения к объектам корзины, а не к постам продуктов, чтобы избежать постоянных изменений в базе.
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_based_on_cart_conditions', 20, 1);
function custom_dynamic_price_based_on_cart_conditions( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
// Пример условия: скидка 10% если в корзине больше 3 товаров
$total_quantity = 0;
foreach ( $cart->get_cart() as $cart_item ) {
$total_quantity += $cart_item['quantity'];
}
if ( $total_quantity > 3 ) {
foreach ( $cart->get_cart() as $cart_item ) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.9; // скидка 10%
$cart_item['data']->set_price( $discounted_price );
}
} else {
// Возвращаем оригинальные цены, если условие не выполнено
foreach ( $cart->get_cart() as $cart_item ) {
$cart_item['data']->set_price( $cart_item['data']->get_regular_price() );
}
}
}
2. Условие по наличию определённого товара в корзине
Например, давайте изменим цену товара с ID 123, если в корзине есть товар с ID 456.
add_action('woocommerce_before_calculate_totals', 'change_price_if_specific_product_in_cart', 20, 1);
function change_price_if_specific_product_in_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$has_product_456 = false;
foreach ( $cart->get_cart() as $cart_item ) {
if ( $cart_item['product_id'] == 456 ) {
$has_product_456 = true;
break;
}
}
foreach ( $cart->get_cart() as $cart_item ) {
if ( $has_product_456 && $cart_item['product_id'] == 123 ) {
$cart_item['data']->set_price( 50 ); // новая цена 50
} else {
$cart_item['data']->set_price( $cart_item['data']->get_regular_price() );
}
}
}
Проверка результата после внедрения
- Добавьте товары в корзину в соответствии с условиями.
- Обновите страницу корзины или оформления заказа.
- Проверьте, что цены изменились согласно логике (например, скидка 10% или цена 50 для товара 123).
- Очистите кэш браузера и кеш плагинов, если изменения не отображаются.
Частые ошибки и как исправить
- Изменения цен не применяются — возможно, код не подключён или приоритет хука слишком низкий. Убедитесь, что функция подключена правильно, и ставьте приоритет 20 или выше.
- Цены меняются в админке — добавьте проверку
is_admin() && ! defined('DOING_AJAX'), чтобы избежать влияния на административные запросы. - Цены сбрасываются после обновления страницы — убедитесь, что изменения происходят на каждом вызове хука, так как цены не сохраняются в базе.
- Проблемы с кешированием — отключите кеш страниц на страницах корзины и оформления заказа.
Практические советы по производительности и безопасности
- Избегайте тяжелых запросов и сложных циклов внутри хука
woocommerce_before_calculate_totals, чтобы не замедлять загрузку корзины. - Не изменяйте цену товара в базе данных напрямую, используйте методы объектов корзины.
- Проверяйте условия корректно, чтобы не допустить конфликтов с другими плагинами или акциями.
- Для сложных условий рассмотрите создание отдельного плагина с изоляцией логики.
Сравнение вариантов реализации изменения цены
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
Хук woocommerce_before_calculate_totals | Гибкость, не требует сторонних плагинов, работает для любых условий | Требует программирования, возможны конфликты с другими плагинами | Приведён выше |
| Плагины скидок | Удобный интерфейс, готовые решения | Может быть дорого, ограничена кастомизация | WooCommerce Dynamic Pricing |
| Использование купонов | Простота использования | Менее гибко, требует ручного применения | Встроенный функционал WooCommerce |