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

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

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

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

1. Добавление кода в functions.php или в кастомный плагин

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

add_action('woocommerce_thankyou', 'wc_delete_product_after_first_order', 10, 1);
function wc_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'],
            'exclude' => [$order_id], // Исключаем текущий заказ
            'meta_query' => [
                [
                    'key' => '_product_id',
                    'value' => $product_id,
                    'compare' => '=',
                ],
            ],
        ];

        $orders = wc_get_orders($args);

        // Если других заказов с этим товаром нет, удаляем товар
        if (empty($orders)) {
            wp_delete_post($product_id, true); // true - удаление без возможности восстановления
        }
    }
}

Важно: В данном примере используется wc_get_orders с meta_query, однако для поиска товаров в заказах придется проверить товары в каждом заказе вручную, так как мета _product_id не хранится в заказах по умолчанию. Поэтому правильнее сделать перебор заказов и их товаров для проверки.

2. Альтернативный, точный вариант проверки прошлых заказов с товаром

function has_product_been_ordered_before($product_id, $exclude_order_id) {
    $args = [
        'limit' => -1,
        'status' => ['completed', 'processing'],
    ];
    $orders = wc_get_orders($args);
    foreach ($orders as $order) {
        if ($order->get_id() == $exclude_order_id) continue;
        foreach ($order->get_items() as $item) {
            if ($item->get_product_id() == $product_id) {
                return true;
            }
        }
    }
    return false;
}

add_action('woocommerce_thankyou', 'wc_delete_product_after_first_order_precise', 10, 1);
function wc_delete_product_after_first_order_precise($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 (!has_product_been_ordered_before($product_id, $order_id)) {
            wp_delete_post($product_id, true);
        }
    }
}

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

  • Оформите тестовый заказ с уникальным товаром, который еще не покупался.
  • После успешного оформления проверьте в админке WooCommerce, что товар удален из каталога.
  • Попробуйте оформить повторный заказ с тем же товаром (если возможно) — он должен быть недоступен.
  • Проверьте логи ошибок PHP и WooCommerce на предмет исключений.

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

  • Товар не удаляется: проверьте, что ID товара корректно получен и что функция wp_delete_post() вызывается.
  • Проверка прошлых заказов занимает слишком много времени: уменьшите количество проверяемых заказов, добавьте кэширование или используйте SQL-запросы напрямую для оптимизации.
  • Удаляется не тот товар: убедитесь, что используете $item->get_product_id(), а не $item->get_variation_id(), если нужно удалить родительский товар.
  • Ошибки доступа (недостаточно прав): убедитесь, что скрипт выполняется с правами администратора, или используйте функции WordPress с правильными правами.

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

  • Удаление товара — операция необратимая, используйте wp_delete_post($product_id, false) для перемещения в корзину, чтобы иметь возможность восстановления.
  • Если товаров много, подумайте об оптимизации поиска заказов с помощью прямых SQL-запросов через $wpdb.
  • Добавьте логирование удалений для аудита:
    error_log('Product '.$product_id.' deleted after first order '.$order_id);
  • Проверьте совместимость вашего решения с кеширующими плагинами и CDN, так как удаление товара может не сразу отражаться на фронтенде.

Сравнение вариантов реализации

МетодПлюсыМинусы
Простой вызов wp_delete_post в woocommerce_thankyouПростая реализация, быстрое внедрениеПлохо масштабируется, может удалить товары ошибочно при высокой нагрузке
Проверка истории заказов через перебор wc_get_ordersТочная проверка, надежностьВысокая нагрузка при большом количестве заказов, требует оптимизации
Использование прямых SQL-запросов для поиска заказов с товаромМаксимальная производительность, масштабируемостьСложность реализации, риск ошибок при изменениях структуры БД
WooCommerce: как отключить автоматическую отправку email уведомлений после оформления заказа
02.07.2026
Как работает автоматическое сохранение в WordPress на примере WP7
07.04.2026
Как использовать хуки для оптимизации WordPress: практические примеры и советы
08.12.2025
Как сделать автоматическое сохранение форм в WordPress с помощью JavaScript
14.01.2026
Как отключить email-уведомления в WordPress без плагинов
06.03.2026