Yandex Metrika
sanches.free

Типовой протокол обмена между Битрикс и 1С: каталог, заказы и расширения

Старт всегда на стороне 1С

Портал не «тягает» данные из учётной базы сам по себе: он только отвечает на последовательные HTTP-запросы конфигурации 1С. В типовых настройках выгрузка бьёт в /bitrix/admin/1c_exchange.php, который из коробки подключает сценарий из /bitrix/modules/sale/admin/1c_exchange.php. Комбинации параметров $_GET["type"] и режима включают разные компоненты; практический интерес чаще сводится к двум связкам:

  • bitrix:catalog.import.1c — разбор каталога и складских данных,
  • bitrix:sale.export.1c — отдача изменившихся заказов назад в 1С.

Входящий поток каталога

Цепочка запросов

Сначала 1С передаёт логин и пароль служебного пользователя портала. Запрос ?type=catalog&mode=checkauth возвращает идентификатор сеансовой связки для последующих шагов.

Инициализация ?type=catalog&mode=init&sessid=… подготавливает служебный массив $_SESSION["BX_CML2_IMPORT"], сообщает возможность упаковать обмен zip-архивом, лимиты на размер пакета и очищает рабочий каталог приёма. Для временных файлов чаще используется /upload/1c_catalog/.

Отладить повторную выгрузку без потери истории можно, если в момент расследования объявить в dbconn.php константу, которая архивирует предыдущие пачки во вложенные каталоги 1c_catalog0, 1c_catalog1 и далее. Не оставляйте её включённой на боевых серверах — диск быстро забьётся.

define('BX_CATALOG_IMPORT_1C_PRESERVE', true);

Дальше платформа принимает кусками тело через ?type=catalog&mode=file&filename=…&sessid=…, после чего либо разбирается с отдельными XML либо вскрывает единственный архив, если режим ZIP разрешён.

Структурно типовые пакеты могут включать названия наподобие import.xml (номенклатура, разделы, склады и свойства), offers.xml — связка торговых предложений и их атрибутов, отдельные prices.xml и rests.xml для цен и остатков в свежих схемах, а также references.xml под пользовательские highload-сущности при их участии.

Изображения оседают внутри дерева вида /upload/1c_catalog/import_files/.

Стадии парсера

Разбор каждого файла триггерит цикл режимом ?type=catalog&mode=import&filename=…; обмен считается завершённым для конкретного файла, когда ответ тела содержит слово success. Непосредственно за XML отвечают связка CIBlockXMLFile (cml2.php) и CIBlockCMLImport; укрупнённая последовательность такова:

  • снос временной модели данных (CIBlockXMLFile::DropTemporaryTables),
  • повторное создание «дерева» узлов (CreateTemporaryTables),
  • заливка исходного файла таблицу b_xml_tree через ReadXMLToDatabase,
  • индексирование буфера (IndexTemporaryTables),
  • перенос метаданных, разделов, пересборка активности узлов,
  • массовый проход элементов либо отдельных цен через ImportElements / ImportElementPrices в зависимости от содержания файла.

Отдельные этапы могут дробиться на несколько последовательных запросов: таймаут одного прохода настраивается в административном интерфейсе блока интеграции с «1С:Предприятие».

После каждого полного файла

На завершении обработки одного конкретного XML платформа триггерит событие OnSuccessCatalogImport1C модуля catalog; в обработчик уходят параметры компонента и путь к файлу результата. Если возможностей хука мало, остаются стандартные события вроде OnBeforeIBlockElementUpdate, где полезно гарантированно понимать, что исполнение идёт внутри сценария CommerceML:

$gateCatalogImportPipe = isset($_GET['type'], $_GET['mode'])
    && $_GET['type'] === 'catalog'
    && $_GET['mode'] === 'import';

if ($gateCatalogImportPipe) {
}

В крайних случаях приходится вынести копию /bitrix/admin/1c_exchange.php, переопределить параметры компонента bitrix:catalog.import.1c или сузить семейство методов наследования у CIBlockCMLImport — любой такой подход уже сопровождающий код на годы вперёд.

Когда мешает проверка Referer/IP

В части сборок включают проверку того, действительно ли запрос исполняет «родной» узел CommerceML. Временное отключение на уровне модуля каталога делают опцией catalog.DEFAULT_SKIP_SOURCE_CHECK; в D7-стиле:

\Bitrix\Main\Config\Option::set('catalog', 'DEFAULT_SKIP_SOURCE_CHECK', 'Y');

Исходящий поток заказов в 1С

Здесь симметричная схема: ?type=sale&mode=checkauth, затем mode=init с тем же sessid, после чего 1С тянет пакет ?type=sale&mode=query.

В выборку попадают заказы без признака внешнего происхождения (EXTERNAL_ORDER = "N"), не промеченные последним импортом из базы как «замороженные» (UPDATED_1C = "N") и затронутые после метки времени успешной выгрузки, которую платформа держит в служебной опции модуля sale.

Флаг UPDATED_1C становится положительным после принятия внешнего апдейта; он снимается, когда оператор интернет-магазина редактирует заказ уже на сайте, поэтому механизм не теряет «шум» между двумя мирами.

Завершение цикла — обращение ?type=sale&mode=success; в опцию «последнего экспорта» записывается время предыдущего запроса списка, а не момента нажатия success, чтобы не отрезать заказы, которые успели родиться между выборкой и подтверждением обработки у 1С.

Изменять выгрузку сложнее

Готовые события на поток экспорта не регистрируются: обычно клонируют компонент bitrix:sale.export.1c, вынимают свой класс-наследник от CSaleExport или подсовывают альтернативный файл обменного endpoint. В актуальных ветках CSaleExport хотя бы читается по слоям, в старых релизах это был монолитный PHP с ручным конкатенированием XML.

Ошибка «проверки источника» на sale-сценарии

С ветки 15.5 всплывает ответ наподобие «Обновите модуль обмена», если просто набрать ?type=sale&mode=query без ожидаемого контекста сессии. Для технических стендов нередко временно ставят опцию sale.secure_1c_exchange в состояние N:

\Bitrix\Main\Config\Option::set('sale', 'secure_1c_exchange', 'N');

Разумный компромисс — вернуться к включённому режиму, как только тестируемый узел может стабильно передавать валидный sessid.

Справочные материалы

Не хотите копаться сами?

Починю за 1-3 дня. Без предоплаты — оплата по результату.

15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии