На сайте лежит рабочий магазин в Telegram: каталог с корзиной, админка владельца и демо-парсер. Это не запись экрана и не макет — заказы падают в настоящую базу. Ниже разобрано, из чего оно собрано и почему сделано именно так.
Демо у разработчика — обычно красивая картинка, по которой невозможно понять, что внутри. А разница между приложением, которое переживёт первую тысячу заказов, и тем, которое рассыплется на второй неделе, лежит именно внутри, и снаружи не видна вообще.
Поэтому здесь честный разбор: какие решения приняты, почему, и где я сама ошиблась. Заодно это готовый список вопросов, которые стоит задать любому разработчику, — не только мне.
Одна страница на обычном HTML, CSS и JavaScript. Ни React, ни сборки. Приложение открывается за доли секунды даже на слабом телефоне и в метро.
Python без внешних библиотек и SQLite. Держит нагрузку небольшого магазина, занимает считаные мегабайты и не требует обслуживания.
Отдельная страница в браузере: добавить товар, поправить цену и остаток, сменить статус заказа, выгрузить всё в Excel.
nginx с сертификатом и systemd. Служба поднимается сама после перезагрузки сервера и переживает падение.
Выбор в пользу простого стека здесь сознательный. Магазину на полсотни позиций фреймворк не даёт ничего, кроме мегабайтов, которые покупатель будет ждать на плохой связи, и зависимостей, которые через год потребуют обновления. Когда проект вырастет до тысяч товаров и складского учёта — стек будет другой, и я скажу об этом прямо.
Всё, что происходит в приложении, происходит на устройстве покупателя. Любое число там можно подменить — цену, скидку, стоимость доставки, — и для этого достаточно бесплатных инструментов, встроенных в браузер.
Поэтому приложение отправляет на сервер только номера товаров и количество. Ни цен, ни итога — их сервер берёт из своей базы и считает сам. Цифры на экране существуют исключительно для человека.
Проверить это можно за минуту на любом магазине: откройте инструменты разработчика, поменяйте цену в запросе и оформите заказ. Если сервер согласился с вашей ценой — магазин можно обворовать через браузер. Такое встречается чаще, чем кажется.
При запуске мессенджер передаёт приложению строку с данными пользователя и криптографической подписью, вычисленной с помощью токена бота. Сервер повторяет вычисление своим токеном и сравнивает результат. Совпало — перед нами действительно этот человек, и никакой регистрации не нужно.
Это важно там, где приложение показывает личные данные. В демо есть экран «Мои заказы»: кто его спрашивает — решает подпись, а не идентификатор из запроса. Разница принципиальная. Если доверять параметру, любой желающий подставит чужой номер и прочитает чужие заказы с адресами и телефонами — классическая утечка, которая стоит владельцу магазина куда дороже, чем разработка.
В демо работает настоящий приём оплаты. Покупатель нажимает «Оплатить картой», и окно оплаты рисует сам Telegram: карта у него уже привязана к аккаунту, реквизиты вводить не нужно. Провайдер подключён тестовый — окно настоящее, деньги не списываются.
Важное здесь — где считается сумма. Счёт выставляет сервер по номеру заказа, беря сумму из базы. Приложение не может попросить счёт на другую сумму, а чужой заказ не оплатит: сервер сверяет, тому ли человеку он принадлежит, по всё той же подписи Telegram.
И отдельный момент, на котором спотыкаются почти все, кто делает оплату впервые: перед списанием Telegram присылает боту запрос-предпроверку и ждёт ответа десять секунд. Не ответил — платёж отменяется, причём молча, и разработчик долго ищет причину. В этот момент правильно ещё раз сверить сумму счёта с базой: счёт мог быть создан полчаса назад, а заказ с тех пор изменился.
Заказ не пропадает в базе. Владельцу приходит сообщение в Telegram, а когда он меняет статус в админке — покупателю прилетает уведомление от бота: «Оплачен», «Собираем», «Курьер выехал», «Доставлен». Тот же статус виден в приложении, в разделе «Мои заказы».
Круг замкнут: приложение → база → админка → покупатель. Именно этого чаще всего не хватает в самописных магазинах — заказы принимаются, а человек потом гадает, случилось ли что-нибудь.
Это главный аргумент в пользу формата, и в демо он показан на живых примерах, а не на словах.
| Возможность | Что видит покупатель |
|---|---|
| Облачное хранилище | Набрал корзину на телефоне — открыл на компьютере, товары на месте. Избранное тоже переезжает: оно привязано к аккаунту, а не к браузеру |
| Номер телефона | Кнопка «Взять из Telegram» вместо ручного ввода. Мессенджер спрашивает согласие сам, отдельным окном |
| Родная кнопка | Кнопка оплаты рисуется самим Telegram внизу экрана, а не приложением. Выглядит и ведёт себя как в системных приложениях |
| Стрелка «назад» | Появляется в шапке мессенджера на вложенных экранах и закрывает именно тот, что открыт |
| Отдача в вибрацию | Короткий отклик на добавление товара, отдельный — на успешный заказ и на ошибку |
| Оплата | Окно оплаты рисует мессенджер, карта уже привязана к аккаунту. Никаких «введите номер карты» и переходов на сторонний сайт |
| Кто это | Приложение знает человека без регистрации, паролей и подтверждения почты |
Отсюда простое правило выбора: если покупателю нужно завести аккаунт, запомнить пароль и подтвердить почту — половина уйдёт на первом же шаге. В Telegram этих шагов нет вообще.
Вне мессенджера всё это молча отключается, и демо продолжает работать как обычная страница — открытое в браузере, оно рисует вокруг себя рамку телефона. Так его можно показать человеку, у которого Telegram не установлен.
В демо действуют промокоды. И первая же версия вела себя дико: покупатель вводил код на скидку, а итог вырастал — с 1 630 до 1 717 ₽ вместо ожидаемых 1 467.
Причина оказалась не в арифметике скидки, а в порядке действий. Бесплатная доставка полагалась от 1 500 ₽, и порог проверялся после вычитания скидки. Скидка роняла сумму ниже полутора тысяч, доставка за 250 ₽ возвращалась, и она перекрывала выигрыш.
Лечится одной строкой: порог считается от стоимости товаров до скидки. Показательно тут другое — код был написан правильно, тесты на скидку проходили, и поймать это можно было только оформив настоящий заказ с промокодом на пограничную сумму. Поэтому в приёмке всегда есть проверка живым заказом, а не только осмотром экранов.
Подробный разбор с цифрами — в отдельной заметке.
Каталог с категориями, поиском и избранным, карточка товара, корзина с промокодом, оформление заказа, оплата картой, история заказов.
работает сейчас АдминкаДобавьте товар или поменяйте цену — и обновите магазин в соседней вкладке. Правка появится там за несколько секунд.
работает сейчас Парсер каталогаСбор товаров с сайта с настройками: сколько страниц, диапазон цен, минимальный рейтинг, только в наличии, сортировка.
Заказы из демо приходят мне в Telegram, так что оформленный вами тестовый заказ я увижу. Это, собственно, и есть демонстрация: так же он будет приходить владельцу магазина.
Нет. Всё внутри приложения работает на устройстве покупателя, и подменить там можно любое число. Настоящую сумму сервер обязан пересчитать сам, взяв цены из своей базы и приняв от клиента только номера товаров и количество. Если разработчик говорит, что этого достаточно на стороне приложения, — это повод насторожиться.
Telegram передаёт при запуске данные пользователя вместе с криптографической подписью, вычисленной по токену бота. Сервер повторяет вычисление и сравнивает результат. Идентификатор, пришедший обычным параметром запроса, доверия не заслуживает: его подставит кто угодно.
Хранить корзину и избранное в облаке мессенджера с привязкой к аккаунту, а не к браузеру. Получать номер телефона по кнопке, с согласия человека. Показывать родную кнопку Telegram, стрелку «назад» и отвечать вибрацией. И знать посетителя без регистрации и паролей.
Настоящее. Заказы попадают в реальную базу, админка меняет каталог, правки видны в магазине через несколько секунд. Каталог возвращается к исходному состоянию раз в час, чтобы посетители не мешали друг другу.
Да, и в демо это работает на тестовом провайдере: окно оплаты рисует сам Telegram, покупатель не вводит реквизиты — карта уже привязана к его аккаунту. Для настоящего магазина нужен договор с платёжным провайдером, его подключают в BotFather, а деньги идут на ваш счёт, минуя разработчика. Со стороны приложения важно, чтобы счёт выставлял сервер по номеру заказа и сверял сумму с базой перед списанием.
От 13 000 ₽, срок 7–14 дней. От вас — список товаров с ценами и фотографии. Приём оплаты, выгрузка в CRM и синхронизация с 1С считаются отдельно, потому что это отдельная работа.
Тогда я так и скажу. Заявки, запись и уведомления отлично живут в боте и стоят дешевле — от 2 500 ₽. Mini App нужен там, где есть каталог и заказы: когда позиций больше десятка, переписка превращается в мучение.
Хотите такое же приложение под свой товар? Покажите задачу — скажу срок, цену и честно предупрежу, если вам хватит обычного бота.
Написать в Telegram @vvs35_bot