Диагностика задачи: зачем менять цену товара программно
Иногда в WooCommerce возникает необходимость динамически менять цену товара в корзине или на странице товара в зависимости от условий, например, количества, роли пользователя, даты или других параметров. Это может быть нужно для временных акций, кастомных скидок, или сложных бизнес-правил. Стандартные скидки WooCommerce или купоны не всегда позволяют реализовать нужную логику.
Как изменить цену товара в WooCommerce программно
Для изменения цены товара в корзине при определённых условиях чаще всего используются хуки, связанные с корзиной — woocommerce_before_calculate_totals. Этот хук позволяет изменять стоимость товаров до подсчёта итогов.
Пример кода — изменение цены в корзине при покупке более 5 единиц товара
add_action('woocommerce_before_calculate_totals', 'custom_change_price_for_bulk', 20, 1);
function custom_change_price_for_bulk($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 ($cart_item['quantity'] >= 5) {
// Устанавливаем новую цену, например, минус 10%
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.9;
$cart_item['data']->set_price($discounted_price);
}
}
}Пояснение к коду
- Проверяем, что код не выполняется в админке (кроме AJAX), чтобы не влиять на админские процессы.
- Защищаемся от повторного вызова, чтобы избежать ошибок.
- Для каждого товара в корзине проверяем количество и, если условие выполняется, меняем цену.
Изменение цены на странице товара (перед добавлением в корзину)
Чтобы изменить цену товара на странице товара, нужно использовать фильтр woocommerce_product_get_price и аналогичные для правильного отображения цены в каталоге и на странице.
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
// Пример: скидка 15% для пользователя с ролью 'subscriber'
if (current_user_can('subscriber')) {
$price = $price * 0.85;
}
return $price;
}Как проверить, что цена изменилась
- Добавьте товар на страницу с условием (например, войдите под ролью subscriber).
- Проверьте отображение цены на странице товара и в корзине.
- В корзине цена должна соответствовать логике из
woocommerce_before_calculate_totals. - Для отладки можно временно добавить
error_log()вызовы внутри функций, чтобы убедиться, что они выполняются.
Частые ошибки и их исправления
- Изменение цены применяется несколько раз: Используйте проверку
did_action('woocommerce_before_calculate_totals') < 2, чтобы избежать повторного применения. - Цена меняется в админке: Добавьте условие
if (is_admin() && !defined('DOING_AJAX')) return;. - Цена не обновляется в корзине после изменения количества: Проверьте, что хук
woocommerce_before_calculate_totalsсрабатывает, а также очистите кэш браузера и кэш сайта. - Изменённая цена не отображается на странице товара: Используйте фильтры
woocommerce_product_get_price,woocommerce_product_get_regular_price, иwoocommerce_product_get_sale_priceвместе.
Практические советы по безопасности и производительности
- Не храните изменённые цены в базе данных — используйте только динамическое изменение через хуки.
- Минимизируйте нагрузку в функциях — не делайте сложных запросов или тяжёлых операций в хуках, влияющих на процесс подсчёта корзины.
- Для более сложных правил используйте кэширование промежуточных результатов, если логика зависит от внешних API.
- Тестируйте изменения в режиме отладки (WP_DEBUG), чтобы отловить ошибки.
Чек-лист для внедрения динамического изменения цены в WooCommerce
- Определить условия изменения цены (количество, роль пользователя, дата и т.п.).
- Добавить функцию на хук
woocommerce_before_calculate_totalsдля изменения цены в корзине. - Добавить фильтры для изменения цены на странице товара (
woocommerce_product_get_priceи др.). - Проверить на разных ролях пользователей и в разных сценариях.
- Протестировать работу корзины и оформления заказа.
- Проверить отсутствие конфликтов с другими плагинами, кешированием и темой.
- Обеспечить защиту от повторного применения и работу только на фронтенде.
Сравнение подходов изменения цены в WooCommerce
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Изменение цены через woocommerce_before_calculate_totals | Динамическое изменение цены в корзине | Гибко, не меняет базу данных | Не влияет на цену на странице товара без дополнительных фильтров |
Изменение цены через фильтры woocommerce_product_get_price | Динамическая цена на странице товара | Отображение актуальной цены для пользователя | Может конфликтовать с кэшированием и плагинами кеша |
| Использование купонов и скидок WooCommerce | Стандартные механизмы скидок | Простота настройки | Ограничена по сложным условиям |