#Признаки проблемы и применимость
Заказ в Битрикс сохраняется, но пользовательский обработчик события не запускает ожидаемое действие — запись в систему учёта, письмо или обновление служебного поля. Важно отличить событие создания от последующего сохранения, проверить регистрацию обработчика и не вызвать повторное сохранение заказа по кругу.
#Причины и отличительные признаки
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Подписка не зарегистрирована в текущем окруженииПодписка не зарегистрирована в текущем окружении. Функция есть в коде, но не вызывается | Функция есть в коде, но не вызывается | Проверить EventManager/addEventHandler и подключение файла |
| Подписан не тот этап событияПодписан не тот этап события. Обработчик нового заказа ожидает OnSaleOrderSaved при ином жизненном цикле | Обработчик нового заказа ожидает OnSaleOrderSaved при ином жизненном цикле | Сопоставить OnSaleOrderBeforeSaved/OnSaleOrderSaved |
| Обработчик завершается ошибкойОбработчик завершается ошибкой. Заказ есть, но побочное действие отсутствует | Заказ есть, но побочное действие отсутствует | Найти исключение в журнале и проверить идемпотентность |
#Пошаговая диагностика и исправление
- Определите точное ожидаемое действиеЗапишите ID безопасного тестового заказа, какое поле или внешняя запись должна появиться и в какой момент. Уточните: после создания, после оплаты или после отгрузки? Эти события различаются; обработчик оплаты не обязан выполняться при обычном создании.
- Проверьте, что заказ действительно сохранёнВ административной части магазина найдите тестовый заказ и убедитесь, что его ID существует. Если нет — исследуйте ошибку оформления заказа, а не события после сохранения. Не создавайте многократно оплачиваемые заказы.
- Сопоставьте имя события с версией APIВ коде собственного модуля посмотрите регистрацию обработчика: EventManager::getInstance()->addEventHandler и название модуля sale. Для событий D7 на сохранение заказа используются OnSaleOrderBeforeSaved и OnSaleOrderSaved; у последнего можно проверить параметр IS_NEW. Не заменяйте автоматически старые события без анализа версии.
- Проверьте подключение файла с обработчикомПосмотрите, загружается ли модуль или файл /local/php_interface/init.php в установленной конфигурации. На тестовой копии временно добавьте узкую запись в закрытый журнал с ID заказа и временем. Не выводите сообщения в ответ покупателю и не записывайте персональные данные.
- Проверьте журнал исключенийСравните время сохранения с PHP-логом. Если обработчик обращается к внешнему API, его HTTP-ошибки и тайм-ауты могут не отменять заказ; их следует логировать отдельно. Не помещайте токены, номера карт и содержимое заказа в диагностический журнал.
- Проверьте повторный вызов и зацикливаниеНа копии воспроизведите одно создание и одно редактирование заказа. Если обработчик вызывается дважды или сам сохраняет тот же заказ, установите проверку состояния и идемпотентный ключ. Не добавляйте безусловный save() внутрь события OnSaleOrderSaved.
- Примените минимальную правку и протестируйте последствияПосле проверки регистрации и условий запустите единичный тестовый заказ. Убедитесь, что обработчик выполнился ровно один раз, а сумма, статус и корзина не изменились. При повторном вызове откатите код и оставьте автоматические действия отключёнными до исправления.
#Проверка результата
Для одного создания заказа вызывается ожидаемое действие без дублей, при редактировании не возникает цикл; журнал не содержит исключений и заказы продолжают сохраняться.
#Что делать, если не помогло
Если события нет, проверьте регистрацию модуля и жизненный цикл заказа; если событие есть, но действие отсутствует, исследуйте условия обработчика и внешнюю интеграцию.