Диагностика проблемы: почему письма отправляются повторно при изменении статуса
В WooCommerce по умолчанию при каждом изменении статуса заказа запускаются определённые email-уведомления. Это может приводить к нежелательной повторной отправке писем, например, когда статус меняется с "обработка" на "выполнен" и обратно, или при редактировании заказа администратором.
Пользователи часто замечают, что клиенты получают несколько писем с одинаковой информацией, что ухудшает пользовательский опыт и может привести к недоверию.
Как проверить, что проблема именно в повторной отправке писем?
- Проанализируйте логи email (если ведется), либо временно активируйте плагин для логирования почты, например
WP Mail Logging. - Измените статус заказа вручную и проверьте, сколько писем приходит на почту.
- Проверьте пользовательские хуки или сторонние плагины, которые могут принудительно отправлять письма.
Пошаговое решение: отключение повторной отправки email при обновлении заказа
1. Использование фильтра woocommerce_email_enabled_{email_id}
Чтобы предотвратить повторную отправку писем при изменении статуса, можно отключить email с помощью фильтра. Например, для письма о новом заказе (new_order) или обработки заказа (customer_processing_order).
add_filter('woocommerce_email_enabled_customer_processing_order', 'disable_repeated_email', 10, 2);
function disable_repeated_email($enabled, $order) {
// Проверяем, если заказ уже был отмечен как обработанный
if (get_post_meta($order->get_id(), '_processing_email_sent', true)) {
return false; // Отключаем письмо
}
// Сохраняем мета, что письмо отправлено
update_post_meta($order->get_id(), '_processing_email_sent', true);
return $enabled;
}Этот код позволяет отправить письмо только один раз, добавляя мета-данные к заказу.
2. Сброс мета при возврате заказа в другой статус
Если заказ меняет статус обратно, мета нужно сбрасывать, чтобы при повторном переходе email снова мог отправиться, если это нужно.
add_action('woocommerce_order_status_changed', 'reset_processing_email_flag', 10, 4);
function reset_processing_email_flag($order_id, $old_status, $new_status, $order) {
if ($new_status !== 'processing') {
delete_post_meta($order_id, '_processing_email_sent');
}
}Проверка результата после внедрения
- Создайте тестовый заказ и измените его статус с «в ожидании» на «обработка» — письмо должно отправиться.
- Повторно переключите статус обратно и снова на «обработка» — письмо не должно отправляться повторно.
- Проверьте логи почты или почтовый ящик клиента, чтобы убедиться, что письма приходят только один раз.
Частые ошибки и как их исправить
- Неправильное имя хука фильтра: Убедитесь, что используете правильный идентификатор письма. Список email ID можно найти в
includes/emails/вашего WooCommerce. - Отсутствие сброса мета-данных: Если мета не удаляется при смене статуса, письма могут не отправляться при повторных переходах, что не всегда желательно.
- Конфликт с плагинами отправки почты: Некоторые сторонние плагины могут игнорировать стандартные хуки WooCommerce. Проверьте совместимость.
Практические советы по безопасности и производительности
- Используйте кэширование мета-данных и избегайте излишних запросов к базе данных при проверках.
- Не отключайте email полностью — лучше контролировать логику отправки, чтобы не пропустить важные уведомления.
- Проверяйте совместимость изменений после обновления WooCommerce, так как внутренняя логика email может изменяться.
Сравнение методов отключения повторной отправки писем
| Метод | Плюсы | Минусы |
|---|---|---|
Фильтр woocommerce_email_enabled_{email_id} с мета-данными | Гибко, не требует плагинов, легко настраивается | Требует написания кода и контроля мета |
| Отключение email через настройки WooCommerce | Просто, без кода | Отключаются все письма данного типа, нет условий |
| Плагины для кастомизации email | Расширенные возможности, GUI | Нагрузка на сайт, возможны конфликты |