Тестирование платёжной интеграции: сценарии, которые забывают проверить
Тестирование платёжной интеграции не заканчивается проверкой, что тестовая оплата проходит и заказ становится «оплачен». Основные потери случаются в сценариях, которые в обычном прогоне не встречаются: повторное уведомление, потерянное уведомление, оплата отменённого заказа, расхождение сумм, таймаут при создании платежа. Ниже чек-лист, который я использую перед запуском: сценарии, способы их воспроизвести и признаки того, что система ведёт себя правильно.
С какого момента считать интеграцию протестированной
Я исхожу из простого определения: интеграция протестирована, когда для каждого возможного исхода платежа вы знаете, что произойдёт с заказом, с деньгами и с учётом, и вы это проверили. Исходов больше, чем кажется. Помимо «успех» и «отказ», есть «ожидание», «отмена покупателем», «истёк срок», «успех без уведомления», «двойное уведомление», «частичный возврат» и так далее.
Прежде чем начать, заведите таблицу исходов. По строкам сценарии, по столбцам: ожидаемый статус заказа, ожидаемая запись в журнале, ожидаемое поведение для покупателя, ожидаемый след в учёте. Такая таблица (в документе или в трекере, не обязательно в сайте) превращает тестирование из хаотичного кликанья в проверяемую процедуру.
Если тестовой среды у провайдера нет или она отличается от рабочей, зафиксируйте это ограничение. Сверьтесь с документацией и менеджером: что именно можно проверить на тестовых данных, а что только на реальных операциях небольшой суммы.
Базовые сценарии, без которых нельзя запускаться
Начните с очевидного, но проверьте его полностью, включая следы в данных.
- Успешная оплата. Заказ меняет статус, запись платежа содержит идентификатор операции, сумму и время подтверждения, покупатель видит страницу успеха, письмо или сообщение отправлено один раз.
- Отказ банка или недостаток средств. Заказ остаётся неоплаченным, покупателю предлагается повторить попытку, повторная попытка создаёт корректный платёж, а не ломает предыдущий.
- Отмена покупателем на странице оплаты. Заказ не теряется, и его можно оплатить заново.
- Истечение срока оплаты. Платёж переходит в статус «просрочен», резерв товара снимается по вашим правилам.
- Закрытие вкладки сразу после оплаты. Заказ всё равно становится оплаченным, потому что подтверждение пришло от провайдера, а не от браузера.
Пятый пункт проверяйте руками: оплатите и закройте окно до возврата на сайт. Если после этого заказ остался «ожидает оплаты», значит, статус зависит от возврата покупателя, и это дефект.
Сценарии с уведомлениями
Здесь чаще всего находятся серьёзные ошибки.
Повторное уведомление. Отправьте то же уведомление дважды, а лучше пять раз, в том числе почти одновременно. Должна появиться одна запись платежа, один документ в учёте, одно письмо. Принципы защиты описаны в статье про идемпотентность повторных уведомлений. Проверка параллельных запросов важна: последовательные повторы проходят даже у слабой реализации, а гонка находит дыры.
Потерянное уведомление. Отключите приём (закройте адрес, остановите обработчик), проведите оплату, затем включите обратно. Заказ должен закрыться фоновой проверкой по расписанию, либо попасть в список «требует внимания». Если не случилось ни того, ни другого, вы обнаружили дыру.
Уведомление в неожиданном порядке. Например, «отменён» приходит после «оплачен», или наоборот. Правила переходов статусов должны быть явными: из какого состояния в какое можно перейти. Недопустимый переход логируется и не меняет данные молча.
Уведомление с неверной подписью или чужими данными. Подделанный запрос должен быть отклонён, а попытка записана в журнал. Проверьте и случай корректной подписи при несовпадающей сумме или идентификаторе заказа.
Уведомление для неизвестного заказа. Не должно быть ошибки 500 и не должно создаваться «призрачных» записей. Нужна аккуратная запись в журнал и ответ в формате, который ожидает провайдер (его уточните в документации, иначе провайдер может повторять запросы бесконечно).
Медленный ответ. Что, если ваш обработчик отвечает дольше, чем ждёт провайдер? Тяжёлую работу (передачу в учёт, отправку писем) выносите из обработчика в очередь, а на запрос отвечайте быстро.
Сценарии с деньгами и суммами
Деньги ломаются на мелочах, которые в обычной демонстрации не видны.
- Суммы с копейками и округлением. Заказ на сумму с дробной частью, со скидкой, с процентом, с несколькими позициями. Итог на сайте, в запросе к провайдеру и в учёте должен совпасть до копейки.
- Минимальные и максимальные суммы. Что происходит с заказом на очень малую сумму или на очень большую? Лимиты провайдера нужно узнать заранее и обработать понятным сообщением, а не безликой ошибкой.
- Подмена суммы. Попробуйте изменить сумму в запросе браузера. Сервер обязан формировать её сам, из данных заказа.
- Валюта. Если вы работаете с несколькими валютами, проверьте, что валюта передаётся и сверяется, а не подразумевается.
- Скидки, промокоды, бонусы, оплата частично бонусами. Платёж провайдеру уходит на оставшуюся сумму, и она корректна при любом сочетании.
Сценарии с жизненным циклом заказа
Платёж живёт не сам по себе, он связан с заказом, который может меняться.
Оплата отменённого заказа. Покупатель получил ссылку, не оплатил, заказ отменили или истёк срок резерва, и тут покупатель платит. Что делает система? Варианты: автоматически возвращает деньги, восстанавливает заказ, если товар ещё есть, или создаёт задачу менеджеру. Любой вариант годится, если он выбран осознанно и проверен. Худший вариант, когда деньги списаны, а у вас никто об этом не знает.
Изменение заказа после создания платежа. Сумма изменилась, а платёж на старую сумму ещё действует. Нужно либо аннулировать старый платёж, либо блокировать правки заказа до окончания оплаты.
Несколько попыток оплаты одного заказа. Каждая попытка должна быть отдельным платежом с собственным идентификатором, но заказ можно оплатить только один раз. Что будет, если успешными окажутся две попытки? Это редкий, но реальный случай, и для него нужно решение, например возврат лишнего платежа.
Возвраты. Полный, частичный, повторный возврат одной и той же суммы, возврат после закрытия периода. Статус заказа, сумма в учёте и остаток к возврату должны меняться согласованно. Если возвраты делаются через кабинет провайдера, а не из вашей системы, убедитесь, что информация о них возвращается к вам, иначе сверка покажет расхождение. Об этом подробнее в материале про автоматическую сверку платежей с 1С.
Сбои и нештатные условия
Проверьте поведение системы, когда что-то не работает.
Провайдер недоступен при создании платежа. Покупатель должен получить понятное сообщение и возможность повторить, а заказ не должен «зависнуть» в странном состоянии.
Таймаут запроса. Вы отправили запрос на создание платежа, ответа нет. Повтор может создать второй платёж. Решения: ключ повторности, если провайдер его поддерживает (уточняйте в документации), либо проверка существующего платежа по вашему идентификатору перед созданием нового.
Недоступен учёт. Подтверждённые платежи копятся в очереди и уходят после восстановления связи. Проверьте, что порядок и целостность сохраняются, а дублей нет.
База данных отвечает медленно или временно недоступна в момент прихода уведомления. Провайдер повторит запрос, но только если вы вернёте ошибку, а не успех. Убедитесь, что при сбое записи вы не отвечаете «принято».
Безопасность и приватность
Часть тестов относится к защите. Просмотрите журналы: нет ли в них секретных ключей, полных данных карт или лишних персональных данных. Проверьте, что ключи не попали в клиентский код и в репозиторий. Убедитесь, что адрес для уведомлений не раскрывает внутреннюю информацию в ответах на ошибки.
Попробуйте перебрать идентификаторы заказов на странице статуса оплаты: чужой заказ не должен открываться. Подробнее о защите платежей я писал в статье про подпись запросов и журнал.
Требования платёжных систем к хранению данных и к страницам оплаты определяются их правилами и действующими нормами, поэтому уточняйте их у провайдера и юриста.
Как организовать тестирование, чтобы оно не превратилось в формальность
Несколько практических приёмов.
Пишите сценарии заранее, а прогоняйте с отметками «прошёл, не прошёл, дата, кто проверял». Повторяйте весь список после любых изменений в платёжной части, а не только после первого запуска.
Для повторяющихся проверок делайте небольшие скрипты, которые отправляют уведомления с нужными телами и подписями. Ручная имитация повторных и параллельных запросов неудобна, а скрипт позволяет прогнать её за секунды.
Проведите запуск на реальных малых суммах. Тестовая среда не всегда повторяет поведение рабочей. Один-два настоящих платежа с последующим возвратом многое проясняют, включая то, как выглядит операция в кабинете и в выписке.
После запуска наблюдайте. Первые дни смотрите журнал и список заказов в ожидании каждый день. Многие проблемы проявляются только при реальном трафике. Для оповещений о сбоях пригодится материал про мониторинг сервисов.
Частые вопросы
Достаточно ли тестовой среды провайдера?
Обычно её хватает для проверки основной логики, но не всегда она воспроизводит все реальные ситуации. Поэтому я рекомендую дополнительно пройти финальный прогон на реальных небольших операциях, если это допускают условия договора.
Кто должен проводить приёмку платёжной интеграции?
Не только разработчик. Желательно участие того, кто будет работать с платежами каждый день: менеджера или бухгалтера. Он заметит несоответствие в том, как данные видны в учёте.
Как проверить параллельные уведомления без специальных инструментов?
Достаточно небольшого скрипта, который отправляет несколько одинаковых запросов одновременно. Результат смотрите по числу созданных записей платежей и документов.
Нужно ли повторять тестирование при смене провайдера или версии API?
Да, хотя бы по основным сценариям. Форматы данных, статусы и порядок событий могут отличаться, и скрытые допущения в вашем коде проявятся именно при смене.
Если вы готовите запуск приёма платежей и хотите проверить интеграцию по списку, посмотрите страницу об интеграциях платёжных систем или напишите в Telegram.