Диагностика задачи: зачем удалять товар после отмены заказа
В стандартных сценариях WooCommerce товары остаются в каталоге вне зависимости от статуса заказов. Однако в ряде случаев, например при продаже эксклюзивных или ограниченных товаров, необходимо автоматически удалять товар из базы после отмены заказа, чтобы избежать повторной продажи. Важно понимать, что здесь речь именно об удалении товара, а не о простом изменении его статуса.
Как реализовать автоматическое удаление товара после отмены заказа
Хуки WooCommerce для отслеживания смены статуса заказа
Для решения задачи нам понадобится поймать момент, когда заказ переходит в статус cancelled (отменён). WooCommerce предоставляет удобный хук woocommerce_order_status_cancelled, который вызывается именно при такой смене статуса.
Пошаговое решение с примером кода
Добавьте следующий код в файл functions.php вашей дочерней темы или в собственный плагин:
add_action('woocommerce_order_status_cancelled', 'delete_products_after_order_cancel', 10, 1);
function delete_products_after_order_cancel($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
if ($product_id) {
wp_delete_post($product_id, true); // true - безвозвратное удаление
}
}
}Объяснение: функция получает ID заказа, загружает объект заказа, перебирает все позиции и удаляет связанные товары из базы. Если нужно сначала проверить тип товара (например, удалять только простые товары), добавьте проверку get_post_type($product_id) === 'product'.
Проверка результата после внедрения
- Создайте тестовый заказ с одним или несколькими товарами.
- Переведите статус заказа в «Отменён» через админку WooCommerce.
- Проверьте, что товары удалены из каталога (в разделе Продукты).
- Если товары не удалились, проверьте журнал ошибок и логи сервера.
Частые ошибки и способы их исправления
- Товары не удаляются: возможно, код не подключен, проверьте, что функция вызывается (добавьте временный
error_logв хук). - Удаляются не те товары: убедитесь, что в заказе именно товары, а не другие типы позиций (например, купоны). Используйте
$item->get_product_id(), а не$item->get_variation_id(), если хотите удалить только основной товар. - Удаление безвозвратно: функция
wp_delete_postс параметромtrueудаляет товар окончательно. Если хотите перемещать в корзину удалённых, используйтеfalse. - Проблемы с правами доступа: убедитесь, что код выполняется с правами администратора или в контексте, где разрешено удалять посты.
Практические советы по безопасности и производительности
- Перед удалением товара убедитесь, что он не связан с другими активными заказами, чтобы не нарушить логику продаж.
- Резервное копирование базы перед внедрением автоматического удаления — обязательное условие.
- Если заказы и товары очень большие, обработка может повлиять на производительность — рассмотрите реализацию через WP-Cron с отложенным удалением.
- Для исключения удаления товаров с запасами > 1 добавьте соответствующую проверку
get_post_meta($product_id, '_stock', true).
Альтернативные варианты реализации и их сравнение
| Способ | Плюсы | Минусы |
|---|---|---|
| Удаление товара по хуку «woocommerce_order_status_cancelled» | Простота, моментальное удаление | Риск удаления нужных товаров, влияет на производительность |
| Отметка товара статусом «черновик» или «скрытый» | Безопаснее, можно восстановить | Товар не удалён фактически, может путать пользователей |
| Удаление товаров через WP-Cron (отложенно) | Снижает нагрузку, контролируемый процесс | Задержка удаления, сложнее реализовать |