Диагностика проблемы с обработкой вебхуков ЮКассы и обновлением базы данных
На двух проектах, размещенных на одном хостинге, внезапно перестали корректно обрабатываться уведомления от ЮКассы. Несмотря на успешный статус платежей (200 OK), данные в базе MySQL не обновляются: подписки пользователей не активируются, а записи о платежах не добавляются.
Поддержка ЮКассы подтверждает, что уведомления отправляются и получают корректный ответ от обработчика. Тестовый эмулятор, полностью повторяющий структуру запроса ЮКассы, работает без ошибок и вносит изменения в базу данных. Хостинг-провайдер (Джино) также не видит проблем на своей стороне.
Ключевые симптомы проблемы
- Реальные платежи от ЮКассы не приводят к обновлению данных в таблицах
usersиpayments. - Тестовые запросы, отправленные вручную, обрабатываются корректно.
- В логах ЮКассы фиксируется успешный ответ (HTTP 200) от callback-скрипта
pay.php. - Проблема возникла одновременно на двух независимых проектах.
Анализ кода обработчика
Представленный скрипт pay.php выполняет стандартную логику:
- Принимает и валидирует JSON-данные от ЮКассы.
- Проверяет событие
payment.succeededи статусsucceeded. - Реализует защиту от повторной обработки через проверку
payment_idв таблицеpayments. - Определяет тариф на основе суммы платежа.
- Расширяет дату подписки пользователя.
- Обновляет запись пользователя и создает запись о платеже.
Возможные направления для диагностики
Разрыв между успешным ответом скрипта и фактическим отсутствием изменений в БД указывает на одну из следующих проблем:
- Ошибки выполнения после отправки HTTP 200: Скрипт может завершаться с кодом 200, но последующие операции с базой данных вызывают исключения, которые не логируются.
- Проблемы с транзакциями или подключением к БД: В момент реального запроса от ЮКассы может возникать ситуация, когда соединение с MySQL разрывается, откатывается или находится в неконсистентном состоянии.
- Различия в данных реального и тестового запроса: Структура или значения полей в реальных уведомлениях могут отличаться от тестовых, приводя к раннему выходу из скрипта (например, из-за неуказанного поля в
metadata). - Проблемы с правами доступа или блокировками: Одновременные запросы или изменения в конфигурации хостинга могли привести к ошибкам при записи в конкретные таблицы.
- Отсутствие логирования ошибок PHP/MySQL: Критические ошибки могут подавляться, и их необходимо выявить, включив детальное логирование в скрипте.
Рекомендуемый план действий
- Внедрить детальное логирование: Добавить в скрипт
pay.phpзапись всех шагов, полученных данных и ошибок БД в отдельный лог-файл перед отправкой любого HTTP-ответа. - Сравнить полные тела запросов: Убедиться, что реальный запрос от ЮКассы содержит все поля, необходимые для валидации (особенно
metadata['nickname']). - Проверить конфигурацию PHP и БД: Убедиться в отсутствии лимитов на время выполнения скрипта (max_execution_time), в корректности настроек PDO/MySQLi, а также в том, что автоматическая фиксация транзакций включена.
- Проанализировать логи веб-сервера и MySQL: Проверить логи ошибок Apache/Nginx и MySQL (например,
slow_query_log) на предмет соответствующих временных меток. - Временно отключить защиту от повторной обработки: Для исключения этого фактора можно закомментировать проверку существующего
payment_id.
Наиболее вероятной причиной является тихая ошибка на уровне базы данных, которая возникает после отправки заголовка 200 OK, но до или во время выполнения SQL-запросов. Внедрение комплексного логирования - ключевой шаг для выявления истинной причины сбоя.