Диагностика проблемы: почему не срабатывает хук изменения статуса заказа в WooCommerce
В WooCommerce для автоматизации действий при изменении статуса заказа используется хук woocommerce_order_status_changed. Часто разработчики сталкиваются с тем, что их функции на этот хук не вызываются или вызываются некорректно. Основные причины:
- Неправильное подключение обработчика (например, ошибка в имени функции или приоритете);
- Конфликты с другими плагинами или темами, которые перезаписывают логику статусов;
- Изменение статуса происходит не через стандартные методы WooCommerce, а напрямую через базу данных или сторонние плагины;
- Отсутствие проверки ролей и условий внутри функции-обработчика, из-за чего она просто не выполняет нужных действий;
- Кэширование (например, объектный кэш или кеш плагина), из-за которого изменения не отражаются своевременно.
Пошаговое решение: правильная настройка и проверка хуков изменения статуса заказа
1. Правильное добавление обработчика
Добавьте следующий код в файл functions.php вашей темы или в собственный плагин:
add_action('woocommerce_order_status_changed', 'custom_order_status_changed', 10, 4);function custom_order_status_changed($order_id, $old_status, $new_status, $order) { // Логируем для отладки error_log("Order #" . $order_id . " changed status from " . $old_status . " to " . $new_status); // Пример действия: отправить письмо или изменить метаданные if ($new_status === 'completed') { // Например, добавить мета $order->update_meta_data('_custom_status_handled', 'yes'); $order->save(); }}Обратите внимание на 4 параметра функции, которые позволяют получить ID заказа, старый и новый статус, а также объект заказа.
2. Проверка, что хук срабатывает
Чтобы убедиться, что функция вызывается, посмотрите логи PHP (обычно error_log) после изменения статуса заказа.
Вы можете сменить статус заказа вручную в админке WooCommerce и проверить, появляется ли запись в логе.
3. Проверка конфликтов и кэша
- Отключите все сторонние плагины кроме WooCommerce и вашего кастомного кода;
- Переключитесь на стандартную тему (например, Storefront) и повторите тест;
- Очистите кэш сервера и объектный кэш, если используете;
- Убедитесь, что изменение статуса происходит через админку или стандартные методы WooCommerce.
Проверка результата после внедрения
- Измените статус заказа в админке WooCommerce;
- Проверьте логи PHP на наличие записи из
error_logв функции-обработчике; - Проверьте, что добавленные метаданные или другие действия выполнены (через админку или код, например
$order->get_meta('_custom_status_handled')); - Проверьте, что никакие ошибки PHP не выводятся.
Частые ошибки и как их исправить
- Неверное имя функции или параметры хука. Убедитесь, что в
add_actionуказан правильный хук и количество аргументов (4). - Изменение статуса напрямую в базе. Хук не сработает, если обновлять статус не через методы WooCommerce (
$order->update_status()). - Использование неправильного приоритета. Стандартный 10 подходит, но если другие плагины блокируют, попробуйте 20 или 1.
- Отсутствие вызова
$order->save(). После обновления метаданных нужно сохранить объект. - Проблемы с кэшированием. Очистите кэш сайта и браузера, отключите плагин кеширования для теста.
Практические советы по безопасности и производительности при работе с хуками WooCommerce
- Не выполняйте тяжелые операции внутри обработчика хука — используйте очередь задач (WP-Cron или внешние сервисы), если нужно отправлять письма или делать API-запросы.
- Проверяйте права пользователя, если функция зависит от ролей или условий.
- Используйте
error_logили специальные плагины для отладки, например Query Monitor. - Для массовых изменений статусов используйте WP-CLI, чтобы избегать излишних вызовов хуков.
Альтернативные методы отслеживания изменения статусов заказов
Если хук woocommerce_order_status_changed по каким-то причинам не подходит, рассмотрите следующие варианты:
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
woocommerce_order_status_{$new_status} | Хук, срабатывающий при конкретном новом статусе, например woocommerce_order_status_completed | Удобно для обработки конкретного статуса | Нужно писать отдельный обработчик под каждый статус |
| Использование WP Cron для регулярной проверки статусов | Запуск задачи, которая сканирует заказы и выявляет изменения | Полный контроль, можно обрабатывать сразу много заказов | Задержка между изменением и обработкой, нагрузка на сервер |
| Отслеживание в базе с помощью триггеров MySQL | Создание триггеров на таблицу заказов для логирования изменений | Мгновенная реакция на изменение | Сложно в сопровождении, требует доступа к базе, не рекомендуется |
Чек-лист для отладки хуков изменения статуса заказа
- Проверьте правильность подключения обработчика (
add_action, количество аргументов). - Убедитесь, что статус меняется через официальные методы WooCommerce.
- Проверьте логи на наличие вызовов функции (
error_logили Query Monitor). - Отключите сторонние плагины и смените тему для исключения конфликтов.
- Очистите кэш и убедитесь, что нет кэширования объекта заказа.
- Проверьте, что используете
$order->save()после обновления метаданных. - Проверьте права пользователя и условия внутри функции.