Диагностика задачи: зачем и когда удалять товары после продажи
В WooCommerce иногда возникает необходимость автоматически удалять товары из каталога после их продажи. Это актуально для ограниченных по количеству товаров, цифровых продуктов с ограниченным доступом, либо для товаров, которые нельзя больше продавать после первой покупки (например, эксклюзивные предложения или акции). Цель — убрать товар, чтобы он не отображался в магазине и не был доступен для повторной покупки.
Проверка текущей ситуации
- Проверьте, есть ли у товара ограничение по количеству (stock management). Если товар закончился, WooCommerce может автоматически скрыть его.
- Убедитесь, что товар действительно нужно удалить, а не просто скрыть. Удаление — необратимая операция, влияет на данные о заказах.
- Выясните, нужно ли удалять товар сразу после оплаты заказа или после смены статуса.
Пошаговое решение: автоматическое удаление товара по событию продажи
Для реализации задачи используем хук woocommerce_order_status_completed, который срабатывает при смене статуса заказа на «завершён». В обработчике получаем товары из заказа и удаляем их программно.
add_action('woocommerce_order_status_completed', 'auto_delete_products_after_purchase', 10, 1);function auto_delete_products_after_purchase($order_id) { if (!$order_id) { return; } $order = wc_get_order($order_id); foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); if ($product_id) { // Удаляем товар без возможности восстановления wp_delete_post($product_id, true); } }}Этот код удалит все товары из заказа сразу после его оплаты и завершения. Если нужно ограничить удаление по определённым категориям или меткам, добавьте проверку:
add_action('woocommerce_order_status_completed', 'auto_delete_selected_products_after_purchase', 10, 1);function auto_delete_selected_products_after_purchase($order_id) { if (!$order_id) { return; } $order = wc_get_order($order_id); foreach ($order->get_items() as $item) { $product_id = $item->get_product_id(); if (!$product_id) { continue; } $terms = wp_get_post_terms($product_id, 'product_cat', array('fields' => 'slugs')); if (in_array('exclusive', $terms)) { // категория exclusive wp_delete_post($product_id, true); } }}Проверка результата после внедрения
- Создайте тестовый заказ с товаром, который должен удаляться.
- Измените статус заказа на «Завершён» вручную или дождитесь автоматического изменения.
- Проверьте, что товар исчез из списка товаров на сайте и в админке.
- Убедитесь, что товар больше не доступен для добавления в корзину.
Частые ошибки и как их исправить
- Товар не удаляется после смены статуса: проверьте, что хук
woocommerce_order_status_completedсрабатывает и код подключен в functions.php или плагине. - Удаляются не те товары: убедитесь, что фильтрация по категориям или другим параметрам работает правильно через
wp_get_post_terms. - Потеря данных заказа: удаление товара необратимо, убедитесь, что данные заказа не зависят от товара, иначе используйте скрытие (
post_status = 'private') вместо удаления. - Ошибки прав доступа: функция
wp_delete_postтребует прав администратора, код должен выполняться с соответствующими возможностями.
Практические советы по безопасности и производительности
- Резервное копирование базы данных перед внедрением автоматического удаления.
- Используйте транзакции в базе (если доступны), чтобы избежать потери данных при ошибках.
- Для больших магазинов с большим количеством заказов ограничьте выполнение кода, чтобы не создавать нагрузку.
- Если нужен обратимый вариант, вместо удаления меняйте статус товара на
draftилиprivate.
Сравнение подходов к удалению товаров после продажи
| Метод | Описание | Преимущества | Недостатки |
|---|---|---|---|
| Удаление (wp_delete_post) | Полное удаление товара из базы | Товар полностью исчезает, освобождает место | Невозможно вернуть, потеря данных о товаре |
| Смена статуса на private/draft | Скрытие товара без удаления | Обратимо, сохраняет данные | Товар всё еще в базе, не освобождает место |
| Отключение публикации через метаполе | Контроль отображения через условие в шаблоне | Гибкий контроль, можно показывать только определённым пользователям | Не удаляет товар из базы, требует дополнительного кода в теме |