Как использовать хук woocommerce_order_status_changed для автоматического обновления метаданных заказа

Что такое хук woocommerce_order_status_changed и зачем он нужен

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

Использование этого хука позволяет реагировать на смену статуса, например, при переходе заказа из "в обработке" в "завершён" или при возврате средств.

Диагностика: как понять, что метаданные не обновляются автоматически

  • Вы изменили статус заказа, но связанные с ним метаданные остаются прежними.
  • Автоматические процессы (например, расчёт бонусов, обновление пользовательских данных) не запускаются.
  • Нет ошибок PHP, но нет и ожидаемого результата.

Для диагностики можно добавить временный лог в обработчик хука, чтобы проверить, вызывается ли он:

add_action( 'woocommerce_order_status_changed', 'debug_order_status_change', 10, 4 );
function debug_order_status_change( $order_id, $old_status, $new_status, $order ) {
    error_log("Order #$order_id status changed from $old_status to $new_status");
}

Если в логах нет сообщений — хук не срабатывает, значит, проблема в регистрации обработчика или конфликте с другими плагинами.

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

Рассмотрим пример, где при переходе заказа в статус completed записывается текущее время в мета поле _completed_timestamp.

add_action( 'woocommerce_order_status_changed', 'update_completed_timestamp_meta', 10, 4 );
function update_completed_timestamp_meta( $order_id, $old_status, $new_status, $order ) {
    if ( 'completed' === $new_status ) {
        update_post_meta( $order_id, '_completed_timestamp', current_time( 'mysql' ) );
    }
}

Объяснение кода:

  • Функция получает ID заказа и новые/старые статусы.
  • Проверяем, что новый статус - completed.
  • Обновляем мета поле заказов с текущим временем в формате MySQL.

Расширенный пример: добавление кастомного флага и уведомления администратору

add_action( 'woocommerce_order_status_changed', 'custom_order_status_actions', 10, 4 );
function custom_order_status_actions( $order_id, $old_status, $new_status, $order ) {
    if ( 'processing' === $new_status ) {
        update_post_meta( $order_id, '_custom_flag', 'yes' );
        wp_mail(
            get_option( 'admin_email' ),
            "Order #$order_id changed status to processing",
            "Заказ №$order_id перешёл в статус обработка."
        );
    }
}

Как проверить, что решение сработало

  1. Перейдите в админку WooCommerce → Заказы.
  2. Измените статус выбранного заказа на completed или processing в зависимости от примера.
  3. Проверьте значения метаданных заказа через базу данных или с помощью плагина типа Adminer или WP phpMyAdmin.
  4. Для примера с уведомлением — проверьте почту администратора.
  5. Также можно вывести значение мета поля в шаблоне заказа, чтобы визуально убедиться в обновлении:
$completed_time = get_post_meta( $order->get_id(), '_completed_timestamp', true );
echo 'Время завершения: ' . esc_html( $completed_time );

Частые ошибки при использовании woocommerce_order_status_changed

  • Неправильное имя хука или параметров. Хук должен использоваться именно как woocommerce_order_status_changed с четырьмя аргументами.
  • Отсутствие приоритета и количества аргументов. При регистрации обработчика нужно указать 4 параметра: add_action('woocommerce_order_status_changed', 'func', 10, 4).
  • Ошибки в логике проверки статусов. Например, сравнение с несуществующим статусом, или использование строгого сравнения без учёта регистра.
  • Проблемы с правами доступа. Если обработчик изменяет данные, убедитесь, что он выполняется с достаточными правами (обычно это не проблема в хуках WooCommerce).
  • Перезапись метаданных без условий. Это может привести к потере важных данных, нужно всегда проверять условия обновления.

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

  • Минимизируйте работу в обработчике. Не вызывайте тяжелые операции, например, внешние API, напрямую в хуке, лучше запускать их через WP-Cron или очереди.
  • Проверяйте данные перед обновлением. Чтобы избежать лишних запросов, сравнивайте новое значение с существующим, обновляйте метаданные только при необходимости.
  • Используйте current_time() вместо date(). Это учитывает часовой пояс WordPress.
  • Обрабатывайте ошибки. Например, проверяйте результат update_post_meta() и логируйте ошибки при необходимости.
  • Безопасность почтовых уведомлений. Если отправляете почту, используйте валидные и защищённые методы, избегайте инъекций.

Сравнение вариантов реализации обновления метаданных

МетодПлюсыМинусыКомпромисс
Обновление в хуке woocommerce_order_status_changedМгновенное реагирование, простота реализацииВозможна нагрузка при частых изменениях, риск блокировки UIДобавлять минимальный код, тяжелые задачи запускать отдельно
Использование WP-Cron для отложенной обработкиСнижает нагрузку, асинхронностьЗадержка в выполнении, зависимость от cronКомбинировать с хуком для постановки задач в очередь
Внешние сервисы через вебхукиМасштабируемость, интеграцияСложность настройки, задержкиИспользовать для сложных интеграций, критичные метаданные обновлять локально
Как отключить AJAX в WooCommerce для оптимизации производительности
19.06.2026
Автоматическое удаление старых неиспользуемых изображений из медиабиблиотеки WordPress
06.02.2026
Как изменить URL авторских связей в WordPress без плагинов
11.12.2025
Как создать собственный вид регистрации в WordPress с помощью плагинов
10.11.2025
Автоматическое удаление товаров из заказов WooCommerce после отмены или возврата
09.06.2026