WooCommerce: автоматическое изменение стоимости и наличия товара после отмены заказа

Диагностика проблемы с отменой заказа в WooCommerce

При отмене заказа в WooCommerce часто возникает необходимость вернуть статус товаров в наличии и корректно обновить их цены, если они были изменены во время оформления заказа. Без автоматизации этих процессов магазин рискует потерять контроль над запасами и ценами, что ведёт к ошибкам в учёте и неудовлетворённому клиенту.

Основные признаки проблемы:

  • Товар остаётся в статусе «нет в наличии» после отмены заказа.
  • Цена товара не возвращается к исходной, если в заказе применялись скидки или специальные условия.
  • Ручное исправление занимает много времени и неэффективно при большом количестве заказов.

Пошаговое решение: автоматизация изменений через хук woocommerce_order_status_cancelled

WooCommerce предоставляет хук woocommerce_order_status_cancelled, который срабатывает при смене статуса заказа на «отменён». Используем его для возврата товаров в корзине к исходному состоянию.

1. Подключение функции к хуку

add_action('woocommerce_order_status_cancelled', 'custom_restore_product_stock_and_price_after_cancellation', 10, 1);

2. Реализация функции восстановления наличия и цены

function custom_restore_product_stock_and_price_after_cancellation($order_id) {
    if (!$order_id) return;

    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item_id => $item) {
        $product = $item->get_product();
        if (!$product) continue;

        // Восстановление запаса товара
        if ($product->managing_stock()) {
            $qty = $item->get_quantity();
            $product->increase_stock($qty);
            $product->save();
        }

        // Восстановление цены (если применялись кастомные скидки)
        // Предполагается, что цена менялась через метаданные заказа
        $original_price = $item->get_meta('_original_price');
        if ($original_price !== '') {
            update_post_meta($product->get_id(), '_price', $original_price);
            update_post_meta($product->get_id(), '_regular_price', $original_price);
            $product->save();
        }
    }
}

Примечание: Для корректного восстановления цены необходимо заранее сохранять оригинальную цену товара в метаданных заказа при оформлении. Это делается в хуке woocommerce_checkout_create_order_line_item.

3. Сохранение оригинальной цены при создании заказа

add_action('woocommerce_checkout_create_order_line_item', 'save_original_price_on_order_item', 10, 4);
function save_original_price_on_order_item($item, $cart_item_key, $values, $order) {
    $product = $item->get_product();
    if (!$product) return;

    $original_price = $product->get_regular_price();
    $item->update_meta_data('_original_price', $original_price);
}

Проверка результата после внедрения

Для проверки функционала:

  1. Создайте тестовый заказ с товарами, измените цены в корзине или примените скидки.
  2. Отмените заказ в админ-панели WooCommerce.
  3. Проверьте, что количество товара на складе увеличилось на количество из заказа.
  4. Проверьте, что цена товара в каталоге вернулась к исходной (регулярной) цене.
  5. Обратите внимание на логи ошибок PHP, если функционал не сработал.

Частые ошибки и способы их исправления

  • Цена не восстанавливается: убедитесь, что оригинальная цена сохраняется в метаданных заказа. Без этого вернуть цену невозможно.
  • Запас товара не обновляется: проверьте, что товар управляет запасом ($product->managing_stock() возвращает true).
  • Функция не вызывается: проверьте правильность подключения хуков и отсутствие конфликтов с другими плагинами.
  • Кэширование мешает обновлению цен: очистите кэш сайта и браузера после внедрения изменений.

Практические советы по безопасности и производительности

  • Не используйте этот код без тестирования на сайте с рабочей копией, чтобы избежать потери данных.
  • Сохраняйте оригинальную цену только если цена товара изменяется динамически, иначе лишние операции не нужны.
  • Минимизируйте количество операций с базой, вызывая $product->save() один раз после всех изменений.
  • Разграничивайте права доступа к отмене заказов, чтобы избежать злоупотреблений.

Сравнение вариантов решения задачи

МетодПлюсыМинусы
Ручное восстановление через админку Простота реализации Трудозатратно, ошибки, не масштабируется
Автоматизация через хук и код Надёжно, автоматизировано, масштабируемо Требуется разработка, тестирование
Использование плагинов управления запасами Готовое решение, поддержка Плагины могут влиять на производительность, возможны конфликты
Как создать и использовать комплексные метаполя в WordPress
11.03.2026
Как настроить отправку писем через SMTP в WordPress без плагинов
26.12.2025
Как удалить или изменить класс в меню WordPress без плагинов
06.01.2026
Как создать автоматические отзывы в WordPress с помощью WPRemark
16.03.2026
Как создать многоуровневую навигацию в WordPress с помощью hierarchical menu
13.04.2026

На оформлении, скоро здесь появится полноценный ресурс