Магазин в Telegram поверх МойСклада. Подключение — вечер, не проект
Владелец даёт поддомен, токен бота и токен МойСклада — и получает работающую витрину: каталог с остатками, корзину, заказы с резервом, бронирование и личный кабинет прямо в мессенджере. Товары не заводятся заново: каталог живёт в МойСкладе, платформа его зеркалит и продаёт.
У магазина уже есть учёт. Нет канала, в котором покупатель и так сидит
Небольшой розничный или оптовый магазин ведёт товары и остатки в МойСкладе. Продавать при этом приходится в переписке: клиент спрашивает «есть ли в наличии», менеджер идёт смотреть, называет цену, записывает заказ в блокнот и потом переносит его в учётную систему руками.
Дорого и долго для такого объёма
Интернет-магазин с интеграцией — это месяцы и бюджет, который не окупится на паре сотен позиций. А потом его ещё нужно кому-то поддерживать.
Забирает маржу и клиента
Комиссия, чужие правила и покупатель, который остаётся покупателем площадки, а не магазина.
Заказ живёт в голове менеджера
Остатки не резервируются, договорённости теряются, а вечером кто-то вручную переносит всё в учёт — и ошибается.
Канал, который уже открыт
Клиенту не нужно ставить приложение и регистрироваться. Он открывает бота, видит актуальные остатки и оформляет заказ, который сразу падает в учёт с резервом.
Тенант — это запись в базе, а не отдельная инфраструктура
Главное продуктовое решение платформы: новый магазин не требует ни своего контейнера, ни своего процесса бота, ни ручной настройки сервера. Подключение — одна команда, которая делает всё остальное сама.
Даёт поддомен, токен бота и токен МойСклада
Бот создаётся у @BotFather за минуту, токен МС берётся в настройках профиля. Секреты попадают в запись тенанта зашифрованными и никогда не лежат в конфигурации сервера.
Ставит вебхук Telegram с секретом в адресе
Бот работает только в webhook-режиме. Один общий пул процессов принимает апдейты всех магазинов и по секрету из адреса направляет их нужному боту — процесс на магазин не поднимается.
Настраивает МойСклад под себя
Заводит недостающие статусы заказа, дополнительные поля и вебхуки, выбирает организацию, склад и тип цены. Учётная система подстраивается под сервис, а не владелец под неё.
Импортирует ассортимент и включает синхронизацию
Товары, модификации, остатки и цены приезжают из МС. Дальше изменения прилетают вебхуками, а ночная сверка ловит то, что вебхук не донёс.
Витрина на поддомене, бот отвечает на /start
Дальше владелец сам собирает меню бота, правит категории витрины и анкеты заявок в кабинете — без разработчика.
Платформа хозяйничает в чужом аккаунте. Аккуратно
Провижининг — это когда сервис заходит в учётную систему клиента и создаёт там объекты. Одна ошибка здесь означает испорченные данные компании, поэтому механика разложена на четыре шага: спецификация желаемого, планировщик, применение и сверка.
Модель «подключился за вечер» проверялась на живом аккаунте
До реализации на пробном аккаунте МойСклада проверено, что создание статусов и дополнительных полей доступно, вебхуки есть на тарифе, а тип цены читается по нужному пути. Если у токена не хватает прав, владелец видит человеческое объяснение, а не трассировку стека.
Товар без категории не теряется
Папки МойСклада зеркалятся, правила маппинга сводят их в категории витрины. Непокрытая папка не ломает синхронизацию: товар приезжает без категории и попадает в очередь на разбор в админке. Ручная привязка помечается и синхронизацией не перетирается.
Резерв ведётся в учёте, а не в голове
Заказ и бронь — разные сущности для покупателя, но одинаковые для склада: и то и другое уезжает в МойСклад как «Заказ покупателя» с резервом позиций и различается служебным полем. Механика резервирования написана один раз.
Двойного заказа не будет
Перед созданием документа проверяется, не выгружен ли он уже, а в МойСклад передаётся локальный идентификатор синхронизации. Повторный вебхук, ретрай воркера или второе нажатие кнопки не создают дубль.
Товар держится ограниченное время
Бронирование живёт по таймеру: напоминание перед истечением, автоматическое снятие после, ограничение числа активных броней на клиента. Снятие возвращает остаток — тоже идемпотентно.
Менеджер работает в МойСкладе
Он меняет статус заказа в привычном интерфейсе, а бот сам сообщает клиенту, что заказ готов к выдаче. Отдельная панель для менеджера не нужна.
Меню бота собирается в админке
Дерево кнопок с автоответами, разделами и переходами в витрину — без правки кода и релиза. Кэшируется в Redis, поэтому меню открывается мгновенно.
Анкеты владелец собирает сам
Один и тот же набор шагов рендерится и диалогом в боте, и формой в витрине. Вопросы, порядок и обязательность настраиваются в кабинете.
Возможности собираются из точек применения
Оператор платформы конструирует тарифы в админке: какие функции входят в какой план. Новый тариф — это настройка, а не выкатка новой версии.
Один пул процессов, много магазинов, ноль утечек между ними
Изоляция арендаторов — то, на чём такие платформы ломаются тише всего: ошибка не падает, она просто показывает одному магазину товары другого. Поэтому резолв тенанта сделан сквозным, а не точечным.
Тенант определяется до первого обращения к данным
Веб-запрос — по поддомену, апдейт бота — по секрету в адресе вебхука, вебхук учёта — по своему секрету, фоновая задача — явным аргументом. Идентификатор кладётся в контекст корутины, и менеджеры моделей фильтруют выборки автоматически.
Состояния ботов не смешиваются
Один общий диспетчер обслуживает всех, но хранилище состояний разделено по идентификатору бота: два магазина с одним и тем же покупателем не путают его диалоги.
Свой ограничитель на каждый аккаунт учёта
Скользящее окно и счётчик параллельных запросов живут в Redis, поэтому лимит соблюдается поверх всех реплик. Активная синхронизация одного магазина не отнимает квоту у другого.
Шифрование на уровне поля с ротацией ключей
Токены бота и учётной системы шифруются при записи, ключ живёт вне базы. Поддерживается набор ключей: новый шифрует, старые ещё расшифровывают — ротация без простоя.
Вход проверяется, а не подразумевается
Личный кабинет и корзина доступны только изнутри Telegram: данные пользователя, которые присылает мессенджер, проверяются подписью. Открыть чужой кабинет по прямой ссылке нельзя.
196 тестов написаны на инварианты, а не на строки
Изоляция тенанта во всех точках входа, шифрование и ротация ключей, проверка подписи витрины, отсутствие записи у ресурсов ассортимента, идемпотентность заказа, специфичность правил категорий — каждое требование закрыто своим тестом.
Один образ, три роли
Веб, воркер и планировщик — это один и тот же образ с разными командами запуска. Меньше сборок, меньше расхождений между тем, что протестировано, и тем, что работает.
Продавайте там, где клиент уже есть
Если у бизнеса есть учётная система и переписка с клиентами, между ними почти всегда можно поставить работающий канал продаж — и он окупается быстрее, чем сайт. Делаю такие платформы целиком: от модели арендности до онбординга, который владелец проходит сам.
Похожие задачи в других отраслях
Каталог измерительной техники
Фасетный поиск с умным сужением, коммерческие предложения с печатью в PDF.
смотреть кейс → Финансы · виджетУправленческая отчётность для МойСклад
ОПиУ, движение денег и управленческий баланс из живых данных учётной системы.
смотреть кейс → Финансы · автоматизацияАвтопривязка платежей
Платёж сам привязывается к документу по одному из восемнадцати правил.
смотреть кейс →