Диагностика: почему нужно менять стоимость товара в корзине по атрибутам
В WooCommerce стандартно стоимость товара определяется базовой ценой и вариациями. Но часто требуется реализовать дополнительное изменение цены в корзине в зависимости от выбранных атрибутов, которые не являются вариациями. Например, добавление наценки за особые параметры товара или скидки при определённых комбинациях.
Без кастомного кода WooCommerce не позволяет напрямую менять цену товара в корзине по произвольным атрибутам. Если попытаться сделать это через вариации, это усложняет управление товарами и не всегда подходит под задачу.
Как проверить, что стоимость товара зависит от атрибутов
- В карточке товара атрибуты отображаются, но не используются как вариации.
- При добавлении товара в корзину цена не меняется автоматически.
- Нужно, чтобы цена в корзине корректировалась программно после добавления товара.
Пошаговое решение: изменение цены товара в корзине по атрибутам через хук woocommerce_before_calculate_totals
Для решения задачи используем хук woocommerce_before_calculate_totals, который вызывается перед подсчётом итоговой суммы корзины. В этом хуке мы можем перебрать все товары в корзине и программно изменить цену в зависимости от нужных атрибутов.
1. Получаем товар и его атрибуты
add_action('woocommerce_before_calculate_totals', 'custom_change_price_based_on_attributes', 20, 1);
function custom_change_price_based_on_attributes( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$attributes = $product->get_attributes();
// Продолжим в следующем шаге
}
}2. Проверяем нужные атрибуты и меняем цену
Предположим, у товара есть атрибут pa_color (цвет) и мы хотим добавить наценку +500 рублей, если выбран цвет «красный».
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$variation_attributes = isset($cart_item['variation']) ? $cart_item['variation'] : [];
if ( isset($variation_attributes['attribute_pa_color']) && $variation_attributes['attribute_pa_color'] === 'red' ) {
$price = $product->get_price();
$new_price = $price + 500;
$product->set_price( $new_price );
}
}3. Полный рабочий пример кода
add_action('woocommerce_before_calculate_totals', 'custom_change_price_based_on_attributes', 20, 1);
function custom_change_price_based_on_attributes( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$variation_attributes = isset($cart_item['variation']) ? $cart_item['variation'] : [];
// Добавляем наценку за красный цвет
if ( isset($variation_attributes['attribute_pa_color']) && $variation_attributes['attribute_pa_color'] === 'red' ) {
$price = $product->get_price();
$new_price = $price + 500;
$product->set_price( $new_price );
}
// Пример: скидка 200 рублей, если выбран атрибут размер L
if ( isset($variation_attributes['attribute_pa_size']) && $variation_attributes['attribute_pa_size'] === 'l' ) {
$price = $product->get_price();
$new_price = max($price - 200, 0);
$product->set_price( $new_price );
}
}
}Проверка результата после внедрения
- Добавьте товар с нужными атрибутами в корзину.
- Перейдите в корзину и проверьте цену товара — она должна измениться согласно логике из кода.
- Проверьте несколько вариантов атрибутов для подтверждения корректной работы.
- Убедитесь, что итоговая сумма заказа корректна и отражает изменения.
Частые ошибки и как их исправить
- Цена не меняется в корзине: проверьте, что хук подключён с правильным приоритетом и что
$product->set_price()вызывается на объекте товара, а не на ID. - Изменения цены сохраняются для всех товаров: убедитесь, что логика изменения цены привязана к конкретным атрибутам, иначе цена изменится у всех товаров.
- Цена сбрасывается при обновлении страницы: используйте хук
woocommerce_before_calculate_totalsименно с параметром 1 для аргументов, чтобы цена корректно пересчитывалась каждый раз. - Наценка/скидка применяется неправильно: внимательно проверьте ключи атрибутов — они должны начинаться с
attribute_pa_и соответствовать slug атрибута.
Практические советы по безопасности и производительности
- Не храните изменённые цены в пользовательских метаполях или базе — меняйте цену только в объекте
$productв момент расчёта корзины. - Не усложняйте логику большого количества условий в одном хуке — выносите функции в отдельные методы для удобства поддержки.
- Тестируйте изменения на локальной копии сайта, чтобы избежать сбоев на живом ресурсе.
Сравнение вариантов изменения цены по атрибутам
| Способ | Плюсы | Минусы | Применимость |
|---|---|---|---|
| Создание вариаций с ценами | Стандартный метод, поддерживается WooCommerce | Много вариаций, сложность управления | Для ограниченного набора вариантов |
Код на хуке woocommerce_before_calculate_totals | Гибкость, можно менять цену динамически | Требует навыков программирования | Для кастомных условий |
| Плагины для наценок/скидок | Простота использования | Доп. нагрузка, не всегда гибко | Для быстрых решений без кода |