Проблема: письма не отправляются при массовом обновлении заказов в WooCommerce
При массовом изменении статусов заказов в WooCommerce стандартная отправка уведомлений часто не срабатывает. Это связано с тем, что массовые действия в админке используют WP_Query без вызова стандартных хуков, отвечающих за триггер писем. В результате клиенты и администраторы не получают уведомления о смене статуса.
Диагностика проблемы
- Проверьте, отправляются ли письма при изменении статуса заказа по одному через админ-панель.
- Измените несколько заказов массово и проверьте, приходят ли уведомления.
- Проверьте логи сервера и WooCommerce на наличие ошибок отправки.
- Отключите все плагины, кроме WooCommerce, и повторите тест.
Если при одиночном изменении письма уходят, а при массовом — нет, значит WooCommerce не запускает стандартные хуки для массового обновления.
Пошаговое решение: как заставить WooCommerce отправлять письма при массовом изменении статуса
1. Создайте кастомный плагин или добавьте код в functions.php вашей темы (желательно дочерней) для перехвата массового обновления статуса заказов.
2. Используйте хук woocommerce_order_status_changed, который срабатывает при смене статуса заказа, чтобы вручную запускать отправку писем.
3. В массовом изменении заказов WooCommerce не вызывает этот хук корректно, поэтому нужно вручную перебрать заказы и вызвать отправку уведомлений.
add_action('load-edit.php', function() {
if (!isset($_GET['post_type']) || $_GET['post_type'] !== 'shop_order') return;
if (!isset($_POST['action']) || ($_POST['action'] !== 'edit' && $_POST['action2'] !== 'edit')) return;
if (!isset($_POST['post']) || !is_array($_POST['post'])) return;
$new_status = isset($_POST['order_status']) ? sanitize_text_field($_POST['order_status']) : '';
if (!$new_status) return;
foreach ($_POST['post'] as $order_id) {
$order = wc_get_order($order_id);
if (!$order) continue;
$old_status = $order->get_status();
if ($old_status !== $new_status) {
$order->update_status($new_status, 'Статус изменен массово через админку', true);
}
}
// Перенаправление чтобы избежать повторного выполнения
wp_redirect(remove_query_arg(array('action', 'action2', 'post', 'order_status')));
exit;
});Объяснение кода:
- Перехватываем загрузку страницы редактирования заказов.
- Проверяем, что выполняется массовое действие (bulk edit).
- Получаем новый статус из POST-параметров.
- Для каждого заказа вызываем
update_status(), которая уже внутри запускает все необходимые хуки и отправляет письма. - Делаем редирект, чтобы избежать повторного выполнения кода при обновлении страницы.
Как получить новый статус из массового действия
В стандартном интерфейсе WooCommerce нет поля для массового изменения статуса заказов по умолчанию. Чтобы добавить возможность массового обновления статуса с корректной отправкой писем, можно использовать дополнительный плагин или собственный код, который добавит селектор статусов в массовые действия.
Пример добавления статуса в bulk actions:
add_filter('bulk_actions-edit-shop_order', function($bulk_actions) {
$bulk_actions['edit'] = __('Изменить статус', 'woocommerce');
return $bulk_actions;
});Далее нужно внедрить форму выбора статуса. Для этого можно использовать JavaScript для отображения селектора после выбора действия.
Проверка результата
- В админке перейдите в раздел «Заказы» (WooCommerce → Заказы).
- Выберите несколько заказов, в выпадающем списке массовых действий выберите «Изменить статус».
- Выберите новый статус и примените действие.
- Проверьте почтовый ящик клиента и администратора — письма с уведомлениями должны прийти.
- Если письма не пришли — проверьте логи почтового сервера и наличие ошибок в логах WordPress.
Частые ошибки и как исправить
- Письма не отправляются вообще: проверьте конфигурацию SMTP, используйте плагины типа WP Mail SMTP для настройки.
- Письма приходят с задержкой или в спам: настройте SPF, DKIM и DMARC для домена, используйте надежные SMTP-сервисы.
- Код не срабатывает при массовом обновлении: убедитесь, что правильно перехватываете параметры POST и что хук
load-edit.phpиспользуется корректно. - Неправильно передается статус: добавьте в массовые действия выбор статуса через JS и форму, чтобы передавать параметр
order_status.
Практические советы по производительности и безопасности
- Избегайте запуска тяжелых операций в цикле массового обновления — используйте транзакции или отложенные задачи, если заказов много.
- Ограничьте количество заказов, которые можно обновлять массово, чтобы не перегружать сервер и почтовый сервис.
- Проверяйте права пользователя на изменение заказов перед выполнением массовых операций.
- Логируйте массовые изменения статусов и отправку писем для аудита.
Сравнение вариантов решения массового обновления статусов с отправкой писем
| Подход | Плюсы | Минусы | Пример |
|---|---|---|---|
| Стандартный WooCommerce | Простота использования | Письма не отправляются при массовом обновлении | Отсутствует |
| Кастомный код с update_status() | Гарантированная отправка писем, полный контроль | Требует доработки интерфейса массовых действий | Код из статьи |
| Плагины для массового изменения статусов | Готовые решения, удобный UI | Могут быть платными, не всегда гибкие | WooCommerce Bulk Edit Plugins |