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

Статья написана для тех, кто заказывает сервис или оценивает чужой проект. Что мы делаем для заказчика и сколько это стоит, описано на странице «Разработка сервиса бронирования и аренды», здесь только устройство.

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

Что именно бронируется: пять вопросов до первой строки кода

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

ВопросЧто значит ответ для сервиса
Что занимается: время, предмет или место?Время хранится диапазоном, предмет единицей парка, место счётчиком свободных мест на событии
Длительность фиксирована или выбирается?Фиксированную длину легко разложить на слоты, выбираемую приходится проверять на пересечение диапазонов
Нужен ли исполнитель вместе с ресурсом?Если для записи нужны мастер и кресло одновременно, занятость проверяется по двум расписаниям сразу
Есть ли время между бронями?Уборка, подготовка или проверка предмета — это буфер, который тоже занимает ресурс
Кто может менять бронь?Клиент сам, только администратор или оба; от этого зависят права и журнал изменений

Ответы записываются в документ до начала работ. Если вы отвечаете «и так, и так» на несколько вопросов подряд, это сигнал, что сервис придётся делить на этапы: сначала один тип ресурса, потом остальные.

Как хранить занятость: сетка слотов или диапазоны

Есть два способа, и выбор влияет на всё остальное.

ПодходКак работаетПлюсМинус
Сетка слотов заранееДля каждого дня создаются записи «10:00–10:30», «10:30–11:00», клиент занимает одну или несколькоПростой поиск свободного, понятный интерфейсСетку нужно создавать и пересоздавать при смене расписания; услуга длиннее слота растекается по нескольким записям
Диапазоны и проверка пересеченияБронь хранится как «ресурс, начало, конец»; свободное время вычисляется как промежутки между бронямиЛюбая длительность, нет сетки для обслуживания, буферы встраиваются естественноПоиск свободного сложнее, нужен индекс по ресурсу и времени

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

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

Защита от двойной брони: три слоя

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

СлойЧто делаетОт чего защищаетЧего не защищает
Удержание с таймеромПосле выбора времени бронь переходит в состояние «удержана» на срок оплаты и снимается самаОт продажи времени, пока другой клиент платитОт одновременного нажатия двумя клиентами
Проверка и запись в одной транзакцииПроверка свободного времени и создание брони выполняются одной операцией, соседние запросы ждут очередиОт гонки двух запросовОт ошибки в коде в обход этой операции
Ограничение в базеPostgreSQL запрещает пересекающиеся диапазоны одного ресурса на уровне схемыОт любых ошибок кода, включая будущиеОт неверно заданных границ диапазона

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

Что делать, если оплата пришла после снятия удержания

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

Оплата: что учесть при предоплате, залоге и возврате

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

  • Бронь подтверждается по уведомлению провайдера, а не по возврату клиента на страницу сайта. Клиент может закрыть вкладку после оплаты, и тогда без уведомления бронь останется удержанной.
  • Уведомление может прийти дважды. Обработчик устроен так, что повтор ничего не меняет: платёж привязан к брони, и повторное сообщение не создаёт вторую.
  • Залог зависит от возможностей эквайринга. Если провайдер умеет блокировать сумму на карте, залог блокируется и снимается после возврата предмета. Если нет, залог вносится отдельным платежом и возвращается отдельной операцией.
  • Частичный возврат считает сервер. Сумма берётся из правила отмены, администратор видит расчёт и может изменить его, оставив причину.
  • Чеки формирует онлайн-касса или сервис фискализации, с которым у вас договор. Признаки расчёта определяет бухгалтер.

Правила отмены и переноса как данные

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

Что записаноПример условияЧто делает сервис
Срок бесплатной отменыЗа 24 часа до началаПоказывает клиенту оставшееся время и сразу возвращает всю сумму
Удержание при поздней отменеЧасть суммы или предоплата целикомРассчитывает возврат и показывает его до подтверждения
НеявкаВремя считается оказаннымЗакрывает бронь через заданное время после начала и применяет правило
ПереносОдин раз и не позднее чем за суткиОсвобождает старое время и занимает новое одной операцией
Отмена по вине площадкиИсполнитель недоступен, предмет неисправенВозвращает всё и не применяет штраф, записывает причину

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

Расписание, часовые пояса и цена

