Диагностика проблемы с повторной отправкой писем в WooCommerce
При изменении статуса заказа WooCommerce по умолчанию отправляет уведомления покупателю. Однако часто возникает ситуация, когда статус меняется несколько раз подряд или программно, и письма начинают приходить повторно и избыточно, что раздражает клиентов и нагружает сервер.
Чтобы понять, когда именно происходит повторная отправка писем, полезно включить логирование email-событий или использовать плагины отладки, например WP Mail Logging. Это позволит выявить, какие хуки срабатывают многократно и при каких условиях.
Пошаговое решение: блокируем повторную отправку писем на основе условий
1. Определяем статус и условия, при которых письма не должны отправляться
Например, вы хотите, чтобы письмо отправлялось только при первом переходе заказа в статус processing, но не при повторных переходах или сменах на другие статусы.
2. Используем фильтр woocommerce_email_enabled_{$email_id} для отключения письма
Этот фильтр позволяет динамически включать или отключать отправку конкретного email. Ниже пример, как отключить письмо, если статус заказа уже был processing ранее.
add_filter('woocommerce_email_enabled_customer_processing_order', 'disable_duplicate_processing_email', 10, 2);
function disable_duplicate_processing_email($enabled, $order) {
// Проверяем мета-флаг, отправлялся ли уже email обработки заказа
if ($order->get_meta('_processing_email_sent')) {
return false; // отключаем повторную отправку
}
return $enabled;
}
// Ставим мета-флаг после отправки письма
add_action('woocommerce_order_status_processing', 'mark_processing_email_sent');
function mark_processing_email_sent($order_id) {
$order = wc_get_order($order_id);
if (!$order->get_meta('_processing_email_sent')) {
$order->update_meta_data('_processing_email_sent', true);
$order->save();
}
}3. Расширяем логику для других статусов и условий
Аналогично можно контролировать письма для статусов completed, on-hold и других, используя соответствующие фильтры:
woocommerce_email_enabled_customer_completed_orderwoocommerce_email_enabled_customer_on_hold_order
Проверка результата после внедрения
Чтобы убедиться, что повторная отправка писем отключена:
- Сделайте тестовый заказ и смените статус на
processing— письмо должно отправиться. - Повторно смените статус на
processing(например, через админку или программно) — письмо не должно отправиться. - Проверьте логи почты или используйте WP Mail Logging для подтверждения.
Частые ошибки и как их исправить
- Ошибка: Метаданные не сохраняются — проверьте, что
$order->save()вызывается после обновления метаданных. - Ошибка: Хук
woocommerce_order_status_processingсрабатывает до отправки письма — убедитесь, что мета-флаг ставится именно после отправки, или используйте более подходящий хук, напримерwoocommerce_email_sendс проверкой типа письма. - Ошибка: Письмо отключается для всех заказов — проверьте логику проверки мета-поля, возможно, оно выставляется некорректно или глобально.
Практические советы по безопасности и производительности
- Храните метаданные с префиксом, чтобы избежать конфликтов с другими плагинами.
- Не создавайте избыточных запросов к базе — используйте кеширование с помощью Transients, если проверка частая.
- Проверяйте корректность email-шаблонов после отключения писем, чтобы не нарушить цепочки уведомлений.
Сравнение вариантов решения
| Способ | Плюсы | Минусы |
|---|---|---|
Использование мета-поля и фильтра woocommerce_email_enabled_{$email_id} | Контроль на уровне отправки, гибкость условий, не требует плагинов | Нужно аккуратно ставить мета, возможны ошибки при сохранении |
| Отключение email через плагин (например, Email Control) | Простой интерфейс, быстрое решение | Меньше гибкости, добавляет нагрузку, не всегда учтёт все условия |
| Изменение статуса заказа с помощью кода без вызова отправки email | Полный контроль над процессом | Сложнее реализовать, требует глубоких знаний API WooCommerce |