Что такое хук woocommerce_order_status_changed и когда он срабатывает
Хук woocommerce_order_status_changed — это динамический action в WooCommerce, который срабатывает каждый раз при смене статуса заказа. Его удобно использовать для выполнения кастомных операций по изменению состояния заказа: отправка уведомлений, обновление данных, интеграция с внешними сервисами.
Сигнатура хука выглядит так:
do_action( 'woocommerce_order_status_changed', $order_id, $old_status, $new_status, $order );где:
$order_id— ID заказа;$old_status— предыдущий статус (например, 'pending');$new_status— новый статус (например, 'completed');$order— объект WC_Order.
Диагностика: как понять, что хук не работает или срабатывает неправильно
Если ваши кастомные действия не выполняются при смене статуса заказа, проверьте следующие моменты:
- Правильно ли зарегистрирован callback с нужным количеством аргументов.
- Используете ли вы корректные имена статусов (без «wc-» префикса).
- Функция не вызывает ошибок PHP (отключите режим подавления ошибок).
- Наличие конфликтов с другими плагинами, которые могут отменять смену статуса или блокировать хук.
- Заказ действительно меняет статус через стандартные методы WooCommerce (например, ручное изменение в админке или программно через
$order->update_status()).
Пошаговое решение: как подключить кастомное действие к смене статуса заказа
1. Подключаем функцию к хук
Добавим следующий код в файл functions.php вашей темы или в кастомный плагин:
add_action('woocommerce_order_status_changed', 'custom_order_status_changed_action', 10, 4);
function custom_order_status_changed_action($order_id, $old_status, $new_status, $order) {
// Например, логируем смену статуса в файл
$log_message = sprintf(
"Заказ #%d изменил статус с %s на %s\n",
$order_id,
$old_status,
$new_status
);
error_log($log_message);
// Добавим кастомную логику под конкретный статус
if ($new_status === 'completed') {
// Ваш код для заказов, ставших "завершёнными"
}
}2. Проверка правильных названий статусов
Убедитесь, что используете именно статус без префикса wc-. Для проверки доступных статусов можно вывести их так:
add_action('init', function() {
$statuses = wc_get_order_statuses();
error_log(print_r($statuses, true));
});3. Пример: отправка письма менеджеру при смене статуса на "processing"
add_action('woocommerce_order_status_changed', 'notify_manager_on_processing', 10, 4);
function notify_manager_on_processing($order_id, $old_status, $new_status, $order) {
if ($new_status === 'processing') {
$to = 'manager@example.com';
$subject = "Заказ #{$order_id} в обработке";
$message = "Заказ #{$order_id} изменил статус на обработку. Сумма: " . $order->get_total();
wp_mail($to, $subject, $message);
}
}Как проверить, что кастомный код сработал
- Для логирования ошибок и отладочной информации используйте
error_log()и смотрите логи сервера (например,error.logApache/Nginx). - Добавьте тестовые сообщения в код, чтобы убедиться в срабатывании callback.
- Проверьте функционал в админке: измените статус заказа и посмотрите, выполняется ли действие (например, письмо приходит, лог создаётся).
- Используйте плагины Debug Bar или Query Monitor для мониторинга хуков и ошибок.
Частые ошибки при работе с хуком woocommerce_order_status_changed
- Неправильное количество аргументов в callback: хук передаёт 4 аргумента, если указать меньше, часть данных не будет доступна.
- Использование неправильных имён статусов: статусы надо писать без префикса
wc-, например,completed, а неwc-completed. - Вызов функции вне контекста WooCommerce: убедитесь, что WooCommerce активен и хук подключается после её инициализации.
- Конфликты с другими плагинами: некоторые плагины могут отменять смену статусов или обрабатывать их иначе.
- Функция wp_mail не настроена или отключена: проверьте почтовую отправку, если используете письма.
Практические советы по безопасности и производительности
- Минимизируйте время выполнения кода в хуке, чтобы не замедлять обновление статуса.
- При необходимости интеграции с внешними API используйте очереди WP-Cron для асинхронных задач.
- Проверяйте права пользователя, если выполнение кода зависит от ролей или доступа.
- Для логирования используйте отдельный файл или сервис, чтобы не перегружать основной error_log.
- Избегайте глобальных переменных и используйте объект
$orderдля получения данных.
Краткое сравнение вариантов реализации кастомных действий при смене статуса заказа
| Метод | Плюсы | Минусы | Примеры использования |
|---|---|---|---|
Хук woocommerce_order_status_changed |
Прямой, полный доступ к заказу, универсален | Требует навыков PHP, может замедлить обработку | Отправка уведомлений, интеграция с CRM, логирование |
| Плагины с триггерами по статусу | Простота настройки, без кода | Ограниченная кастомизация, возможны конфликты | Автоматические письма, статусы доставки |
| WP-Cron для отложенных задач | Асинхронность, не блокирует смену статуса | Зависит от посещаемости сайта | Сложные интеграции, отчёты, рассылки |