Как автоматически удалить товар из заказов WooCommerce после отмены или возврата

Диагностика задачи: зачем удалять товар из заказа после отмены или возврата

В стандартном WooCommerce товары, добавленные в заказ, сохраняются в базе даже если заказ отменён или возвращён. Это может приводить к ошибкам при статистике, инвентаризации и аналитике, особенно если товар в заказе больше не актуален. Автоматическое удаление таких товаров из отменённых или возвращённых заказов помогает держать данные в чистоте и предотвращает накладки.

Как определить, что товар в заказе нужно удалить

Товар нужно удалить, если статус заказа изменился на один из следующих:

  • cancelled — заказ отменён;
  • refunded — заказ частично или полностью возвращён;
  • failed — заказ неудачный (опционально, если нужно).

Удаление должно происходить только после подтверждения изменения статуса, чтобы не потерять данные преждевременно.

Пошаговое решение: код для автоматического удаления товаров из заказа

Реализуем на хуке woocommerce_order_status_changed. В обработчике проверяем новый статус и очищаем позиции заказа (items) при необходимости.

add_action('woocommerce_order_status_changed', 'wplessons_remove_items_on_cancel_refund', 20, 4);
function wplessons_remove_items_on_cancel_refund($order_id, $old_status, $new_status, $order) {
    if (in_array($new_status, ['cancelled', 'refunded'])) {
        // Получаем все позиции заказа
        $items = $order->get_items();
        foreach ($items as $item_id => $item) {
            // Удаляем позицию из заказа
            $order->remove_item($item_id);
        }
        // Сохраняем изменения
        $order->calculate_totals();
        $order->save();
    }
}

Обратите внимание, что мы вызываем calculate_totals() для пересчёта итогов заказа после удаления позиций, и затем сохраняем заказ.

Альтернативный вариант: удалять только конкретные товары

Если нужно удалять не все товары, а только определённые (например, с конкретенным метаполем или товарной категорией), можно добавить фильтрацию:

foreach ($items as $item_id => $item) {
    $product = $item->get_product();
    if ($product && has_term('special-category', 'product_cat', $product->get_id())) {
        $order->remove_item($item_id);
    }
}

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

  1. Создайте тестовый заказ в WooCommerce с несколькими товарами.
  2. В админ-панели измените статус заказа на cancelled или refunded.
  3. Обновите страницу редактирования заказа и убедитесь, что список товаров пуст.
  4. Проверьте, что итоговые суммы заказа пересчитаны и равны нулю.
  5. Проверьте, что отчетность WooCommerce не учитывает удалённые товары в этих заказах.

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

  • Товары не удаляются: Убедитесь, что хук подключён с достаточным приоритетом (не ниже 20), и что функция получает правильный объект $order. Также проверьте, что статус заказа действительно меняется на cancelled или refunded.
  • Итоговая сумма заказа не обновляется: Обязательно вызывайте calculate_totals() и save() после удаления позиций.
  • Ошибка при удалении: Иногда плагин кеширования или сторонние расширения блокируют изменение заказа. Попробуйте отключить их на время теста.
  • Удаляются не все нужные товары: Проверьте логику фильтрации, если удаляете не все позиции.

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

  • Не удаляйте товары из заказов с другими статусами, чтобы избежать потери данных.
  • Храните резервные копии базы данных перед внедрением кода, особенно если заказы важны для бухгалтерии.
  • Если магазин большой и заказов много, оптимизируйте код, например, обрабатывайте удаление в асинхронных задачах WP Cron.
  • Тестируйте решение на staging-сервере, чтобы избежать сбоев на живом сайте.

Сравнение вариантов реализации удаления товаров из заказа

МетодПлюсыМинусы
Удаление всех товаров при смене статусаПростая реализация, полное очищение заказаПотеря данных по всем товарам, может не подходить для частичных возвратов
Удаление по категории или метаполюТочный контроль, не удаляет все позицииСложнее в реализации, требует поддержки метаданных
Ручное удаление товаров в админкеБезопасно, контролируемоТрудозатратно, можно забыть
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
12.05.2026
Как избежать проблем при использовании PHP 8 в WordPress
15.03.2026
Как использовать хук WooCommerce для обновления мета данных заказа на этапе оформления
07.05.2026
Как создать уникальный фильтр по пользовательским мета-полям в WordPress
18.02.2026
Как снизить размер библиотеки WP Block Library в WordPress для ускорения сайта
22.01.2026