Workspace Digital Awards — приём заявок открыт! Успейте номинироваться по самой низкой цене. Повышение цен с 1 октября.
Opulence
Приложение системы лояльности для сети кофеен Долина Кофе
Opulence
#Приложение под ключ #Иллюстрации#Брендинг

Приложение системы лояльности для сети кофеен Долина Кофе

31 
Opulence Россия, Москва
Поделиться: 0 0 0
Сфера

HoReCa и еда

Сдано

Сентябрь 2026

Задача

Dolina Coffee это сеть кофеен. Бонусы гостей живут в iiko: касса считает баллы, кассир видит карту, гость получает кэшбек. Программа работает, но существует она только внутри кассы.

Гость вне кофейни не знает ничего. Сколько у него баллов, какой у него статус, когда он был в последний раз. Чтобы узнать баланс, нужно прийти и спросить на кассе.

У сети та же слепота с другой стороны. Менеджер видит выручку и чеки, а вот кто из постоянных гостей перестал ходить, уже нет. Гость просто исчезает, и заметить это некому.

Нам заказали три вещи сразу: приложение гостя с картой и балансом, инструмент менеджера для работы с уходящими гостями и бэкенд, связавший это с iiko.

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

Решение

Собрали три независимых продукта с общим бэкендом:

  1. PWA гостя: вход через VK ID, карта с QR, баланс, история, уровни, дистанционный заказ.

  2. Бэкенд: прокси к iiko, собственный журнал операций, вебхуки, ночная синхронизация, аналитика.

  3. Админ-панель: задания менеджерам, недельная аналитика, OLAP-отчёты, выгрузки.

  4. Импорт исторических данных из iikoWeb со сведением личности гостя.

  5. Алгоритм поиска гостей под риском по их личному ритму визитов.

Вход в один тап и отказ от регистрации в приложении

Гость заходит через VK ID: один тап, PKCE, секрет в браузере не нужен. VK возвращает код и идентификатор устройства, бэкенд меняет их на номер телефона, по номеру ищется карта в iiko.

Дальше отдельное решение. Регистрацию карты мы в приложение не понесли. Незарегистрированный гость видит экран «приходите в кофейню».

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

Карта, QR и три уровня

Главный экран это карта лояльности. QR с треком карты, кассир сканирует его в iikoFront. Рядом баланс, размер кэшбека, условия программы.

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

Уровней три. СТАНДАРТ с серебряной обводкой аватара есть у всех. ПРЕТЕНДЕНТ НА ПРО с бронзовой обводкой даётся за 7 визитов в течение 30 дней и держится до конца текущего месяца и весь следующий. ПРО с золотой обводкой даёт кэшбек 15% и остаётся навсегда.

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

Свой журнал операций

iikoCloud отдаёт баланс, но не отдаёт историю транзакций. А профиль гость открывает именно ради истории.

Пришлось вести собственный журнал: он наполняется вебхуками iiko и нашими же вызовами пополнения и списания. Хранилище простое, файл на томе Docker, потому что источник истины всё равно в iiko, а журнал играет роль витрины.

Сбор истории: импорт и сведение личности

Журнал решает задачу вперёд. Но вебхуки копят данные только с момента подключения, а список прошлых заказов через Transport API получить нельзя. Сеть работала годы, и вся эта история осталась бы за бортом.

Историю залили импортом «Журнала операций» из iikoWeb в формате xlsx. Там своя сложность: гость в выгрузке известен только по номеру телефона, без идентификатора iiko.

Решение неочевидное, зато аналитика заработала сразу на исторических данных. Иначе их пришлось бы копить месяцами.

Ночная синхронизация и щадящий пул

Push-вебхуки iiko оказались ненадёжными: часть событий не доходит. Строить недельную аналитику на потоке с пропусками нельзя.

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

Пул запросов намеренно щадящий. Резкий всплеск обращений к iiko приводит к бану IP, и тогда встаёт весь сервис. Скорость синхронизации здесь стоит дешевле доступа.

Две авторизации в iiko

У iiko два разных флоу получения токена: обычный ресторанный ключ и partner-доступ через marketplace. Какой достанется на конкретном объекте, заранее неизвестно.

Клиент к iiko поддерживает оба и выбирает по набору переменных окружения. Токен кэшируется на час и обновляется сам. Переезд между типами доступа не требует правок в коде.

Задания менеджеру: гость молчит дольше обычного

Самая содержательная часть проекта это правило отбора гостей для звонка.

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

Сравниваем другое: насколько долго гость молчит относительно своего обычного интервала между визитами.

Алгоритм считает по каждому гостю медианный разрыв между визитами за 90 дней. Затем смотрит, сколько дней прошло с последнего визита. Гость попадает в группу риска, если молчит дольше полутора своих обычных интервалов. Отдельный пол в четыре дня защищает ежедневных гостей: человека, заходящего каждое утро, не дёргают из-за пары пропущенных дней.

Гости с числом визитов меньше четырёх за окно отсеиваются: ритма у них нет, оценивать нечего.

Отдельно решается когорта. Её берут по обычной частоте гостя, минуя просевший счётчик визитов. Иначе затихший завсегдатай утёк бы в мелкий сегмент из-за самого факта тишины. То есть выпал бы из списка ровно тогда, когда он там нужнее всего.

Ёмкость обзвона и кулдаун

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

Кулдаун считается по факту взаимодействия. Позвонили гостю, пауза две недели. Показали в списке, но до звонка не дошло, пауза неделю. Так один и тот же человек не попадает в обзвон каждую неделю, а поток задач ровно распределяется.

К каждой задаче прикладываются любимый напиток и блюдо гостя. Они собираются автоматически из OLAP-отчёта «кто что купил». Менеджеру важно, с чем звонить, и «ваш латте и círка» работает лучше, чем «мы заметили, что вы давно не заходили».

Причина звонка формулируется человеческим языком: «Обычно заходит раз в 5 дн., не был уже 9 дн.». Для ежедневных гостей формулировка меняется на «Заходил почти каждый день».

Логика отбора живёт отдельно от базы

Правило поиска кандидатов вынесено в отдельный модуль без единого обращения к базе: на вход карта визитов и карта трат, на выходе список кандидатов.

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

Аналитика по сегментам частоты

Гости, чеки и средний чек разложены по сегментам частоты визитов: 7+, 6, 5, 4, 3, 2, 1. На графике шесть недель, текущая выделена, пять прошлых серые.

Неделя выбирается барабаном. Недели без данных и будущие недоступны: выбрать пустой период просто нельзя.

Дистанционный заказ за флагом

Панель заказа собрана целиком: любимые позиции гостя сверху, ниже меню по категориям, корзина внизу. Работает через внешнее меню iiko.

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

Результат

Результат

Dolina Coffee получила программу лояльности с приложением для гостя и инструментом для менеджера. Учёт баллов остался в iiko, расхождений между кассой и приложением нет по построению.

Гость видит баланс, статус, историю и QR для кассы. Менеджер получает недельный список гостей под риском с причиной звонка и любимыми позициями. Аналитика по сегментам частоты визитов строится на полной истории, включая период до запуска приложения.

Собственная разработка заняла около трёх недель от первого коммита до продакшена.

https://dolina-coffee.ru

Стек технологий


Оцените кейс
Спасибо за оценку
Выскажите мнение
Авторизуйтесь, чтобы добавить свой комментарий.
оставить заявку

Хотите заказать похожий проект?

Opulence с удовольствием обсудит вашу задачу

Оставить заявку