Требования к интеграции POS
Спецификация оценки для поставщиков POS-систем — требования к подключению, контракт коннектора, параметры производительности, семантика сбоев и порядок определения объёма интеграции.
Fooodo — это слой заказов и платежей для гостей, работающий поверх существующей POS-системы. Гости делают заказы и оплачивают их за столом через QR; заказы записываются в POS через серверный коннектор и поступают туда идентично заказам, введённым на терминале. POS не заменяется: он остаётся системой учёта меню и источником истины для кухонных операций и отчётности.
В этом документе описывается, что требуется от POS для интеграции с Fooodo, — операции, которые должен предоставлять POS API, ожидания к данным на уровне сущностей, требования к подключению и производительности, а также семантика сбоев, — после чего приводятся контрольный список оценки и путь к запуску в продакшн. Целевая аудитория — инженерная команда поставщика POS-системы, оценивающая осуществимость и трудозатраты.
Направление интеграции: Fooodo вызывает POS API. Коннектор реализуется и эксплуатируется Fooodo; ваша сторона предоставляет, документирует и поддерживает API-поверхность, доступную из облака Fooodo. Никакое программное обеспечение Fooodo не устанавливается и не размещается на стороне POS. Референсный коннектор, реализующий этот контракт, работает в продакшне в сети с несколькими локациями; новые коннекторы разрабатываются под каждого клиента после того, как сеть подписывает договор.
Как устроена интеграция
- Fooodo — это слой заказов и платежей для гостей; POS продолжает управлять кухней — те же маршруты печати, тот же KDS, те же отчёты.
- Контракт таков: заказ, созданный через Fooodo, поступает в POS неотличимо от заказа, введённого на терминале. Кухонному персоналу не нужно знать о существовании Fooodo.
- Fooodo — вызывающая сторона. Чтение выполняется по расписанию (меню, состояние заказа); запись происходит в момент события (заказ создан, заказ оплачен). Fooodo не потребляет вебхуки или событийный push от POS — вам не нужно их реализовывать.
- Ваша сторона предоставляет, документирует и поддерживает API — Fooodo строит и эксплуатирует всё остальное.
- Справочные данные доступны только для чтения через границу интеграции: Fooodo никогда не изменяет меню, цены, модификаторы и другие мастер-данные POS.
Что должна предоставлять ваша POS-система
Контракт коннектора охватывает четыре домена — локации, меню, заказы и платежи. Конкретно — в виде операций, названных здесь обобщённо; в вашем API они будут иметь собственные названия:
| Операция | Направление | Обязательна? |
|---|---|---|
| Получить полное меню — продукты, категории, цены, налоговые флаги | Fooodo читает | Обязательна |
| Получить группы модификаторов и ингредиенты | Fooodo читает | Обязательна |
| Проверить, онлайн ли локация | Fooodo читает | Обязательна |
| Читать доступность позиций («распродано») — может предоставляться через запрос меню или запрос статуса, в зависимости от того, что предоставляет ваш API | Fooodo читает | Обязательна |
| Получить состояние заказа на уровне стола | Fooodo читает | Обязательна |
| Получить полные детали заказа | Fooodo читает | Обязательна |
| Создать или обновить заказ — включая добавление позиций к открытому заказу и обработку заказов, заблокированных открытыми на терминале | Fooodo пишет | Обязательна |
| Отметить заказ как оплаченный | Fooodo пишет | Обязательна |
| Отправить сообщение на кухню | Fooodo пишет | Опциональна |
| Применить карту лояльности / предоставить меню с ценами по программе лояльности | Fooodo читает + пишет | Опциональна — только если сеть использует программу лояльности POS |
Это также полная поверхность записи — операций отмены, аннулирования или возврата через эту границу нет. Аннулирования выполняются на терминале POS, как и сегодня (Fooodo получает их через обновление заказа в процессе выполнения), а обработка возвратов находится полностью за пределами коннектора — она никогда не обращается к вашему API.
Fooodo поддерживает два потока заказов — Pay-First и Pay-Later с несколькими раундами dine-in, при котором раунды добавляются к открытому заказу POS и оплачиваются в конце (см. fooodo.com/docs/order-flows). Перечисленные выше операции охватывают оба потока; возможность добавления к открытому заказу — это то, на что Pay-Later опирается в наибольшей степени.
Контракт определён как набор операций, а не как формат передачи данных — коннектор строится под каждого клиента на основе уже имеющегося у вас интерфейса. Транспорт и формат вашего API рассматриваются на этапе определения объёма; для оценки осуществимости важно, чтобы перечисленные выше операции были доступны каким-либо образом.
Если ваша POS-система не может напрямую предоставить одну из обязательных операций, это не является автоматическим тупиком — именно это в первую очередь прорабатывается на звонке по определению объёма.
Как выглядят данные
Ожидания на уровне сущностей, чтобы ваша команда могла сопоставить их с собственной моделью данных. (Схемы на уровне полей находятся в репозитории интеграции, который партнёры получают в процессе онбординга.)
- Меню — категории, содержащие продукты; продукты несут цены, налоговые флаги, варианты (например, размеры) и группы модификаторов (добавление / удаление / замена ингредиентов, каждый со своей ценой). POS остаётся источником истины: Fooodo читает эту структуру, но никогда не записывает в неё.
- Заказ — ссылка на конкретный стол в конкретной локации; позиции с выбранным вариантом, модификаторами и количеством; итоговые суммы. К заказам можно добавлять позиции, пока они открыты (поток Pay-Later добавляет раунды к открытому заказу POS), а эффекты скидок или программы лояльности отражаются в заказе, который получает POS.
- Платёж — отметка «оплачено», применяемая к существующему заказу. Чаевые могут направляться в отдельную строку POS. Данные карты или кошелька нигде в этом потоке не фигурируют.
- Статус — локация онлайн/офлайн; доступность позиций («распродано»); состояние каждого заказа, включая «заблокирован — открыт на терминале». Заказы, полученные из POS, могут содержать идентификатор назначенного официанта, который Fooodo использует для атрибуции персонала в отчётах.
Требования к подключению
Именно на этом пункте чаще всего спотыкается большинство оценок.
- POS API каждой локации должен быть доступен из облака Fooodo через интернет по HTTPS по стабильному URL для каждой локации. В конфигурации Fooodo хранятся API-эндпоинт и идентификатор локации для каждого ресторана — этот эндпоинт должен отвечать на вызовы Fooodo.
- On-premise POS: заведению необходимо надёжное широкополосное подключение, а POS API должен быть открыт для Fooodo защищённым способом — через облачный шлюз вашего вендора, VPN-туннель или защищённый обратный прокси на площадке. Конкретный механизм согласовывается на этапе определения объёма; «POS доступен только из локальной сети» — это наиболее распространённый пробел.
- Cloud POS: соединение сервер-сервер (S2S) между облаком Fooodo и вашим облачным API с учётными данными и идентификаторами для каждой локации.
- Важно не только наличие соединения, но и его качество. Создание заказа и отметка об оплате находятся на критическом пути оформления заказа гостем, а проверка онлайн/офлайн выполняется каждую минуту, чтобы Fooodo мог перевести локацию в режим только для чтения в момент, когда POS становится недоступен. Кратковременный обрыв соединения на несколько минут обрабатывается корректно; соединение, которое нестабильно в течение всего дня, ухудшает качество обслуживания гостей в этой локации — независимо от того, насколько хороша интеграция.
Параметры производительности
Референсное развёртывание выполняет следующие циклы для каждой локации круглосуточно в течение сервиса:
| Что выполняется | Периодичность |
|---|---|
| Проверка онлайн/офлайн локации | каждую минуту |
| Получение новых заказов, открытых на терминале POS | каждые 4 минуты |
| Обновление состояния заказов в процессе выполнения (правки официанта, аннулирования) | каждые 2 минуты |
| Обновление доступности позиций меню («распродано») | каждые 5 минут |
| Полное обновление меню / категорий / цен | ежедневно, перед началом сервиса |
Ваш API должен выдерживать такой опрос для всех подключённых локаций одновременно, а две записи на критическом пути — создание заказа и отметка об оплате — должны выполняться за секунды. Неудавшиеся записи повторяются по расписанию с экспоненциальной задержкой, поэтому кратковременный отказ восстановим; хронически медленный эндпоинт — нет.
Семантика сбоев, на которую опирается Fooodo
Интеграция построена так, чтобы выдерживать кратковременную недоступность POS, и опирается на то, что POS возвращает различимые ошибки:
- «Заказ заблокирован / открыт на терминале» должно отличаться от жёсткого сбоя. Референсный коннектор распознаёт специфические коды ошибок блокировки и в ответ повторяет попытку с короткой задержкой (около пяти попыток за ~2,5 минуты), а не завершает с ошибкой. Отказы при отметке об оплате повторяются по более медленному расписанию (~17 минут), поскольку оплаченный заказ находится в процессе сверки, а не блокирует обслуживание.
- Недоступный POS автоматически переводит локацию в режим только для чтения. Кэшированное меню по-прежнему загружается для гостей, новые заказы блокируются при оформлении с понятным сообщением, а накопленные обновления применяются, когда POS возвращается в строй, — без вмешательства оператора.
- Повторные записи должны быть безопасными. Fooodo повторяет неудавшиеся отправки заказов; в процессе определения объёма мы совместно проверяем, что повторная попытка после таймаута не может привести к двойному созданию заказа на вашей стороне.
Сети с несколькими локациями
Fooodo создан для сетей. Каждый ресторан в компании имеет собственный POS-эндпоинт, идентификатор локации и учётные данные — разные локации могут указывать на разные экземпляры POS — а по мере создания новых коннекторов и на разные POS-системы. Оценивайте по наименее подключённой локации сети, а не по лучшей.
Безопасность
- Весь трафик коннектора передаётся по HTTPS/TLS с учётными данными для каждой локации. Механика учётных данных (API-ключ, токен, OAuth, mTLS) согласовывается на этапе определения объёма.
- Данные карт никогда не пересекают границу POS. Платежи проходят через отдельный платёжный сервис Fooodo (Mollie — карта, Apple Pay, Google Pay); ваша POS-система получает заказ и впоследствии отметку «оплачено», но никогда — данные платёжного инструмента. Интеграция не добавляет никаких потоков данных карт в вашу POS-систему.
- Общая позиция Fooodo в области безопасности — шифрование, субпроцессоры, GDPR — задокументирована на fooodo.com/security.
Среды и тестирование
- Ожидается наличие тестового экземпляра вашей POS-системы. Среда стейджинга Fooodo работает против вашей тестовой среды; продакшн-трафик никогда её не затрагивает.
- Режим mock позволяет вести раннюю разработку против приложения меню Fooodo с полным мокированием POS-трафика — полезно до того, как установлено какое-либо подключение.
- Партнёры получают репозиторий интеграции — полный контракт коннектора с фиксацией версий — в процессе онбординга.
Контрольный список оценки
Для оценки трудозатрат работа на вашей стороне, как правило, концентрируется в четырёх местах: устранение пробелов по обязательным операциям; открытие API для каждой локации (см. раздел «Требования к подключению»); выдача идентификаторов и учётных данных для каждой локации; развёртывание тестовой среды.
Если вы можете ответить «да» на все эти вопросы, интеграция, скорее всего, осуществима:
- Предоставляет ли ваша POS-система API, охватывающий обязательные операции выше — чтение меню, создание заказа, добавление позиций к уже открытому заказу, отметка об оплате, статус локации?
- Может ли этот API быть доступен из интернета по HTTPS для каждой локации — через облако вендора, S2S, VPN или защищённый прокси?
- Есть ли у каждой локации стабильный идентификатор и учётные данные?
- Возвращает ли API различимые ошибки для «заказ заблокирован на терминале» и жёстких сбоев?
- Выдерживает ли он опрос раз в минуту для каждой локации и выполняет ли записи заказов за секунды?
- Есть ли тестовая среда, против которой может работать стейджинг Fooodo?
- Ведут ли себя заказы, созданные через API, точно так же, как заказы с терминала на кухне (печать, KDS, отчёты)?
- Можно ли сделать повторное создание заказа после таймаута безопасным против двойного создания — с помощью ключа идемпотентности или способа проверить, существует ли заказ уже?
«Нет» или «не уверен» по любому из этих пунктов — это именно то, для чего нужен разговор по определению объёма: у многих из них есть более одного жизнеспособного ответа.
От оценки до живого коннектора
- Оценка — ваша команда изучает это руководство, заполняет контрольный список, и мы сравниваем результаты. Как правило, инициируется общим клиентом-рестораном.
- Определение объёма — рабочая сессия по сопоставлению вашего API с контрактом коннектора; для пробелов ищутся варианты решения. Fooodo определяет объём и рассчитывает стоимость сборки коннектора под каждого клиента в момент, когда сеть берёт на себя обязательства; работа, необходимая на вашей стороне, оценивается в том же разговоре, вместе с коммерческими условиями. Полезно подготовить заранее: документацию по вашему API, план тестовой среды, идентификаторы локаций и технический контакт на вашей стороне.
- Сборка и тестирование — разработка начинается в режиме mock, затем переходит в вашу тестовую среду против стейджинга Fooodo.
- Пилот и развёртывание — сначала одна живая локация, затем вся сеть.
Для начала: отправьте ответы на контрольный список и приблизительную оценку трудозатрат на вашей стороне на адрес partners@fooodo.com или воспользуйтесь формой для разработчиков на fooodo.com/developers. Детальный вид на уровне сборки — репозиторий интеграции с полным контрактом коннектора — передаётся в процессе онбординга.
Потоки заказов — Pay-First и Pay-Later
Когда использовать Pay-First и Pay-Later, как каждый из них работает от начала до конца, какие статусы заказов видят операторы в панели администратора и какие фоновые задания поддерживают синхронизацию заказов с POS.
Коннектор R-Keeper
Живая эталонная реализация контракта POS-коннектора Fooodo — какие данные пересекают границу, расписание синхронизации, ценообразование для программ лояльности и механизм повторных попыток при сбоях в продакшене.