Диагностика задачи: зачем удалять товар после покупки
В WooCommerce иногда возникает необходимость автоматически удалять товар из каталога сразу после его успешной покупки. Это может быть полезно для продажи уникальных товаров, ограниченных тиражей, или для управления складом без использования дополнительных плагинов. В стандартном WooCommerce нет встроенного функционала для этого, поэтому реализовать задачу нужно через кастомный код.
Как автоматически удалять товар после успешного заказа в WooCommerce
Основные хуки для решения задачи
Нам потребуется отследить успешное завершение оплаты заказа, после чего получить список купленных товаров и удалить их из базы. Для этого подходит хук woocommerce_order_status_completed, который срабатывает, когда заказ перешёл в статус «завершён».
Пошаговое решение с примером кода
Добавьте следующий код в файл functions.php активной темы или в кастомный плагин:
add_action('woocommerce_order_status_completed', 'wpid_delete_products_after_purchase', 10, 1);
function wpid_delete_products_after_purchase($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();
// Защита от удаления товаров с ID 0 или несуществующих
if (!$product_id) continue;
// Удаляем товар программно
wp_delete_post($product_id, true); // true - без перемещения в корзину
}
}Объяснение кода:
- Функция получает объект заказа по ID.
- Перебирает все позиции заказа.
- Для каждого товара вызывает
wp_delete_post()с параметромtrue— чтобы удалить товар навсегда без попадания в корзину.
Проверка результата после внедрения
- Создайте тестовый заказ с одним или несколькими товарами.
- Переведите статус заказа в «Завершён» вручную в админке WooCommerce.
- Проверьте, что соответствующие товары исчезли из каталога и из базы данных (wp_posts с post_type = 'product').
- Для проверки можно использовать запрос в базе:
SELECT ID, post_title FROM wp_posts WHERE post_type = 'product' AND ID = <product_id>;— он должен не возвращать результата для удалённых товаров.
Частые ошибки и их исправление
- Товар не удаляется: проверьте, что хук
woocommerce_order_status_completedсрабатывает. Для отладки добавьте в функциюerror_log('Order completed: '.$order_id);. Убедитесь, что статус заказа действительно меняется. - Удаляются не те товары: убедитесь, что получаете ID товара через
$item->get_product_id(), а не вариации или другие объекты. - Удалённые товары появляются в корзине: при удалении используется второй параметр
trueвwp_delete_post(), чтобы удалять без перемещения в корзину. - Ошибка прав доступа: убедитесь, что код запускается от имени пользователя с достаточными правами (обычно при изменении статуса заказа это так).
Практические советы по безопасности и производительности
- Перед удалением товара проверьте, не используется ли он в других заказах или связях, чтобы не нарушить целостность данных.
- Если товары имеют вариации, код нужно доработать, чтобы удалять их тоже, иначе останутся «мертвые» записи.
- Для крупных магазинов с большим количеством заказов рекомендуется не вызывать удаление сразу при изменении статуса, а ставить задачи в очередь (через WP-Cron), чтобы не создавать нагрузку.
- Резервное копирование базы перед внедрением — обязательное условие.
Дополнительный вариант: отключение удаления и замена на скрытие
Если удаление слишком радикально, можно вместо удаления просто скрывать товар с помощью изменения статуса на draft. Для этого замените в коде строку удаления на:
wp_update_post(['ID' => $product_id, 'post_status' => 'draft']);Так товар исчезнет с витрины, но останется в базе для отчётности.
Сравнение вариантов решения
| Метод | Плюсы | Минусы |
|---|---|---|
| Удаление товара (wp_delete_post) | Полное удаление, освобождение места, отсутствие товара в каталоге | Риск потери данных, невозможность восстановления без бэкапа |
| Смена статуса на draft | Безопасно, товар можно восстановить, сохраняются данные | Товар остаётся в базе, не освобождает место |