Типовой протокол обмена между Битрикс и 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 дней гарантии