Три обстоятельства ломают уже работающие сервисы при росте.

  • Время хранится в едином стандарте, показывается по поясу площадки. Если площадки в разных регионах, клиент бронирует по местному времени площадки, а в письме и календаре стоит тот же пояс с пометкой. Ошибка здесь заметна не сразу, а в день брони.
  • Брони через полночь и границы суток. Аренда на ночь или с вечера до утра не помещается в календарный день, и модель «бронь принадлежит дню» ломается. Бронь принадлежит ресурсу и диапазону.
  • Цена зависит от времени. Сезон, выходные, длительность и пакеты считаются на сервере и фиксируются в брони при создании. Если цену пересчитывать по текущему прайсу, закрытые брони «меняют» стоимость задним числом.

Для аренды предметов добавляются состояние предмета, ремонт и комплектность. Предмет, отправленный на ремонт, блокируется как отдельная «бронь» без клиента, поэтому поиск свободного его не предлагает.

Напоминания, календарь и неявки

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

Бронь выгружается в календарь клиента файлом формата iCal. Исполнитель видит расписание в адаптивном интерфейсе на телефоне, а при желании его личный календарь подключается на чтение, чтобы запись не попадала на личные дела. Это отдельная задача, и в первую версию её лучше не включать.

Что проверить до запуска

Сервис бронирования проверяют не только «кнопкой в браузере». Обязательные проверки:

  1. Десятки одновременных попыток занять одно время: прошла ровно одна.
  2. Таймер удержания: оплата не пришла, время освободилось; оплата пришла после снятия, сработало выбранное правило.
  3. Повторное уведомление провайдера не создаёт вторую бронь и не меняет сумму.
  4. Отмена в каждой точке правил: за секунду до границы и сразу после неё.
  5. Часовые пояса: площадка в одном регионе, клиент в другом, бронь на границе суток.
  6. Права: клиент не открывает чужую бронь, подбирая номер в адресной строке.
  7. Отказ внешних сервисов: провайдер оплаты и SMS недоступны, бронь остаётся в понятном состоянии.

Если подрядчик на вопрос о двойной брони отвечает «проверяем в интерфейсе», считайте это признаком слабой защиты и спрашивайте про ограничение в базе и тесты гонки. Другие вопросы подрядчику собраны в статье «Как выбрать подрядчика на разработку ПО».

Что делаем мы и с чего начать

Начинаем с обследования: 200 000 ₽ и 2–3 недели за одну площадку и одну-две системы, 350 000 ₽ и 3–4 недели для сети площадок и нескольких систем. На выходе документ с моделью занятости, состояниями брони, правилами отмены, схемой оплаты и вилкой бюджета. Стоимость вычитается из первого этапа, если продолжаете с нами, а документом можно пользоваться и без нас.

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

Частые вопросы

Как сделать сервис бронирования, чтобы не было двойных броней?

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

Чем бронирование слота отличается от аренды предмета?

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

Сколько времени держать бронь до оплаты?

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

Что делать, если клиент оплатил, а время уже занято?

Заранее выбранное правило: если время ещё свободно, бронь подтверждается, если нет, деньги возвращаются автоматически, а клиент получает предложение выбрать другое время. Решение не должно приниматься вручную в каждом случае.

Можно ли обойтись готовым конструктором онлайн-записи?

Можно, пока слоты фиксированной длины, одно правило отмены и стандартная предоплата. Когда появляются залог, парк с комплектами, сезонная цена, сеть площадок или требование хранить данные у себя, конструктор упирается в потолок.

Принимает ли сервис платежи и хранит ли данные карт?

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

Нужно ли мобильное приложение для бронирования?

Часто достаточно адаптивного веб-сервиса с установкой на экран телефона. Нативные приложения для iOS и Android мы не делаем, и для большинства сценариев записи и аренды они не обязательны.

Сколько стоит разработка сервиса бронирования?

Обследование — 200 000 ₽ или 350 000 ₽ для сети площадок. Пилот одного сценария — 150 000–400 000 ₽, первая версия — 400 000–1 200 000 ₽ за 2–3 месяца, вывод в эксплуатацию — от 1 500 000 ₽ этапами по 300 000–700 000 ₽. Обследование вычитается из первого этапа, если продолжаете с нами.