Всё хорошо
Покупатель платит, банк шлёт уведомление, сервер сверяет платёж с банком и только потом выдаёт доступ.
Как закрываю
Сервис не верит уведомлению на слово. На курсе по монтажу уведомление однажды пришло не по адресу: бот запросил платёж у банка, не нашёл его и доступ вслепую не выдал.
Вебхук не дошёл
Банк списал деньги и отправил уведомление, а сервер в эту минуту недоступен. Покупатель заплатил, заказ висит без оплаты, доступ никто не выдал.
Как закрываю
Фоновая задача сама спрашивает у банка статус незавершённых заказов. На SaveAPP адрес уведомлений было не поменять, поэтому мост опрашивал банк раз в 30 секунд.
Редирект потерял запрос
Адрес уведомлений отвечает редиректом, например на www. По дороге POST превращается в GET, тело запроса теряется, и сервер получает пустой конверт.
Как закрываю
Прописываю конечный адрес и проверяю его так, как его вызовет сервис. На ViVaDa так ломалась интеграция с агрегатором: ушёл POST, приехал GET без данных.
Повторное уведомление
Банк шлёт то же уведомление ещё раз. Это нормально: ЮKassa повторяет его в течение 24 часов, если не получила ответ 200. Простой обработчик каждый раз заново шлёт письмо и выдаёт доступ.
Как закрываю
Обработчик видит, что платёж уже учтён, отвечает 200 и больше ничего не делает. На курсе по монтажу я видел три повтора за пять минут, в 17:33, 17:35 и 17:38.
Карта отклонена
Банк отказал, деньги не списаны, а страница возврата всё равно говорит «Спасибо». Покупатель уверен, что оплатил, и ждёт доступ.
Как закрываю
Страница возврата проверяет статус платежа, при отказе показывает ошибку и даёт повторить. Уведомления идут только после payment.succeeded. На курсе по монтажу были оба случая, оба закрыты.