Перейти к содержимому

Финтех · MVP

Splitta

Рассрочка для интернет-магазинов: проверка покупателя, график платежей и возврат — на реальных платежах с первого дня.

Роль
Продуктовый дизайн, фронтенд, бэкенд, инфраструктура
Срок
7 недель
Стек
Next.js · Node.js · Docker

Что изменилось

46 дней
от первой встречи до первого платежа настоящего покупателя. Дату выбирал не проект: магазин входил в сезон на сорок девятый.
210 заявок
за первые шесть недель пилота, 138 из них одобрены. Гипотезу проверяли на них, а не на слайдах.
16 возвратов
каждый девятый оформленный заказ, и график пересчитался сам. Это та часть, которую чуть не отложили во вторую версию.
11 минут
медиана от заявки до решения в рабочие часы. Ночная заявка ждала утра: решение принимает человек, а не правило.

Экономику рассрочки проект не менял и не мог: кому одобрять, на какой срок и на каких условиях — правила заказчика, код их исполняет, а не пишет. И семь недель ничего не доказали про рынок: шесть недель на одном магазине отвечают, держится ли сценарий и правильно ли ходят деньги, а не нужен ли продукт многим. Чем заплачено за скорость, перечислено выше: ручная проверка, отсутствие автотестов за пределами денежных путей, один способ оплаты. Это работа, которую кто-то сделает, а не работа, которая не понадобилась.

Что было до

Продукт собирали с нуля, и параллельно шло подключение к платёжному провайдеру: без боевых ключей рассрочка остаётся презентацией, а дату выдачи ключей назначаем не мы. Заявку провайдеру подали на третий день проекта, раньше первой строки кода. Песочница пришла на девятый день, боевые ключи — на тридцать седьмой, за двенадцать дней до даты, к которой всё должно было работать.

  • Рассрочку компания выдавала несколько лет, но только в залах партнёров: решение принимал человек, у которого покупатель стоит перед глазами. Онлайн-заявок не было ни одной, а значит, не было и истории по ним.
  • Четыре интернет-магазина сказали «интересно, покажите, как это работает». Показывать было нечего: сценарий существовал на слайдах, а слайдам чекаут не отдают.
  • Дату назначил не проект. Партнёрский магазин пускал рассрочку в сезон, до начала которого оставалось сорок девять дней; следующее окно открывалось через полгода, и до него гипотеза просто лежала бы.

Что сделали

  • Сценарий покупателя: заявка, проверка, график и первый платёж — девять экранов на нашем домене, магазин отдаёт покупателя ссылкой и получает один вебхук.

  • Платёжный слой за одним интерфейсом: списание, отмена, возврат и повтор с ключом идемпотентности — провайдер меняется конфигурацией, а не переписыванием.

  • Админка ручной проверки: на время пилота заявку открывает сотрудник заказчика — решение, комментарий и возврат с пересчётом графика в одном месте.

Результат

Сервис вышел в продакшен внутри семи недель: первый платёж настоящего покупателя прошёл на сорок шестой день, за три дня до сезона, ради которого срок и назначался. Проверять стало что — не демонстрацию, а весь путь денег: заявку, отказ банка, повтор, возврат с пересчётом графика. За скорость заплачено ручной проверкой заявок, одним способом оплаты и одним магазином в пилоте; всё это названо ценой заранее, а не найдено после запуска.

Кто заказчик

Финансовая компания, которая выдаёт рассрочку несколько лет — но только в залах партнёров, где напротив покупателя сидит менеджер, а документы лежат на столе. В интернете у неё не было ничего: ни одной заявки, ни истории по заявкам, ни одного подключённого магазина.

В зале решение занимает у менеджера минут двадцать, и половину вопросов можно задать вслух. В браузере от покупателя остаются анкета, карта и несколько секунд терпения. Поэтому проверять предстояло не умение компании считать риск, а две чужие вещи: дойдёт ли покупатель до конца сценария и пустит ли магазин новый способ оплаты в свой чекаут.

Задача

Как ставил заказчик
«Сделайте, как у больших»: покупатель нажимает кнопку в чекауте, через секунду видит решение и график. В первую версию просили автоматический скоринг, личный кабинет покупателя и кабинет партнёра, чтобы магазины подключались сами.
Как задача выглядела после разбора
Скоринг строить было не на чем. Офлайн-решение опирается на то, что менеджер видит через стол, а онлайн-заявок не существовало: любой порог в первой версии был бы выдумкой за счёт заказчика. Дорогое место оказалось другим — возврат. В этой товарной категории назад едет примерно каждый девятый заказ, а возврат по рассрочке — не отмена платежа, а пересчёт действующего графика. Отсюда другая формулировка: за семь недель делается не продукт для рынка, а один сценарий целиком — на одном магазине, на настоящих деньгах, вместе с ветками, где всё пошло не так. Решение по заявке принимает человек, и это записано в план, а не обнаружено на второй неделе.

