Диагностика задачи: зачем менять цену и наличие товара при оформлении заказа
В типовом WooCommerce после того, как товар добавлен в корзину, его цена и статус наличия не меняются автоматически. Однако в ряде кейсов необходимо динамически корректировать стоимость товара или статус наличия прямо при оформлении заказа. Это может быть нужно при специальных акциях, изменении цены по региону, контроле складских остатков в реальном времени или при автоматическом резервировании товара.
Без кастомной логики WooCommerce не умеет обновлять эти параметры на лету, что приводит либо к неверному отображению цены, либо к проблемам с учётом остатков.
Как проверить, что цена и наличие не меняются автоматически
- Добавьте товар в корзину и перейдите к оформлению заказа;
- Попробуйте изменить данные, которые должны повлиять на цену (например, адрес доставки, купон, количество);
- Если цена и наличие товара не меняются, значит кастомной логики нет.
Пошаговое решение: динамическое изменение стоимости и наличия товара
1. Изменение цены товара в корзине через хук woocommerce_before_calculate_totals
Этот хук позволяет изменить цену товара в объекте WC_Cart перед подсчётом итогов.
add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_change', 20, 1);
function custom_dynamic_price_change( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
foreach ( $cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
// Например, уменьшаем цену на 10% для товара с ID 123
if ( $product->get_id() === 123 ) {
$original_price = $product->get_regular_price();
$new_price = $original_price * 0.90; // скидка 10%
$product->set_price( $new_price );
}
}
}2. Автоматическое изменение наличия товара при оформлении заказа
Чтобы менять наличие, нужно воздействовать на статус продукта после оформления заказа. Рекомендуется использовать хук woocommerce_order_status_completed или woocommerce_reduce_order_stock.
add_action('woocommerce_reduce_order_stock', 'custom_update_product_stock_status', 10, 1);
function custom_update_product_stock_status( $order ) {
foreach ( $order->get_items() as $item ) {
$product = $item->get_product();
if ( ! $product ) continue;
$stock_quantity = $product->get_stock_quantity();
// Если остаток 0 или меньше, меняем статус на "нет в наличии"
if ( $stock_quantity <= 0 ) {
$product->set_stock_status('outofstock');
$product->save();
}
}
}Проверка результата после внедрения
- Добавьте товар с ID 123 в корзину и перейдите к оформлению заказа — цена должна показываться с 10% скидкой;
- Оформите заказ, уменьшив остаток товара до 0 — после завершения заказа статус товара должен смениться на «нет в наличии»;
- Проверьте страницу товара в админке и на сайте, чтобы убедиться, что изменения отразились.
Частые ошибки и как их исправить
- Цена не меняется в корзине: часто вызвано неправильным приоритетом хука
woocommerce_before_calculate_totalsили отсутствием проверкиis_admin(). Обязательно добавляйте проверкуif ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;чтобы избежать конфликтов. - Статус товара не обновляется: убедитесь, что у товара включён учёт остатков (
manage_stock) и вы вызываете$product->save()после изменения статуса. - Изменения цены не сохраняются после обновления корзины: иногда другие плагины или тема могут сбрасывать цену. Проверьте конфликты, отключая плагины поочерёдно.
Практические советы по производительности и безопасности
- Минимизируйте работу с базой данных в хуках оформления заказа — используйте кэширование, если нужно несколько запросов;
- Избегайте изменения цены товара вне корзины, чтобы не нарушать логику WooCommerce;
- Не отключайте проверки
is_admin()без необходимости, чтобы избежать проблем с админкой; - Проверяйте права доступа при сохранении данных, чтобы исключить возможность вмешательства злоумышленников.
Сравнение подходов: плагин vs кастомный код
| Метод | Плюсы | Минусы | Компромиссы |
|---|---|---|---|
| Использование плагинов для динамических цен и управления складом | Быстрая настройка, поддержка, готовый функционал | Могут быть тяжелыми, конфликтовать, не всегда гибкие | Подходит для бизнесов без разработчиков, но ограничивает кастомизацию |
| Кастомный код в functions.php или плагине | Максимальная гибкость, легковесность, точечные решения | Требует навыков разработки, сложнее поддерживать | Идеально для уникальных бизнес-процессов и опытных разработчиков |