Диагностика задачи: зачем менять цену товара по сумме корзины
В стандартном WooCommerce цены товаров фиксированы и не зависят от содержимого корзины. Однако в ряде случаев требуется динамическая корректировка цены товара в зависимости от общей суммы товаров в корзине — например, для предоставления скидок при больших заказах или стимуляции кросс-продаж.
Вопрос: как реализовать изменение цены отдельного товара при достижении определённого порога суммы корзины без сторонних плагинов?
Пошаговое решение: динамическая корректировка цены с помощью фильтра
Для изменения цены товара в зависимости от суммы корзины нужно использовать хук WooCommerce woocommerce_before_calculate_totals. Он позволяет изменять цену каждого товара в корзине перед подсчётом итогов.
Пример кода для functions.php вашей темы или отдельного плагина:
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_based_on_cart_total', 20, 1);
function custom_dynamic_price_based_on_cart_total($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
if (did_action('woocommerce_before_calculate_totals') >= 2) return;
// Получаем текущую сумму корзины без учёта скидок
$cart_total = 0;
foreach ($cart->get_cart() as $cart_item) {
$cart_total += $cart_item['data']->get_price() * $cart_item['quantity'];
}
// Задаём пороговую сумму для изменения цены
$threshold = 5000; // например, 5000 рублей
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
$original_price = floatval($product->get_regular_price());
if ($cart_total >= $threshold) {
// Применяем скидку 10% к цене товара
$new_price = $original_price * 0.9;
$product->set_price($new_price);
} else {
// Возвращаем оригинальную цену, если порог не достигнут
$product->set_price($original_price);
}
}
}Объяснение кода
- Проверяем, что функция не сработает в админке или при AJAX-запросах вне фронтенда.
- Считаем сумму корзины с текущими ценами товаров.
- Если сумма больше порога, уменьшаем цену каждого товара на 10%.
- Иначе возвращаем исходную цену товара.
Проверка результата после внедрения
1. Добавьте товары в корзину так, чтобы общая сумма была меньше 5000 рублей — цены не должны изменяться.
2. Добавьте товары на сумму выше 5000 рублей — цена на товары в корзине должна уменьшиться на 10%.
3. В админке WooCommerce в разделе заказов проверьте итоговые цены и сумму заказа.
4. Включите режим отладки WooCommerce (define('WP_DEBUG', true);) и убедитесь в отсутствии ошибок.
Частые ошибки и их исправление
- Цена не меняется: Проверьте, что код добавлен в правильный файл (functions.php или плагин) и что нет синтаксических ошибок.
- Цена меняется, но итоговая сумма некорректна: Убедитесь, что в корзине нет других плагинов, которые также меняют цену, вызывая конфликт.
- Изменения применяются в админке или на странице заказа: Добавьте проверки
is_admin()иDOING_AJAXкак в примере, чтобы избежать этого. - Цены меняются неправильно при повторном пересчёте: Используйте
did_action('woocommerce_before_calculate_totals'), чтобы предотвратить повторные изменения.
Практические советы по безопасности и производительности
- Не храните изменённые цены в базе — меняйте их только временно через фильтр, иначе могут возникнуть проблемы с учётом заказов и отчетностью.
- Для ускорения вычислений можно кэшировать сумму корзины, если она часто запрашивается в разных местах.
- Тестируйте на чистой установке WooCommerce, чтобы убедиться в отсутствии конфликтов с другими плагинами.
- Внимательно проверяйте влияние изменения цены на расчёт налогов, если они у вас активированы.
Сравнение вариантов реализации
| Метод | Преимущества | Недостатки |
|---|---|---|
Код на хуке woocommerce_before_calculate_totals | Гибкий, без сторонних плагинов, полный контроль | Требует навыков PHP и тестирования; возможны ошибки при конфликте с другими плагинами |
| Плагины скидок и динамического ценообразования | Простота настройки, готовые интерфейсы | Могут быть платными, утяжеляют сайт, ограниченная кастомизация |