К другим статьям
1С-БитриксDeliveryGuruИнтеграцииОчереди
Для разработчиков

Интеграция DeliveryGuru с 1С-Битрикс: очередь заказов, меню и стоп-листы

Интеграция ресторана с DeliveryGuru состоит не из одного запроса «отправить заказ». На витрине покупатель выбирает доставку или самовывоз, Битрикс сохраняет заказ, очередь передаёт его наружу, а в обратном направлении приходят меню и стоп-листы. Каждая часть имеет собственные ошибки и темп работы.

Ниже разобрана архитектура zr.dginteg и опыт проекта «Бакинский бульвар». Примеры анонимизированы и показывают только структуру; реальные адреса API, токены и данные заказов не публикуются.

Выбор доставки на витрине

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

Стоит хранить нормализованный код, например delivery или pickup, и отдельно выбранный ресторан/зону, если это требуется процессом. Название для интерфейса может меняться, код — нет.

$mode = (string) $request->getPost('delivery_mode');

if (!in_array($mode, ['delivery', 'pickup'], true)) {
    throw new DomainException('Не выбран допустимый способ получения заказа');
}

Код минимальный: в реальном checkout также проверяются доступность адреса, время работы и состав корзины. Клиентскому JavaScript доверять нельзя.

OnSaleOrderSaved не должен вызывать API

Событие OnSaleOrderSaved удобно как сигнал появления или изменения заказа. Но делать HTTP-запрос к DeliveryGuru прямо в обработчике опасно: внешний сервис может отвечать долго, оформление заказа зависнет, а повторное сохранение создаст дубль.

Обработчик должен быстро поставить задачу:

public static function onSaleOrderSaved(
    \Bitrix\Main\Event $event
): void {
    $order = $event->getParameter('ENTITY');
    $isNew = (bool) $event->getParameter('IS_NEW');

    if (!$isNew || !$order instanceof \Bitrix\Sale\Order) {
        return;
    }

    OrderQueueService::enqueueOnce((int) $order->getId());
}

Статический вызов приведён схематически. В production handler лучше оставить тонким, а идемпотентность обеспечить уникальным ключом заказа в очереди.

Очередь и Workers\Order

Задача очереди хранит локальный ORDER_ID, статус, число попыток, время следующего запуска и безопасное описание последней ошибки. Payload лучше собирать перед отправкой из актуального заказа либо сохранять версионированный snapshot — выбор зависит от того, должны ли поздние изменения попасть во внешний заказ.

Workers\Order выполняет один понятный цикл:

  1. атомарно забирает доступную задачу;
  2. строит DTO DeliveryGuru;
  3. отправляет через API client;
  4. сохраняет внешний идентификатор и безопасный фрагмент ответа;
  5. отмечает успех либо планирует повтор.

Повтор использует exponential backoff с верхним пределом. Ошибки валидации не нужно повторять бесконечно; сетевые и временные серверные ошибки — нужно. После лимита попыток задача переходит в состояние, требующее внимания.

Идемпотентность строится на стабильном ключе заказа. Если внешнее API поддерживает idempotency key, передавайте обезличенный технический идентификатор. Если нет — перед повторной отправкой проверяйте сохранённую связь.

Маппинг заказа

Не передавайте объект Bitrix\Sale\Order в HTTP client. Отдельный mapper формирует DTO с разрешёнными полями: позиции, количество, сумма, способ получения, комментарий и адрес в объёме, необходимом внешней системе.

final class DeliveryOrderDto
{
    public string $externalKey;
    public array $items = [];
    public int $amountMinor;
    public string $fulfillment;
}

Пример схематический и совместим с PHP 7.4. Логи должны маскировать телефон, адрес и комментарий клиента.

Меню и стоп-листы

Синхронизация меню и стоп-листов — отдельные процессы. Меню обновляет справочные данные и связи внешних позиций с товарами Битрикс. Стоп-лист быстро меняет доступность уже сопоставленных позиций.

Надёжный алгоритм:

  • загрузить ответ во временный набор;
  • проверить схему и уникальность внешних id;
  • сопоставить позиции по устойчивому идентификатору;
  • применить изменения транзакционно или пакетами;
  • только после успеха отметить синхронизацию завершённой.

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

На витрине стоп-лист должен блокировать добавление, но сервер повторно проверяет корзину перед созданием заказа. Между просмотром меню и оформлением доступность могла измениться.

Cron и hit

zr.dginteg поддерживает режимы cron/hit. Для production предпочтителен cron: он не зависит от посещаемости и даёт предсказуемый интервал. Hit-режим полезен как совместимый резерв на небольших проектах, но при отсутствии трафика очередь остановится.

Один запуск ограничивается количеством задач и временем:

$worker->runBatch(20, 25);

Здесь 20 — максимум задач, 25 — схематичный лимит секунд. Короткие batch-запуски не удерживают cron бесконечно и упрощают восстановление после ошибки.

Административный мониторинг

В админке полезны четыре экрана:

  • очередь заказов: статус, попытки, следующий запуск;
  • история запросов: метод, длительность, HTTP-код, correlation id;
  • меню и сопоставления;
  • стоп-листы и время последней успешной синхронизации.

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

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

Практический вывод

Устойчивая интеграция отделяет оформление заказа от внешнего API. OnSaleOrderSaved создаёт идемпотентную задачу, Workers\Order отвечает за доставку с повторами, а меню и стоп-листы синхронизируются независимо и наблюдаются через админку.

Перед запуском проверьте отказ API, повтор события Sale, пустой стоп-лист, заказ с недоступной позицией и остановку cron. Именно эти сценарии определяют надёжность сильнее, чем успешный запрос на тестовом заказе.

Нужен модуль или интеграция?

Разберём архитектуру вашей задачи на 1С-Битрикс

Опишите сценарий и ограничения проекта — предложу безопасную схему реализации, оценку и следующий шаг.