Разработка сайта ресторана на 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка сайта ресторана на 1С-Битрикс
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Разработка сайта ресторана на 1С-Битрикс

Сайт ресторана — это не визитка с адресом и фотографией зала. Это система, через которую проходят заказы на доставку, бронирования столиков, обновления меню и синхронизация с кассой. Всё это завязано на инфоблоки, REST API кассовых систем и кастомные компоненты. Если на старте не продумать связку между инфоблоком меню и POS-системой, через три месяца окажется, что официант добавил новую позицию в iiko, а на сайте её нет — потому что синхронизация работает в одну сторону, и никто не написал обратный обработчик.

Инфоблок «Меню»: структура данных

Меню ресторана — это инфоблок с разделами-категориями и элементами-блюдами. Разделы: «Завтраки», «Салаты», «Горячее», «Десерты», «Напитки», «Винная карта». Вложенность — один уровень, для подкатегорий (например, «Красное вино» внутри «Винная карта») используется второй уровень разделов.

Свойства элемента (блюда):

  • WEIGHT — числовое, грамм. Выводится на карточке и в Schema.org разметке
  • CALORIES — числовое, ккал. Опционально — расширенный блок: белки, жиры, углеводы (три отдельных свойства PROTEINS, FATS, CARBS)
  • ALLERGENS — множественный список: глютен, лактоза, орехи, морепродукты, яйца, соя. Фильтрация по аллергенам через CIBlockElement::GetList() с PROPERTY_ALLERGENS в фильтре
  • PRICE — числовое. Не через модуль catalog, если не нужна корзина — обычное свойство инфоблока. Если нужна онлайн-оплата — подключение к торговому каталогу через CCatalog::Add()
  • PHOTO — файл. Основное фото блюда. Дополнительные фото — множественное свойство MORE_PHOTOS
  • IS_NEW — чекбокс. Отметка «Новинка» для выделения в списке
  • IS_SPICY — чекбокс. Пометка острого блюда
  • STOP_LIST — чекбокс. Блюдо временно недоступно (закончился ингредиент). Элемент не удаляется, а скрывается по фильтру в шаблоне компонента
  • SORT_ORDER — числовое. Порядок внутри раздела, позволяет шеф-повару через админку выставить фирменные блюда первыми

Для ресторанов с сезонным меню добавляется свойство SEASON (множественный список: весна, лето, осень, зима) и фильтрация по текущему сезону в component.php.

Онлайн-заказ и интеграция с POS-системами

Это технически самая нагруженная часть проекта. Ресторан работает с кассовой системой — iiko, r_keeper или Poster. Сайт должен не просто принимать заказы, а передавать их в кассу в реальном времени и получать обратную связь: подтверждение, время приготовления, статус.

Архитектура взаимодействия с iiko:

iiko предоставляет iiko Transport API (ранее iiko Biz API). Авторизация — по apiLogin, получение токена через POST /api/1/access_token. Токен живёт 60 минут, кешируется в $_SESSION или в Highload-блоке с TTL.

Создание заказа — POST /api/1/deliveries/create. Тело запроса содержит:

{
  "organizationId": "...",
  "order": {
    "phone": "+375...",
    "orderTypeId": "...",  // delivery или self-pickup
    "items": [
      {
        "productId": "iiko-product-uuid",
        "amount": 2,
        "modifiers": [...]
      }
    ],
    "address": {
      "street": "...",
      "house": "...",
      "flat": "..."
    },
    "comment": "Без лука"
  }
}

Критический момент — маппинг productId. В инфоблоке Битрикс у каждого блюда хранится свойство IIKO_PRODUCT_ID (строка, UUID из iiko). При синхронизации меню через GET /api/1/nomenclature загружается полный каталог iiko и сопоставляется с элементами инфоблока по этому UUID. Синхронизация запускается агентом CAgent раз в 15 минут или по вебхуку из iiko.

Что синхронизируется из iiko в Битрикс:

  • Наличие блюда (stop-лист). iiko отправляет POST на webhook-endpoint /api/iiko-stoplist/. Обработчик обновляет свойство STOP_LIST у соответствующего элемента инфоблока через CIBlockElement::SetPropertyValuesEx()
  • Цена. Если ресторан меняет цены в кассе, они должны приехать на сайт. Обработчик в агенте сравнивает цены из /api/1/nomenclature с PRICE в инфоблоке и обновляет расхождения
  • Модификаторы (добавки, гарниры). Хранятся в отдельном инфоблоке «Модификаторы» со свойством IIKO_MODIFIER_ID

Что отправляется с сайта в iiko:

  • Заказ с позициями, адресом, комментарием
  • Тип оплаты (онлайн или при получении)
  • Промокод, если есть — скидка рассчитывается на стороне iiko

Интеграция с r_keeper:

