Диагностика проблемы: почему нужно удалять товары из заказов
В стандартной логике WooCommerce товары в заказах остаются в базе даже после отмены или возврата. Это может вызывать путаницу в отчетах, мешать точной аналитике продаж и создавать проблемы при синхронизации с внешними системами. Если у вас задача — полностью исключать отменённые или возвращённые товары из заказов, потребуется кастомный код, поскольку в WooCommerce такого поведения по умолчанию нет.
Пошаговое решение: добавляем автоматическое удаление товаров
1. Определяем нужные хуки WooCommerce
Для отслеживания отмены и возврата заказа используем хуки woocommerce_order_status_cancelled и woocommerce_order_status_refunded. Они срабатывают при смене статуса заказа на "отменён" и "возвращён" соответственно.
2. Реализуем функцию удаления товаров из заказа
Удалять товары из заказа можно через метод remove_item($item_id) объекта WC_Order. Для этого перебираем все позиции заказа и удаляем их.
function wplessons_remove_order_items_on_cancel_or_refund( $order_id ) {
if ( ! $order_id ) return;
$order = wc_get_order( $order_id );
if ( ! $order ) return;
foreach ( $order->get_items() as $item_id => $item ) {
$order->remove_item( $item_id );
}
$order->save();
}
add_action( 'woocommerce_order_status_cancelled', 'wplessons_remove_order_items_on_cancel_or_refund' );
add_action( 'woocommerce_order_status_refunded', 'wplessons_remove_order_items_on_cancel_or_refund' );3. Добавляем проверку, чтобы не удалять товары по ошибке
Если вы хотите удалять товары только при полном возврате, а не при частичном, можно добавить проверку статуса возврата. Для простоты в базовом примере удаляем при любом возврате или отмене.
Проверка результата после внедрения
Создайте тестовый заказ в WooCommerce с несколькими товарами. Затем выполните отмену заказа через админ-панель, изменив статус на "Отменён". Также протестируйте возврат заказа с помощью статуса "Возвращён".
После смены статуса откройте заказ и убедитесь, что список товаров пуст. Для дополнительной проверки можно вывести содержимое заказа через консоль или в коде:
$order = wc_get_order( $order_id );
var_dump( $order->get_items() ); // должен вернуть пустой массивЧастые ошибки и как их исправить
- Функция не срабатывает: проверьте, подключен ли код в functions.php вашей темы или в плагине. Убедитесь, что WooCommerce активен.
- Товары не удаляются: возможно, вы вызываете метод удаления без вызова
$order->save()— он обязателен для сохранения изменений. - Удаляются не все товары: убедитесь, что перебор происходит по всем элементам через
get_items(), включая различные типы позиций. - Проблемы с кешированием: очистите кеш сайта и браузера после внесения изменений.
Практические советы по безопасности и производительности
- Добавляйте проверку ролей пользователя, если код применяется в контексте фронтенда, чтобы избежать несанкционированного удаления.
- Избегайте повторных вызовов функции удаления, если статус уже был сменён и обработан — можно сохранять мета-данные заказа с отметкой об обработке.
- Код размещайте либо в дочерней теме, либо в отдельном плагине, чтобы избежать потери изменений при обновлении WooCommerce или темы.
Альтернативные варианты: плагин vs код
| Вариант | Плюсы | Минусы |
|---|---|---|
| Кастомный код (как в статье) | Точный контроль, нет лишних функций, бесплатно | Нужны навыки разработки, требует тестирования |
| Плагины для управления статусами заказов | Упрощают настройку, часто имеют дополнительные опции | Могут быть избыточными, влиять на производительность, требовать оплаты |