Почему нельзя было в лоб

Семь недель — это не скорость, а расписание, составленное чужими решениями. Четыре условия пришли снаружи и не двигались; два мы приняли сами и договорились о них до старта.

Дата сезона
Магазин пускал рассрочку с фиксированной даты и ни с какой другой: вне сезона его трафик — около трети, и пилот на нём отвечал бы месяцами. Сорок девять дней — весь бюджет проекта, и занять у конца было нечего: конец принадлежал не нам.
Боевые ключи провайдера
Проверку компании перед подключением провайдер ведёт по своему расписанию, а не по нашему плану. Песочница похожа на боевой контур ровно там, где провайдер это обещал, а расходится на отказах, повторах и возвратах, то есть ровно там, где в этом проекте и происходит вся работа.
Два дня чужого разработчика
Разработчика магазин мог выделить на два дня, в преддверии своего самого горячего сезона. Всё, что больше ссылки и вебхука, в срок бы не встало, как бы хорошо оно ни выглядело у нас на схеме.
Каждый девятый заказ возвращают
В этой категории возврат — обычное дело, а не редкая ветка. Значит, самая дорогая логика проекта попадала в первую версию, а дешёвые части оставались ждать своей очереди.
Настоящие деньги, а не песочница
Решение наше. Пилот на тестовых платежах доказал бы, что работает наш код, а не что работает продукт: отказ банка, повтор, частичный возврат, карта, истёкшая между двумя платежами, — всё это живёт только там, где деньги настоящие. Цена — нельзя выкатить «почти работает» и посмотреть, что будет.
Решение принимает человек
Тоже наше и тоже до старта: заявку открывает сотрудник заказчика. Один человек проходит около пятидесяти заявок за смену — по три минуты плюс звонок там, где что-то не сходится. На пилоте их было пять, и упирались мы не в число, а в часы: заявка, поданная ночью, ждала утра. Со вторым и третьим магазином ждать пришлось бы уже заметной части покупателей, поэтому пилот с самого начала ограничен одним магазином.

Как шла работа

  1. 01

    Разбор и сценарий

    1 неделя

    Пять дней ушло на путь денег: что происходит между «покупатель выбрал рассрочку» и «магазин получил перевод», и каждая ветка, где происходит не это, — отказ, отмена, несостоявшееся списание, возврат. Из недели вышли два решения, определившие остальные шесть: скоринга в первой версии не будет, возврат в неё войдёт. На третий день ушла заявка провайдеру — она всё равно ждала бы дольше кода.

  2. 02

    Платёжный слой и график

    1,5 недели

    Списание, отмена, возврат и повтор — за одним интерфейсом, чтобы провайдер остался сменной деталью, а не фундаментом. Здесь же арифметика графика: целые копейки, остаток от деления в первый платёж, пересчёт после частичного возврата. Это единственная часть проекта, на которую писали тесты, и первая, которая заработала на песочнице.

  3. 03

    Заявка, проверка, админка

    1,5 недели

    Девять экранов покупателя на нашем домене и админка, в которой заявку открывает сотрудник заказчика: анкета, результат привязки карты, то, что компания уже знает об этом покупателе, решение и комментарий к нему. Дизайн-систему не заводили: рисовали один сценарий целиком и делали компоненты по мере надобности — на четверых и на семь недель библиотека окупиться не успевает.

  4. 04

    Возврат и пересчёт

    1 неделя

    Дорогая неделя, и дорогой она была запланирована. Полный возврат закрывает график и возвращает уплаченное; частичный уменьшает остаток и пересобирает будущие платежи, не трогая прошедшие. Трудность не в формуле: возврат начинает магазин, деньги идут через провайдера, а график живёт у нас — три стороны обязаны сойтись на одной сумме, причём в любом порядке прихода.

  5. 05

    Прод, боевые ключи, первые платежи

    2 недели

    Инфраструктуру не откладывали на конец: тот же образ, что стоял на стенде, поднимался с первой недели. На тридцать седьмой день пришли боевые ключи, и переход на них занял смену конфигурации с перезапуском. Дальше девять дней своими картами и мелкими суммами: списание, отказ банка, повтор, возврат. Первый платёж настоящего покупателя прошёл на сорок шестой день, за три дня до сезона.