r_keeper использует UCS DeliveryPOS API. Принцип аналогичен, но протокол — XML-RPC вместо JSON REST. Запросы обёрнуты в XML-конверт, ответы парсятся через SimpleXMLElement. Маппинг товаров — по MenuItemID. Основная сложность — r_keeper требует VPN-туннель к серверу ресторана, тогда как iiko работает через облако.

Интеграция с Poster POS:

Poster предоставляет REST API с OAuth-авторизацией. Создание заказа — POST /api/incomingOrders.createIncomingOrder. Poster проще в интеграции: JSON API, облачное развёртывание, webhook для обновления статуса заказа. Маппинг — по product_id из Poster.

Обработка статусов заказа:

После создания заказа в POS сайт должен отслеживать статус. Два подхода:

  1. Polling — агент или cron-задача раз в 60 секунд опрашивает API кассы по orderId. Статусы: «Принят», «Готовится», «В пути», «Доставлен». Обновляет свойство STATUS в Highload-блоке «Заказы»
  2. Webhook — POS отправляет POST на /api/order-status/ при смене статуса. Предпочтительный вариант для iiko и Poster, но не всегда доступен для r_keeper

Статус отображается клиенту на странице /my-orders/ через AJAX-опрос каждые 30 секунд или через WebSocket (если инфраструктура позволяет).

Бронирование столиков

Кастомный компонент project:table.reservation с формой: дата, время, количество гостей, имя, телефон, комментарий.

Логика бронирования:

  • Данные записываются в Highload-блок «Бронирования»: DATE, TIME, GUESTS, NAME, PHONE, STATUS, TABLE_ID
  • Столики — отдельный Highload-блок: TABLE_NUMBER, CAPACITY, ZONE (зал, терраса, VIP)
  • При бронировании компонент проверяет доступность: выборка из Highload-блока бронирований по DATE + TIME с окном ±2 часа, сопоставление с вместимостью свободных столиков
  • Если свободных столиков нет — предложение ближайшего доступного времени

Интеграция с CRM Битрикс24:

Каждое бронирование создаёт лид через CRest::call('crm.lead.add', [...]). Параметры:

$leadData = [
    'TITLE' => 'Бронь столика: ' . $date . ' ' . $time,
    'NAME' => $name,
    'PHONE' => [['VALUE' => $phone, 'VALUE_TYPE' => 'WORK']],
    'SOURCE_ID' => 'WEB',
    'UF_CRM_TABLE' => $tableNumber,
    'UF_CRM_GUESTS' => $guests,
    'COMMENTS' => $comment
];
CRest::call('crm.lead.add', ['fields' => $leadData]);

Хостесс видит бронирования в CRM и подтверждает их. Статус лида «Подтверждено» → обработчик обновляет STATUS в Highload-блоке → клиенту приходит SMS через модуль messageservice или через внешний SMS-шлюз.

Фотогалерея и оптимизация изображений

Фуд-фотография — тяжёлые файлы. Исходники от фотографа — 5-10 МБ на снимок. На сайте нужны три размера: thumbnail для списка меню (400x300), средний для карточки блюда (800x600), full-size для лайтбокса (1600x1200).

Ресайз через CFile::ResizeImageGet() с BX_RESIZE_IMAGE_PROPORTIONAL. Результат кешируется в /upload/resize_cache/. Для WebP — конвертация через imagewebp() в обработчике OnBeforeFileResize или через Nginx-модуль ngx_http_image_filter_module.

srcset для Retina-дисплеев:

<img
  src="/upload/resize_cache/menu/800x600/dish.webp"
  srcset="/upload/resize_cache/menu/400x300/dish.webp 400w,
          /upload/resize_cache/menu/800x600/dish.webp 800w,
          /upload/resize_cache/menu/1600x1200/dish.webp 1600w"
  sizes="(max-width: 640px) 400px, (max-width: 1024px) 800px, 1600px"
  loading="lazy"
  alt="Название блюда"
>

Атрибут loading="lazy" — нативная ленивая загрузка. Для старых браузеров — IntersectionObserver в JS. На странице меню с 50+ блюдами это экономит 30-40 МБ начальной загрузки.

Mobile-first: 80% трафика с телефонов

Ресторанный сайт ищут с телефона — «ресторан рядом», «меню доставки». Шаблон строится mobile-first:

  • Меню категорий — горизонтальный скролл с overflow-x: auto, не выпадающий список
  • Карточка блюда — фото на всю ширину, название, вес, цена. Кнопка «Добавить» зафиксирована внизу экрана через position: sticky
  • Форма заказа — минимум полей. Телефон + адрес. Имя и комментарий — опционально. Автозаполнение адреса через Dadata API (POST https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address)
  • Форма бронирования — нативные <input type="date"> и <input type="time"> вместо кастомных datepicker-ов

Адаптивность — CSS Grid + Flexbox в шаблоне компонента. Breakpoint-ов три: 375px (телефон), 768px (планшет), 1280px (десктоп). Тестирование через Lighthouse: целевые показатели Performance > 90, LCP < 2.5s.

