Диагностика проблемы с обработкой вебхуков ЮКассы и обновлением базы данных

На двух проектах, размещенных на одном хостинге, внезапно перестали корректно обрабатываться уведомления от ЮКассы. Несмотря на успешный статус платежей (200 OK), данные в базе MySQL не обновляются: подписки пользователей не активируются, а записи о платежах не добавляются.

Поддержка ЮКассы подтверждает, что уведомления отправляются и получают корректный ответ от обработчика. Тестовый эмулятор, полностью повторяющий структуру запроса ЮКассы, работает без ошибок и вносит изменения в базу данных. Хостинг-провайдер (Джино) также не видит проблем на своей стороне.

Ключевые симптомы проблемы

  • Реальные платежи от ЮКассы не приводят к обновлению данных в таблицах users и payments.
  • Тестовые запросы, отправленные вручную, обрабатываются корректно.
  • В логах ЮКассы фиксируется успешный ответ (HTTP 200) от callback-скрипта pay.php.
  • Проблема возникла одновременно на двух независимых проектах.

Анализ кода обработчика

Представленный скрипт pay.php выполняет стандартную логику:

  1. Принимает и валидирует JSON-данные от ЮКассы.
  2. Проверяет событие payment.succeeded и статус succeeded.
  3. Реализует защиту от повторной обработки через проверку payment_id в таблице payments.
  4. Определяет тариф на основе суммы платежа.
  5. Расширяет дату подписки пользователя.
  6. Обновляет запись пользователя и создает запись о платеже.

Возможные направления для диагностики

Разрыв между успешным ответом скрипта и фактическим отсутствием изменений в БД указывает на одну из следующих проблем:

  • Ошибки выполнения после отправки HTTP 200: Скрипт может завершаться с кодом 200, но последующие операции с базой данных вызывают исключения, которые не логируются.
  • Проблемы с транзакциями или подключением к БД: В момент реального запроса от ЮКассы может возникать ситуация, когда соединение с MySQL разрывается, откатывается или находится в неконсистентном состоянии.
  • Различия в данных реального и тестового запроса: Структура или значения полей в реальных уведомлениях могут отличаться от тестовых, приводя к раннему выходу из скрипта (например, из-за неуказанного поля в metadata).
  • Проблемы с правами доступа или блокировками: Одновременные запросы или изменения в конфигурации хостинга могли привести к ошибкам при записи в конкретные таблицы.
  • Отсутствие логирования ошибок PHP/MySQL: Критические ошибки могут подавляться, и их необходимо выявить, включив детальное логирование в скрипте.

Рекомендуемый план действий

  1. Внедрить детальное логирование: Добавить в скрипт pay.php запись всех шагов, полученных данных и ошибок БД в отдельный лог-файл перед отправкой любого HTTP-ответа.
  2. Сравнить полные тела запросов: Убедиться, что реальный запрос от ЮКассы содержит все поля, необходимые для валидации (особенно metadata['nickname']).
  3. Проверить конфигурацию PHP и БД: Убедиться в отсутствии лимитов на время выполнения скрипта (max_execution_time), в корректности настроек PDO/MySQLi, а также в том, что автоматическая фиксация транзакций включена.
  4. Проанализировать логи веб-сервера и MySQL: Проверить логи ошибок Apache/Nginx и MySQL (например, slow_query_log) на предмет соответствующих временных меток.
  5. Временно отключить защиту от повторной обработки: Для исключения этого фактора можно закомментировать проверку существующего payment_id.

Наиболее вероятной причиной является тихая ошибка на уровне базы данных, которая возникает после отправки заголовка 200 OK, но до или во время выполнения SQL-запросов. Внедрение комплексного логирования - ключевой шаг для выявления истинной причины сбоя.