Enver Dzheparov

3 октября 2026 г. · CS-Cart · API · Интеграции

Интеграция CS-Cart с r_keeper: что всплыло на боевом объекте

Как я подключал интернет-магазин пиццерии к r_keeper Delivery: OAuth, вебхуки статусов, нечёткое сопоставление меню и три проблемы, которых нет в документации.

Задача звучала коротко: написать коннектор между сайтом пиццерии на CS-Cart и r_keeper Delivery и выгружать по регламенту заказы, покупателей, товары с остатками и ценами, категории. На деле самое интересное началось после того, как коннектор заработал.

Как устроена синхронизация

Модуль ходит в API r_keeper Delivery по OAuth: Client ID и Client Secret выдаёт дилер r_keeper. Дальше три потока:

Для вебхука на сайте поднят отдельный endpoint. Первая версия принимала токен параметром в URL, но интерфейс r_keeper такие ссылки не принимает: только чистый адрес и заголовок. В итоге авторизация переехала в заголовок X-Webhook-Token.

Проблема 1: меню, которое расходится на треть

API r_keeper принимает в заказе только блюда, которые пришли из его же меню. Произвольный товар с сайта касса отклоняет. А меню на сайте и в кассе жили отдельно и расходились примерно на треть.

Сопоставлять вручную сотни позиций никто не будет, поэтому модуль сравнивает названия нечётко:

Нечёткое сравнение ошибается на коротких и похожих названиях: «Пицца 4 вкуса 50 см» однажды склеилась с «33 см». Поэтому у модуля есть отчёт сравнения, где каждое совпадение можно принять или отклонить, и предпросмотр синхронизации без изменений.

Ещё одна ловушка: соусы, у которых в кассе цена 0. Синхронизация цен честно перенесла этот ноль на сайт. После этого появился режим «только цены и остатки» и привычка смотреть отчёт перед массовым обновлением.

Проблема 2: Симферополь, Украина

Тестовый заказ на «бульвар Ленина, 22, Симферополь» в r_keeper определился как Украина. Оказалось, что Delivery проверяет адреса через DaData и собирает строку как street + cityName. Когда в запросе есть только полный адрес одной строкой и нет координат, сервис угадывает.

Решение — передавать город отдельным полем и координаты точки доставки. После этого адреса стали определяться правильно.

Проблема 3: скидка, с которой заказ не идёт на кухню

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

Правильный формат — одна скидка на весь заказ общей суммой и с id скидки, заведённой в кассе. Причём важен именно id: по одному названию касса скидку не узнаёт. Это выяснилось только когда я включил тестовый режим, посмотрел реальный запрос и сравнил с тем, что ожидает касса.

Что помогло в отладке

Итог

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

Кейс проекта →

Есть похожая задача?

Написать мне →