Проблема: необходимость удаления товара после первого заказа
В WooCommerce иногда возникает задача автоматически удалить товар из каталога сразу после того, как он был куплен впервые. Это актуально для ограниченных коллекций, эксклюзивных предложений или акций с единичным тиражом. Стандартных средств для этого нет, поэтому нужно реализовать кастомное решение.
Диагностика проблемы
Перед реализацией важно проверить, что товар:
- Доступен для покупки и отображается на сайте.
- Правильно фиксируется в заказах WooCommerce.
- Имеет уникальный ID, по которому можно отследить покупки.
Для диагностики можно вручную проверить несколько заказов в админке WooCommerce, убедиться, что товар действительно был куплен, и что его ID совпадает с тем, что вы хотите удалить.
Пошаговое решение
1. Использование хука WooCommerce для отслеживания завершённых заказов
Лучше всего использовать хук woocommerce_order_status_completed, который срабатывает при смене статуса заказа на «завершён».
2. Получение товаров из заказа и проверка первого заказа по товару
Нужно проверить, был ли это первый заказ, содержащий данный товар. Если да — удалить товар.
add_action('woocommerce_order_status_completed', 'wpbook_delete_product_after_first_order', 10, 1);function wpbook_delete_product_after_first_order($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(); // Проверяем, был ли этот товар куплен ранее $args = [ 'limit' => 1, 'status' => ['completed', 'processing'], 'product' => $product_id, 'exclude' => [$order_id], ]; $orders = wc_get_orders($args); if (empty($orders)) { // Это первый заказ с этим товаром, удаляем товар wp_delete_post($product_id, true); // true — принудительное удаление error_log('Товар ID ' . $product_id . ' удалён после первого заказа #' . $order_id); } }}3. Добавление кода в functions.php или в кастомный плагин
Рекомендуется использовать отдельный плагин для подобного кода, чтобы не потерять изменения при обновлении темы.
Проверка результата после внедрения
- Создайте тестовый товар и опубликуйте его.
- Оформите тестовый заказ с этим товаром и завершите его (статус «завершён»).
- Проверьте, что товар исчез из каталога и больше не доступен для покупки.
- Проверьте логи ошибок (error_log) на предмет записей удаления.
Частые ошибки и как исправить
1. Товар не удаляется после первого заказа
- Проверьте, что хук
woocommerce_order_status_completedсрабатывает. - Убедитесь, что в заказе есть корректные товары (не вариации, если работаете с простыми товарами).
- Проверьте правильность использования аргументов в
wc_get_orders. Параметрproductтребует WooCommerce 3.7+.
2. Удаляются товары, купленные не впервые
- Возможно, не учитывается исключение текущего заказа в запросе
wc_get_orders. Проверьте параметрexclude. - Проверьте, нет ли кеширования заказов, которое мешает правильной проверке.
3. Ошибки при удалении товаров с вариациями
- Для вариационных товаров удаляйте родительский товар (
post_parentвариации равен ID родителя). - Иначе товар останется в базе и будет отображаться.
Практические советы по безопасности и производительности
- Используйте транзакции или логи для отладки, чтобы не потерять данные при ошибках.
- Не храните в коде ID конкретных товаров — сделайте функцию универсальной.
- Проверяйте права пользователя перед удалением, если код будет запускаться в админке.
- Для сайтов с большим количеством заказов используйте кеширование и оптимизируйте запросы.
Сравнение способов реализации
| Метод | Плюсы | Минусы | Использование |
|---|---|---|---|
Хук woocommerce_order_status_completed с проверкой заказов | Точное удаление, работает сразу после заказа | Зависит от корректности статусов и WooCommerce версии | Подходит для большинства случаев |
| Отложенное удаление с WP-Cron | Позволяет сгладить нагрузку, можно отложить удаление | Сложнее в реализации, возможны задержки | Для больших магазинов с высокой нагрузкой |
| Ручное удаление через админку с метками | Простота, контроль вручную | Нет автоматизации, риск забыть | Малые магазины, ограниченный ассортимент |