Мы создаём мобильные приложения для продуктовой доставки — одного из самых технически сложных сегментов. Представьте: клиент открывает приложение, видит 5000 товаров, добавляет молоко в корзину, а через минуту оно уже недоступно. Как избежать такого? Только синхронизация остатков в реальном времени с помощью WebSocket-событий. Большой каталог (тысячи позиций), управление остатками в реальном времени, замены товаров, сборка заказа на складе, логистика последней мили — каждый из этих блоков отдельная система. Наша задача — объединить их в единое целое, обеспечив стабильность и скорость работы.
Как обеспечить производительность каталога с тысячами позиций?
Первая проблема — производительность каталога. 5000+ SKU, поиск, фильтры по категориям, акциям, брендам. Наивная реализация — загрузить всё и фильтровать локально — не работает.
Правильный подход: серверная пагинация и фильтрация. Flutter + Flutter infinite_scroll_pagination: запрашиваем 20 позиций, при скролле до конца — следующие 20. Поиск — серверный, через PostgreSQL full-text search (tsvector + tsquery) или Elasticsearch для сложных запросов с опечатками (fuzzy search через Levenshtein distance).
Кеширование популярных категорий в Redis: главная страница с акциями и хитами продаж обновляется раз в 5 минут, а не при каждом запросе.
Остатки в реальном времени. Товар закончился на складе — он должен исчезнуть из каталога немедленно, не через следующую синхронизацию. Обновления остатков через WebSocket-событие или SSE (Server-Sent Events): клиент подписан на канал категории, сервер пушит изменения.
Пример реализации WebSocket-соединения
final wsUrl = Uri.parse('wss://example.com/socket'); final webSocket = await WebSocket.connect(wsUrl); webSocket.listen((message) { // Обработка события об остатках }); Что делать, если товара нет в наличии?
После оформления заказ уходит сборщику на складе. Приложение сборщика — отдельный Flutter-интерфейс: список позиций, сканирование штрихкода для подтверждения, отметка «нет в наличии» с предложением замены.
Замены — чувствительный момент. Сборщик предлагает замену → клиент получает push и должен подтвердить или отклонить. Таймаут 5 минут: если не ответил — применяется автозамена (аналог из той же категории) или позиция исключается из заказа с пересчётом суммы.
Этот flow требует: WebSocket между приложением сборщика и клиентским приложением, пересчёт суммы заказа на лету, push с высоким приоритетом (FCM High Priority, priority: high в payload).
Слоты доставки и логистика
Клиент выбирает слот: сегодня с 18 до 20, завтра с 10 до 12. Доступные слоты — это серверная логика: количество активных курьеров × ёмкость слота − уже занятые заказы. Не хардкод, а динамический расчёт.
Зоны доставки: полигоны в PostGIS. При вводе адреса проверяем, попадает ли точка в зону доставки (ST_Contains), и если да — показываем доступные слоты для этой зоны.
Трекинг курьера — координаты через WebSocket, маркер с анимацией на flutter_map. Расчётное время прибытия через Yandex Routes API с учётом пробок.
Программа лояльности и персонализация
Накопительные баллы — стандарт для продуктовой доставки. Но эффективнее работает персонализация: «Вы обычно заказываете молоко раз в неделю — оно у вас скоро закончится». Это не ML-магия, это простая аналитика по истории заказов: частота покупки товара × среднее время между заказами = дата следующего предполагаемого заказа. Push за день до этой даты.
Автозаполнение корзины: «Повторить прошлый заказ» — один тап, все позиции в корзине, недоступные — исключены, остальные — с актуальными ценами.
Типичные ошибки при разработке
Реализовывать корзину только на клиенте (SharedPreferences). При авторизации с нового устройства корзина теряется. Корзина должна жить на сервере, синхронизироваться с клиентом.
Забыть про возвраты. Клиент получил испорченный товар — должен быть flow в приложении: фото + описание → заявка на возврат → решение в течение 24 часов → возврат через ЮКасса API.
| Проблема | Решение |
|---|---|
| Корзина теряется при смене устройства | Серверная корзина с синхронизацией |
| Товар закончился — каталог не обновляется | WebSocket-события об остатках |
| Замена товара без подтверждения клиента | Push с таймаутом и автозамена |
| Слоты доставки переполнены | Динамический расчёт на основе PostGIS |
Стоимость разработки клиентского приложения начинается от нескольких миллионов рублей в зависимости от интеграций. Стоимость поддержки после запуска — фиксированная ежемесячная плата. Экономия до 40% за счёт использования Flutter вместо двух нативных команд.
Как мы это делаем: процесс и стек
- Аналитика и прототипирование (User Flow, архитектура)
- Дизайн — адаптивный под iOS и Android
- Разработка клиентского приложения (Flutter)
- Разработка приложения сборщика и курьерского приложения
- Веб-панель управления (Laravel)
- Интеграции: 1С, ЮКасса, SMS-шлюзы, логистические API
- Тестирование: unit, widget, integration тесты, нагрузочное тестирование
- Деплой в App Store и Google Play, прохождение модерации
- Техническая документация, обучение персонала, поддержка 2 месяца
Стек
Flutter 3.x + Bloc, Laravel 10 + WebSocket, PostgreSQL + PostGIS + Elasticsearch (для поиска), Redis, FCM, ЮКасса с поддержкой возвратов, Yandex MapKit + Yandex Routes API.
| Компонент | Срок разработки |
|---|---|
| Клиентское приложение (каталог, корзина, заказ, трекинг) | 16–20 нед. |
| Приложение сборщика | 6–8 нед. |
| Курьерское приложение | 8–12 нед. |
| Веб-панель управления | 8–12 нед. |
| Интеграции (1С, кассы, SMS) | 3–6 нед. |
Полный цикл разработки продуктовой доставки с нуля — от 28 до 40 недель в зависимости от объёма интеграций и требований к масштабированию. Мы имеем 7+ лет опыта в мобильной разработке и реализовали более 15 проектов в сфере доставки. Гарантируем стабильность и поддержку после запуска.
Оценим ваш проект бесплатно — свяжитесь с нами для консультации. Закажите разработку, и мы подготовим коммерческое предложение.







