WooCommerce: как автоматически удалять товары после первого заказа

Проблема: необходимость удаления товаров после первого заказа

В WooCommerce иногда возникает задача автоматически удалять товары из каталога, если кто-то совершил их покупку впервые. Это может быть актуально для ограниченных тиражей, эксклюзивных предложений или акций с единичным доступом к товару.

Диагностика проблемы

По умолчанию WooCommerce не предоставляет возможность автоматически удалять или скрывать товар после первого заказа. Для реализации такой логики нужно вмешаться в процесс обработки заказов и проверить, был ли товар уже куплен.

Основные вопросы для диагностики:

  • Как отследить первый заказ товара?
  • В какой момент удалять или скрывать товар?
  • Как корректно обновить данные, чтобы не сломать логику магазина?

Пошаговое решение: реализация автоматического удаления товаров

1. Отслеживание первого заказа товара

Для этого используем хук woocommerce_order_status_completed, который срабатывает при смене статуса заказа на «завершён». В обработчике проверяем, есть ли в базе другие заказы с этим товаром.

2. Логика удаления товара

Если товар был куплен впервые, удаляем его программно через функцию wp_delete_post(). Для избежания потери данных можно рассмотреть вариант изменения статуса товара на «черновик» или «вне каталога».

3. Пример кода

add_action('woocommerce_order_status_completed', 'auto_remove_products_after_first_order', 10, 1);
function auto_remove_products_after_first_order($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();

        // Ищем другие завершённые заказы с этим товаром, кроме текущего
        $args = array(
            'limit' => 1,
            'status' => 'completed',
            'return' => 'ids',
            'exclude' => array($order_id),
            'meta_query' => array(
                array(
                    'key' => '_product_id',
                    'value' => $product_id,
                    'compare' => '=',
                ),
            ),
        );

        // Получаем заказы с этим товаром
        $orders_with_product = wc_get_orders($args);

        // Если других заказов с этим товаром нет — удаляем
        if (empty($orders_with_product)) {
            // Вместо удаления можно переводить в черновик: wp_update_post(array('ID' => $product_id, 'post_status' => 'draft'));
            wp_delete_post($product_id, true);
        }
    }
}

Важно: В meta_query выше условие упрощено, поскольку в заказах товар хранится не как мета, а в item meta. Для корректного поиска понадобится более сложный SQL-запрос. Ниже - более точный метод.

Уточнённый метод проверки покупки товара

function has_other_completed_orders_with_product($product_id, $exclude_order_id) {
    global $wpdb;
    $query = $wpdb->prepare(
        "SELECT order_items.order_id
        FROM {$wpdb->prefix}woocommerce_order_items AS order_items
        JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS itemmeta
        ON order_items.order_item_id = itemmeta.order_item_id
        JOIN {$wpdb->posts} AS posts
        ON order_items.order_id = posts.ID
        WHERE posts.post_status = 'wc-completed'
        AND order_items.order_item_type = 'line_item'
        AND itemmeta.meta_key = '_product_id'
        AND itemmeta.meta_value = %d
        AND order_items.order_id != %d
        LIMIT 1",
        $product_id,
        $exclude_order_id
    );

    $result = $wpdb->get_var($query);
    return !empty($result);
}

add_action('woocommerce_order_status_completed', 'auto_remove_products_after_first_order_refined', 10, 1);
function auto_remove_products_after_first_order_refined($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();

        if (!has_other_completed_orders_with_product($product_id, $order_id)) {
            wp_delete_post($product_id, true); // или wp_update_post(array('ID' => $product_id, 'post_status' => 'draft'));
        }
    }
}

Проверка результата после внедрения

  1. Создайте тестовый товар в WooCommerce.
  2. Сделайте заказ с этим товаром и переведите его в статус «Завершён».
  3. Проверьте, удалён ли товар из каталога (через админку или URL товара).
  4. Попробуйте сделать повторный заказ того же товара — он должен быть недоступен.

Если товар удаляется или становится недоступен после первого завершённого заказа — решение работает.

Частые ошибки и как их исправить

  • Не удаляется товар после заказа: Проверьте, что хук woocommerce_order_status_completed срабатывает, а функция wp_delete_post() вызывается с правильным ID.
  • Удаляются все товары сразу: Ошибка в логике проверки предыдущих заказов. Используйте SQL-запрос с join по order_items и order_itemmeta, как в примере выше.
  • Проблемы с кешированием: После удаления товара очистите кеш сайта и браузера, чтобы увидеть изменения.
  • Нарушается целостность данных: Вместо удаления используйте изменение статуса на draft или private.

Практические советы по безопасности и производительности

  • Безопасность: Убедитесь, что код выполняется только в нужных условиях — используйте проверки прав пользователя и nonce, если добавляете UI для управления.
  • Производительность: SQL-запросы к заказам могут быть тяжёлыми при большом объёме данных. Кешируйте результаты или используйте транзиенты, если возможно.
  • Резервное копирование: Перед автоматическим удалением товаров сделайте резервную копию базы данных на случай ошибок.

Сравнение вариантов удаления товара после первого заказа

МетодПлюсыМинусыРекомендации
Удаление товара (wp_delete_post())Полное удаление, освобождение местаПотеря данных, нельзя восстановить без бэкапаИспользовать с осторожностью, лучше на небольших магазинах
Смена статуса на «черновик»Товар скрыт, данные сохраненыТовар остаётся в базе, занимает местоРекомендуется для безопасности и простоты восстановления
Использование кастомного поля для скрытияГибкость в управлении отображениемТребует дополнительной логики в шаблонахПодходит для сложных сценариев
Как отключить Gutenberg и использовать классический редактор в WordPress
23.03.2026
WooCommerce: удаление пользовательских ролей и изменение прав доступа
10.05.2026
Как создать динамическое меню в WordPress с применением WP7
05.01.2026
Как использовать WP7 AJAX для реального времени обновления данных в WordPress
27.01.2026
Как удалить метаданные из изображений в WordPress
06.02.2026