Технические решения

Стек отвечает не задаче вообще, а трём обстоятельствам этого проекта: команда из четырёх человек на два интерфейса, арифметика денег, которая обязана совпадать в трёх местах, и дата боевых ключей, назначенная снаружи.

  • Провайдер как сменная деталь

    Списание, отмена, возврат и статус платежа спрятаны за одним интерфейсом; остальной код знает четыре метода и один набор ошибок. Реализаций две: боевая и второго провайдера, доведённая до песочницы. Вторая нужна была не как запасной аэродром на бумаге, а как проверка интерфейса: пока реализация одна, интерфейс неизбежно повторяет форму первого провайдера. Точку невозврата назначили на сороковой день — нет ключей, переезжаем, четыре дня из оставшихся девяти. Ключи пришли на тридцать седьмой. Сработал бы переезд, мы не знаем.

  • Деньги целыми, график — записями

    Ни одной суммы в дробных числах: только целые копейки. График считается один раз, при оформлении, и ложится в базу отдельными платежами с датами, а не формулой, которую пересчитывают на каждом экране. Остаток от деления кладётся в первый платёж, а не размазывается по всем: тогда сумма графика равна сумме заказа буквально, и это одно сравнение вместо рассуждения об округлении.

  • Ключ идемпотентности и журнал заявки

    Каждый запрос к провайдеру несёт ключ, собранный из идентификатора платежа: повтор после таймаута приходит к тому же платежу, а не заводит второе списание. Каждая смена состояния заявки — строка журнала: кто, когда, что ответил провайдер, чем стало. На настоящих деньгах вопрос «что случилось с этим платежом» задают в тот же день, и отвечать на него походом в поддержку провайдера — значит отвечать завтра.

  • Ссылка и вебхук вместо SDK

    Вся интеграция магазина — подписанная ссылка с составом заказа и суммой, а обратно один вебхук: оформлено или нет. Ключей и графиков магазин не касается. Так вышло не от красоты, а от двух дней его разработчика. Побочный эффект оказался важнее замысла: раз сценарий живёт у нас, он одинаков у всех магазинов и правится без их релизов. Next.js здесь ровно за это — девять экранов покупателя и админка собраны одним приложением, с одним деплоем и одним набором форм.

  • Один образ, две конфигурации

    Стенд и продакшен — один и тот же образ; отличаются они переменными окружения, и ключи провайдера среди них. Поэтому день прихода боевых ключей не стал событием: конфигурация и перезапуск вместо ветки, выкатки и второго круга тестов. Docker здесь не про масштабирование — на пилоте один контейнер и одна база, — а про то, чтобы неизвестная дата снаружи не превращалась в риск внутри.

Что осталось за рамками

Ниже — список того, чего в первой версии нет. Он писался до запуска, а не после: у каждой строки есть причина и цена.

  • Автоматическое решение по заявке. Правило нельзя написать раньше, чем закроется первый полный цикл платежей: пока ни один график не дошёл до конца, неизвестно, кого одобрили зря. Первые двести заявок с их исходами — материал, а не ответ.

  • Автотесты за пределами денежных путей. График, возврат и повторы покрыты; админку и боковые экраны проверяли руками. Цена известна: из четырёх дефектов, найденных в первые две недели после запуска, три были в админке.

  • Подключение магазинов. Второй и третий подключаем мы, руками, примерно за день каждый. Кабинет партнёра, в котором магазин подключается сам, не делали: строить его до того, как сценарий устоялся, — значит закрепить в интерфейсе то, что ещё двигается.

  • Просрочка. Автоматизированы напоминания; всё, что после них, ведёт человек по правилам заказчика — их писал его юрист, и в код мы их намеренно не переносили.

  • Способы оплаты. В первой версии одна привязанная карта на весь график. Каждый следующий способ — это ещё одна ветка возврата, а возврат мы уже посчитали самым дорогим местом.

Сейчас в работе: второй магазин и правила автоматического одобрения для самых простых заявок — по данным первых месяцев. Всё, что сложнее правила, по-прежнему открывает человек.

Контакты

Пришлите описание задачи

Ответ с объёмом работ, сроками и оценкой бюджета придёт в течение 24 часов.

Первый звонок — 30 минут, без обязательств с вашей стороны.