Что такое хук woocommerce_order_status_changed и когда он срабатывает
Хук woocommerce_order_status_changed вызывается каждый раз, когда статус заказа в WooCommerce меняется. Он принимает четыре параметра:
$order_id— ID заказа;$old_status— предыдущий статус заказа;$new_status— новый статус заказа;$order— объект WC_Order.
Этот хук подходит для запуска любых действий, связанных с изменением статуса, например, отправка уведомлений, обновление данных в CRM, смена меток и т.д.
Диагностика задачи: зачем и как применять этот хук
Частая задача — отправить кастомное уведомление клиенту или администратору, когда заказ переходит в определённый статус, например, "выполнен" или "отменён". Без правильного использования хука можно столкнуться с:
- многократным срабатыванием;
- отправкой уведомлений не в тот момент;
- отсутствием доступа к данным заказа.
Для диагностики стоит проверить, вызывается ли хук именно в нужный момент и с правильными параметрами.
Пошаговое решение: добавление кастомного кода на хук
Пример добавления функции, которая отправляет письмо клиенту при изменении статуса заказа на "completed":
add_action('woocommerce_order_status_changed', 'wpstandart_notify_customer_on_completed', 10, 4);
function wpstandart_notify_customer_on_completed($order_id, $old_status, $new_status, $order) {
if ($new_status === 'completed' && $old_status !== 'completed') {
$to = $order->get_billing_email();
$subject = 'Ваш заказ #' . $order_id . ' выполнен';
$message = 'Спасибо за покупку! Ваш заказ был успешно обработан и выполнен.';
wp_mail($to, $subject, $message);
}
}Обратите внимание на условие, которое предотвращает повторную отправку письма, если статус уже был "completed".
Как расширить функционал: интеграция с API или CRM
Допустим, нужно отправить данные заказа в CRM при смене статуса на "processing":
add_action('woocommerce_order_status_changed', 'wpstandart_send_order_to_crm', 10, 4);
function wpstandart_send_order_to_crm($order_id, $old_status, $new_status, $order) {
if ($new_status === 'processing') {
$data = [
'order_id' => $order_id,
'customer_email' => $order->get_billing_email(),
'total' => $order->get_total(),
'items' => []
];
foreach ($order->get_items() as $item) {
$data['items'][] = [
'product_id' => $item->get_product_id(),
'quantity' => $item->get_quantity()
];
}
$response = wp_remote_post('https://crm.example.com/api/orders', [
'body' => json_encode($data),
'headers' => [
'Content-Type' => 'application/json'
]
]);
if (is_wp_error($response)) {
error_log('Ошибка отправки в CRM: ' . $response->get_error_message());
}
}
}Как проверить, что решение работает
- Измените статус заказа в админке WooCommerce на нужный (например, "completed").
- Проверьте, что клиент получил email (если добавляли отправку почты).
- Если интеграция с внешним сервисом, проверьте логи запросов или ответ API.
- Для отладки можно временно добавить
error_logвнутри функции и проверить файлdebug.log(включите WP_DEBUG и WP_DEBUG_LOG).
Частые ошибки и как их исправлять
- Письмо отправляется несколько раз при повторном изменении статуса
Решение: добавлять проверку, что старый статус не совпадает с новым. - Объект
$orderне передан или null
Проверьте, что функция принимает 4 параметра и указана вadd_actionс числом 4 аргументов. - Ошибка при отправке POST-запроса к API
Проверьте URL, формат данных и наличие SSL на сервере.
Практические советы по производительности и безопасности
- Не выполняйте долгие запросы или тяжелые операции напрямую в хуках изменения статуса — лучше использовать очередь или WP-Cron для асинхронной обработки.
- Используйте
wp_mailс проверкой результатов и настройками SMTP для надежной доставки почты. - Для интеграции с внешними API добавьте обработку ошибок и повторную попытку отправки.
- Не выводите чувствительные данные в логи на продакшн-сайте.
Сравнение способов реализации отправки уведомлений при смене статуса
| Способ | Плюсы | Минусы | Пример кода |
|---|---|---|---|
Использовать woocommerce_order_status_changed напрямую |
Просто, быстро, подходит для большинства задач | Может нагружать сайт при большом количестве заказов | В статье выше |
| Отложенная обработка через WP-Cron | Не блокирует работу сайта, можно масштабировать | Сложнее в реализации, возможны задержки | wp_schedule_single_event() + хук |
| Использовать сторонние плагины уведомлений | Готовые решения, много настроек | Зависимость от плагина, меньше гибкости | Например, Better Notifications for WP |