Как PDP бронирует квартиры через платёжные ссылки банка
В PDP подключили банк-эквайер для онлайн-бронирования квартир: платёжные ссылки с TTL, редирект на страницу банка и callback с проверкой цифровой подписи.

«Бронь не должна висеть вечно».
Пользователь выбирает квартиру в PDP, выбирает тип финансирования — ипотека, рассрочка или полная оплата — и нажимает оплату бронирования. Дальше сценарий должен быть скучным: открылась страница банка, платёж прошёл, бронь зафиксировалась. Без ощущения, что деньги ушли в одну систему, а квартира осталась в другой.
Инженерная часть здесь начинается в момент, когда PDP формирует платёжную ссылку. Ссылка живёт ограниченное время: у неё есть TTL. Это важно для бронирования, потому что квартира не может бесконечно ждать пользователя, который ушёл пить кофе, закрыл вкладку или решил вернуться завтра.
Что видит пользователь
В пользовательском сценарии нет карточной формы внутри PDP. После выбора условий бронирования пользователь уходит на страницу банка-эквайера. Там он вводит платёжные данные, подтверждает операцию и возвращается обратно.
Такой маршрут выглядит привычно: банк отвечает за платёжную страницу, PDP — за состояние брони. Граница ответственности понятная и для пользователя, и для разработки.
Но у этого маршрута есть важная деталь: возврат пользователя со страницы банка нельзя считать доказательством оплаты. Вкладку можно закрыть. Редирект может не доехать. Пользователь может нажать «назад». Поэтому финальное решение по брони PDP принимает не по факту возврата в интерфейс, а по callback от банка.
Жизнь платёжной ссылки
Для каждой попытки оплаты PDP создаёт платёжную ссылку у банка-эквайера. В ссылку закладывается ограничение по времени жизни. Пока TTL не истёк, пользователь может перейти по ссылке и завершить оплату на стороне банка.
После истечения TTL ссылка больше не должна удерживать бронь. Это та самая часть, которую пользователь обычно не формулирует словами, но хорошо чувствует: если ссылка протухла, система не должна делать вид, что всё ещё можно оплатить старую попытку.
Самый неприятный класс ошибок в такой схеме — рассинхрон статусов. Например, пользователь оплатил на странице банка, но не вернулся в PDP. Или наоборот: вернулся, но платёж ещё не подтверждён. Поэтому редирект оставили пользовательским маршрутом, а не источником истины.
Callback и подпись банка
Банк-эквайер отправляет callback в PDP после события по платежу. На этом шаге нельзя доверять только тому, что HTTP-запрос пришёл на нужный endpoint. В callback проверяется цифровая подпись банка.
Смысл проверки простой: PDP должен убедиться, что статус платежа сообщил именно банк, а не кто-то, кто знает URL обработчика. Только после верификации подписи можно менять состояние бронирования.
Здесь была живая, но полезная дискуссия: где проводить границу между «пользователь видит успешный экран» и «бронь действительно подтверждена». Решили держаться банковского callback. Экран после возврата может подсказать, что платёж обрабатывается, но изменение статуса брони завязано на подписанное сообщение от эквайера.
Ипотека, рассрочка и полная оплата
В PDP нужно было учесть три типа финансирования: ипотека, рассрочка и полная оплата. Для пользователя это разные способы купить квартиру, но для интеграции с эквайером они сходятся в одном месте: оплате бронирования через платёжную ссылку.
Мы не стали смешивать бизнес-логику выбора финансирования с обработкой банковского callback. Тип финансирования фиксируется в сценарии бронирования, а платёжная интеграция отвечает за своё: создать ссылку с TTL, отправить пользователя в банк, принять callback, проверить цифровую подпись и обновить статус.
В такой схеме меньше скрытых зависимостей. Если позже меняются правила по ипотеке или рассрочке, обработчик банковского callback не превращается в место, где внезапно живёт половина продуктовой логики.
Следующий участок, за которым стоит следить в подобных интеграциях, — тексты и состояния для пользователя: ссылка истекла, платёж ожидает подтверждения, бронь подтверждена, платёж не прошёл. Именно эти статусы превращают банковскую интеграцию из набора endpoint’ов в понятный сценарий бронирования.