Мультиязычное меню

Для ресторанов в туристических зонах — меню на нескольких языках. В 1С-Битрикс мультиязычность реализуется через:

  • Отдельный сайт в системе многосайтовости (LID = s1 для русского, s2 для английского). Инфоблоки привязаны к обоим сайтам, свойства NAME_EN, DESCRIPTION_EN — дополнительные текстовые свойства
  • Или через свойство LANGUAGE (список: ru, en, de) и фильтрацию в компоненте по текущему языку LANGUAGE_ID

Первый вариант надёжнее: разные URL (/menu/ и /en/menu/), корректные hreflang-теги, независимые SEO-настройки.

Schema.org: Restaurant + Menu

В result_modifier.php формируется JSON-LD разметка:

{
  "@context": "https://schema.org",
  "@type": "Restaurant",
  "name": "Название ресторана",
  "servesCuisine": "Итальянская",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "...",
    "addressLocality": "Минск"
  },
  "openingHoursSpecification": [...],
  "menu": {
    "@type": "Menu",
    "hasMenuSection": [
      {
        "@type": "MenuSection",
        "name": "Горячее",
        "hasMenuItem": [
          {
            "@type": "MenuItem",
            "name": "Стейк рибай",
            "description": "...",
            "nutrition": {
              "@type": "NutritionInformation",
              "calories": "850 cal"
            },
            "offers": {
              "@type": "Offer",
              "priceCurrency": "BYN"
            }
          }
        ]
      }
    ]
  }
}

Разметка выводится через $APPLICATION->AddHeadString(). Типы Restaurant, Menu, MenuItem — отдельные сущности Schema.org, Google распознаёт их для Rich Snippets в поисковой выдаче.

Акции и спецпредложения

Инфоблок «Акции» (тип promotions). Свойства: DATE_START, DATE_END, PROMO_TYPE (бизнес-ланч, happy hour, сезонное), DISCOUNT_PERCENT, LINKED_DISHES (множественная привязка к элементам инфоблока «Меню»).

Вывод на главной через news.list с фильтром по датам: >=DATE_START и <=DATE_END относительно текущей даты. Истекшие акции автоматически скрываются без участия администратора.

Для бизнес-ланча — отдельный раздел меню с ограничением по времени: компонент проверяет серверное время и показывает блок «Бизнес-ланч» только с 12:00 до 16:00.

Мероприятия ресторана

Инфоблок «Мероприятия» — для анонсов: живая музыка, тематические вечера, дегустации. Свойства: EVENT_DATE, EVENT_TIME, DESCRIPTION, COVER_CHARGE (чекбокс — вход платный/бесплатный), POSTER (изображение).

Вывод — лента на главной (три ближайших мероприятия) и отдельная страница /events/ со списком. Прошедшие мероприятия перемещаются в архив автоматически по EVENT_DATE < now().

Интеграция с агрегаторами доставки

Яндекс.Еда и Delivery Club предоставляют API для ресторанов-партнёров. Интеграция двусторонняя:

  • Выгрузка меню — формирование XML/JSON-фида с позициями, ценами, фото, стоп-листом. Фид генерируется агентом раз в 30 минут из инфоблока «Меню»
  • Приём заказов — webhook от агрегатора на /api/aggregator-order/. Обработчик создаёт заказ в Highload-блоке и передаёт в POS-систему

Это избавляет администратора от ручного обновления меню в личных кабинетах агрегаторов.

Этапы разработки

  1. Проектирование (1-2 недели) — структура инфоблоков, схема интеграции с POS, прототипы страниц, маппинг данных между Битрикс и кассовой системой
  2. Дизайн (1-2 недели) — макеты: главная, меню (список + карточка), бронирование, доставка, акции
  3. Бэкенд (2-4 недели) — инфоблоки, компоненты меню и бронирования, интеграция с POS-системой, CRM, обработка заказов
  4. Фронтенд (1-3 недели) — адаптивные шаблоны, оптимизация изображений, формы заказа и бронирования, AJAX-обновление статусов
  5. Интеграции (1-2 недели) — POS-система, агрегаторы доставки, SMS-уведомления, платёжная система
  6. Тестирование (1-2 недели) — функциональное, тестовые заказы через POS, мобильное тестирование, нагрузочное
  7. Запуск (3-5 дней) — деплой, мониторинг синхронизации с кассой, проверка на реальных заказах
Масштаб проекта Ориентировочные сроки
Сайт-витрина с меню и бронированием 3-5 недель
Сайт с онлайн-заказом и интеграцией POS 6-9 недель
Полная система: заказ, POS, агрегаторы, мультиязычность 8-12 недель

Сроки зависят от выбранной POS-системы (iiko интегрируется быстрее r_keeper за счёт облачного API), количества языков и требований к личному кабинету клиента.