WooCommerce: как отключить автоматическое обновление остатков товаров по API

Проблема: автоматическое изменение остатков товаров в WooCommerce по API

Автоматическое обновление остатков товаров по API в WooCommerce удобно для синхронизации с внешними системами, например, с ERP или складским учётом. Однако в некоторых случаях это приводит к нежелательным ситуациям: остатки сбрасываются некорректно, данные дублируются, или сторонние сервисы некорректно передают информацию. В результате на сайте отображается неверный запас, что ведёт к ошибкам в заказах и недовольству клиентов.

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

  • Проверьте, какие внешние сервисы подключены для обновления запасов через WooCommerce REST API или сторонние плагины.
  • Отследите логи запросов к API, чтобы понять, когда и с какими данными обновляются остатки.
  • Определите, влияет ли автоматическое обновление непосредственно на записи stock_quantity у товаров WooCommerce.
  • Проверьте, не запускаются ли сторонние крон-задачи или хуки, которые могут обновлять остатки без контроля.

Пошаговое решение: отключение автоматического обновления запасов по API

WooCommerce не имеет встроенной функции «отключить обновление остатков по API», поскольку API — это интерфейс для программного взаимодействия. Чтобы запретить автоматическое изменение запасов через API, необходимо перехватить соответствующие запросы и предотвратить обновление поля stock_quantity. Это можно сделать через фильтры WooCommerce.

1. Запрет на обновление запаса через REST API

Добавьте следующий код в файл functions.php вашей темы или в кастомный плагин:

add_filter('woocommerce_rest_pre_insert_product_object', function($product, $request) {
    if (isset($request['stock_quantity'])) {
        // Удаляем параметр, чтобы не обновлять запас
        unset($request['stock_quantity']);
    }
    return $product;
}, 10, 2);

Этот фильтр предотвращает обновление поля stock_quantity при обработке REST API запроса на обновление товара.

2. Блокировка массового обновления остатков через WP-CLI или другие скрипты

Если обновление происходит не только через REST API, но и через скрипты, можно добавить защиту при сохранении товара, чтобы не менять запас:

add_action('woocommerce_before_product_object_save', function($product) {
    // Получаем старое значение запаса
    $old_stock = $product->get_meta('_old_stock_quantity');
    if ($old_stock !== '') {
        $product->set_stock_quantity($old_stock);
    }
});

add_action('woocommerce_after_product_object_save', function($product) {
    // Сохраняем текущий запас, чтобы потом не менять его
    $product->update_meta_data('_old_stock_quantity', $product->get_stock_quantity());
});

Этот код сохраняет текущий запас в метаполе и восстанавливает его при попытке изменить.

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

  • Отправьте запрос обновления товара через REST API с параметром stock_quantity и убедитесь, что запас не изменился.
  • Попробуйте обновить запас вручную в админке WooCommerce — изменение должно работать, если нужно.
  • Проверьте логи сервера на отсутствие ошибок, связанных с REST API.
  • Если у вас есть сторонние интеграции, протестируйте их работу и убедитесь, что запасы не меняются автоматически.

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

  • Код не работает, запасы всё равно обновляются: проверьте, не перезаписывает ли другие хуки или плагины поле stock_quantity. Используйте приоритет фильтра выше (например, 20) или отладьте последовательность вызовов.
  • Нарушается работа сторонних функций, которые должны обновлять запасы: в этом случае стоит реализовать более тонкую логику с проверкой источника запроса (например, IP, user-agent, авторизация), чтобы не блокировать легитимные обновления.
  • Ошибка синхронизации данных: если данные приходят из нескольких источников, рассмотрите использование очередей обновлений или отдельного сервиса для агрегации запасов.

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

  • Ограничьте доступ к REST API по IP или методам аутентификации, чтобы исключить несанкционированные обновления.
  • Ведите логирование запросов на обновление запасов для быстрого обнаружения проблем.
  • При большом количестве товаров и частых обновлениях используйте кеширование и отложенную обработку (cron) для снижения нагрузки на базу.
  • Тестируйте изменения на staging-среде, чтобы избежать сбоев в рабочем магазине.

Сравнение вариантов решения

МетодОписаниеПлюсыМинусы
Фильтр woocommerce_rest_pre_insert_product_objectБлокирует обновление stock_quantity через REST APIПростая реализация, быстрое решениеНе блокирует обновления из других источников
Хуки сохранения товараВосстанавливает старое значение запаса при сохраненииРаботает для любых обновлений, включая WP-CLIСложнее в поддержке, может конфликтовать с легитимными обновлениями
Ограничение доступа к APIОграничивает кто может делать запросы на обновлениеПовышает безопасностьТребует настройки сервера и аутентификации
⭐⭐⭐⭐⭐