В этой статье мы рассмотрим продвинутую технику интеграции — настройку обмена произвольными справочниками между 1С и Битрикс через REST API. Вы научитесь выгружать данные, которые не входят в стандартные схемы обмена (каталог, заказы), такие как Производители, Склады, Дополнительные свойства или любые другие бизнес-справочники.
Для кого эта статья: Для разработчиков 1С и Bitrix, которые уже настроили базовый обмен товарами и заказами и хотят расширить функционал интеграции. Требуется базовое понимание работы REST API и структуры данных в обеих системах.
Архитектура решения
В отличие от стандартного обмена через CommerceML, для произвольных справочников мы будем использовать REST API Битрикс. Это дает нам гибкость в формате данных и позволяет обмениваться любыми структурами.
Часть 1: Подготовка структуры в Битрикс
1 Выбор типа хранения данных
В Битрикс есть два основных способа хранения справочников:
| Тип | Когда использовать | Преимущества |
|---|---|---|
| Highload-блок | Большие объемы данных, частая запись/чтение, нужны сложные связи | Высокая производительность, отдельная таблица в БД, удобный API |
| Инфоблок | Небольшие справочники, нужны версии, права доступа, workflow | Встроенные механизмы CMS, управление правами, история изменений |
Для примера создадим Highload-блок "Производители":
2 Создание Highload-блока
- Перейдите в
Настройки → Highload-блоки - Нажмите "Добавить Highload-блок"
- Заполните параметры:
- Название: Производители (Manufacturers)
- Название таблицы: manufacturers
- Код: MANUFACTURERS
// Пример добавления полей через код (в init.php или отдельном скрипте)
use Bitrix\Highloadblock as HL;
use Bitrix\Main\Entity;
$hlblock = HL\HighloadBlockTable::getList([
'filter' => ['=NAME' => 'Производители']
])->fetch();
if ($hlblock) {
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
// Добавляем поля
$fields = [
['FIELD_NAME' => 'UF_NAME', 'USER_TYPE_ID' => 'string', 'MANDATORY' => 'Y'],
['FIELD_NAME' => 'UF_XML_ID', 'USER_TYPE_ID' => 'string', 'MANDATORY' => 'Y'],
['FIELD_NAME' => 'UF_DESCRIPTION', 'USER_TYPE_ID' => 'string'],
['FIELD_NAME' => 'UF_SORT', 'USER_TYPE_ID' => 'integer', 'DEFAULT_VALUE' => 500],
['FIELD_NAME' => 'UF_ACTIVE', 'USER_TYPE_ID' => 'boolean', 'DEFAULT_VALUE' => 1],
['FIELD_NAME' => 'UF_1C_ID', 'USER_TYPE_ID' => 'string'], // Внутренний ID из 1С
];
$obUserField = new CUserTypeEntity();
foreach ($fields as $field) {
$field['ENTITY_ID'] = 'HLBLOCK_' . $hlblock['ID'];
$obUserField->Add($field);
}
}
3 Настройка REST API в Битрикс
Для приема данных из 1С нам нужен обработчик REST API:
- Создайте файл
/bitrix/rest/manufacturers.php - Зарегистрируйте метод в REST-приложении
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
// Проверка ключа REST API
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
use Bitrix\Highloadblock as HL;
use Bitrix\Main\Loader;
Loader::includeModule('highloadblock');
class ManufacturersRestApi extends IRestService
{
public static function OnRestServiceBuildDescription()
{
return [
'manufacturers' => [
'manufacturers.sync' => [
'callback' => [__CLASS__, 'syncManufacturers'],
'options' => []
],
'manufacturers.get' => [
'callback' => [__CLASS__, 'getManufacturers'],
'options' => []
],
]
];
}
// Метод для синхронизации данных из 1С
public static function syncManufacturers($query, $nav, $server)
{
$data = $server->getInput();
if (!isset($data['manufacturers']) || !is_array($data['manufacturers'])) {
return ['error' => 'Invalid data format'];
}
$hlblock = HL\HighloadBlockTable::getList([
'filter' => ['=NAME' => 'Производители']
])->fetch();
if (!$hlblock) {
return ['error' => 'Highload-block not found'];
}
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
$entityDataClass = $entity->getDataClass();
$results = [
'added' => 0,
'updated' => 0,
'errors' => []
];
foreach ($data['manufacturers'] as $manufacturer) {
try {
// Ищем по внешнему коду из 1С
$existing = $entityDataClass::getList([
'filter' => ['UF_XML_ID' => $manufacturer['xml_id']],
'select' => ['ID']
])->fetch();
$fields = [
'UF_NAME' => $manufacturer['name'],
'UF_XML_ID' => $manufacturer['xml_id'],
'UF_DESCRIPTION' => $manufacturer['description'] ?? '',
'UF_SORT' => (int)($manufacturer['sort'] ?? 500),
'UF_ACTIVE' => $manufacturer['active'] === 'N' ? 0 : 1,
'UF_1C_ID' => $manufacturer['id_1c'] ?? '',
];
if ($existing) {
// Обновляем существующую запись
$result = $entityDataClass::update($existing['ID'], $fields);
if ($result->isSuccess()) {
$results['updated']++;
}
} else {
// Добавляем новую запись
$result = $entityDataClass::add($fields);
if ($result->isSuccess()) {
$results['added']++;
}
}
if (!$result->isSuccess()) {
$results['errors'][] = [
'xml_id' => $manufacturer['xml_id'],
'errors' => $result->getErrorMessages()
];
}
} catch (Exception $e) {
$results['errors'][] = [
'xml_id' => $manufacturer['xml_id'] ?? 'unknown',
'error' => $e->getMessage()
];
}
}
return $results;
}
// Метод для получения данных (опционально)
public static function getManufacturers($query, $nav, $server)
{
$hlblock = HL\HighloadBlockTable::getList([
'filter' => ['=NAME' => 'Производители']
])->fetch();
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
$entityDataClass = $entity->getDataClass();
$items = $entityDataClass::getList([
'select' => ['*'],
'order' => ['UF_SORT' => 'ASC', 'UF_NAME' => 'ASC']
])->fetchAll();
return ['manufacturers' => $items];
}
}
// Регистрация обработчиков
AddEventHandler('rest', 'OnRestServiceBuildDescription', ['ManufacturersRestApi', 'OnRestServiceBuildDescription']);
Часть 2: Настройка выгрузки из 1С
4 Создание HTTP-сервиса в 1С
В конфигурации 1С создаем веб-сервис для выгрузки справочника "Производители":
// В модуле HTTP-сервиса 1С
Функция ОтправитьПроизводителиВБитрикс()
// Получаем данные справочника
Запрос = Новый Запрос;
Запрос.Текст = "
ВЫБРАТЬ
Производители.Ссылка КАК Ссылка,
Производители.Наименование КАК Наименование,
Производители.Код КАК Код,
Производители.Артикул КАК Артикул,
Производители.Описание КАК Описание,
Производители.ПометкаУдаления КАК Удален
ИЗ
Справочник.Производители КАК Производители
ГДЕ
НЕ Производители.ЭтоГруппа";
Выборка = Запрос.Выполнить().Выбрать();
// Формируем JSON для отправки
МассивПроизводителей = Новый Массив;
Пока Выборка.Следующий() Цикл
Производитель = Новый Структура;
Производитель.Вставить("xml_id", Выборка.Код);
Производитель.Вставить("id_1c", Строка(Выборка.Ссылка));
Производитель.Вставить("name", Выборка.Наименование);
Производитель.Вставить("description", Выборка.Описание);
Производитель.Вставить("sort", 500);
Производитель.Вставить("active", НЕ Выборка.Удален);
МассивПроизводителей.Добавить(Производитель);
КонецЦикла;
// Формируем тело запроса
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("manufacturers", МассивПроизводителей);
JSON = Новый ЗаписьJSON;
JSON.УстановитьСтроку();
ЗаписьДанных(JSON, ТелоЗапроса);
// Отправка через HTTP-соединение
Соединение = Новый HTTPСоединение("ваш-сайт.ру");
ЗапросHTTP = Новый HTTPЗапрос("/rest/manufacturers.sync.json");
// Устанавливаем заголовки
ЗапросHTTP.Заголовки.Вставить("Content-Type", "application/json");
ЗапросHTTP.Заголовки.Вставить("Authorization", "Bearer YOUR_REST_TOKEN");
// Устанавливаем тело запроса
ЗапросHTTP.УстановитьТелоИзСтроки(JSON.Закрыть(), "application/json; charset=utf-8");
Попытка
ОтветHTTP = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
Если ОтветHTTP.КодСостояния = 200 Тогда
// Читаем ответ
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ОтветHTTP.ПолучитьТелоКакСтроку());
Результат = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Возврат Результат;
Иначе
Возврат "Ошибка HTTP: " + ОтветHTTP.КодСостояния;
КонецЕсли;
Исключение
Возврат "Ошибка при отправке: " + ОписаниеОшибки();
КонецПопытки;
КонецФункции
5 Настройка регулярного обмена
Чтобы обмен происходил автоматически, можно:
Вариант А: Регламентное задание в 1С
// В модуле регламентного задания 1С
Процедура РегламентноеЗадание_ВыгрузкаПроизводителей()
Результат = ОтправитьПроизводителиВБитрикс();
// Запись результатов в журнал
КонецПроцедуры
Вариант Б: Запуск из обработки "Обмен с сайтом"
Добавьте свою команду в стандартную обработку обмена с сайтом, чтобы выгрузка производителей выполнялась вместе с основной синхронизацией.
Вариант В: REST API из Битрикс
Настройте в Битрикс агента, который будет инициировать выгрузку, вызывая веб-сервис 1С по расписанию.
Часть 3: Практический пример - Склады
6 Расширяем решение для справочника "Склады"
// Поля для Highload-блока "Склады"
$fields = [
['FIELD_NAME' => 'UF_NAME', 'USER_TYPE_ID' => 'string', 'MANDATORY' => 'Y'],
['FIELD_NAME' => 'UF_XML_ID', 'USER_TYPE_ID' => 'string', 'MANDATORY' => 'Y'],
['FIELD_NAME' => 'UF_ADDRESS', 'USER_TYPE_ID' => 'string'],
['FIELD_NAME' => 'UF_PHONE', 'USER_TYPE_ID' => 'string'],
['FIELD_NAME' => 'UF_WORK_HOURS', 'USER_TYPE_ID' => 'string'],
['FIELD_NAME' => 'UF_IS_RETAIL', 'USER_TYPE_ID' => 'boolean', 'DEFAULT_VALUE' => 0],
['FIELD_NAME' => 'UF_ACTIVE', 'USER_TYPE_ID' => 'boolean', 'DEFAULT_VALUE' => 1],
['FIELD_NAME' => 'UF_1C_ID', 'USER_TYPE_ID' => 'string'],
['FIELD_NAME' => 'UF_GEO_LAT', 'USER_TYPE_ID' => 'double'],
['FIELD_NAME' => 'UF_GEO_LON', 'USER_TYPE_ID' => 'double'],
];
// В 1С, аналогично производителям
Запрос.Текст = "
ВЫБРАТЬ
Склады.Ссылка КАК Ссылка,
Склады.Наименование КАК Наименование,
Склады.Код КАК Код,
Склады.Адрес КАК Адрес,
Склады.Телефон КАК Телефон,
Склады.РежимРаботы КАК РежимРаботы,
Склады.ЭтоРозничныйСклад КАК Розничный,
Склады.КоординатаШирота КАК Широта,
Склады.КоординатаДолгота КАК Долгота
ИЗ
Справочник.Склады КАК Склады";
Часть 4: Оптимизация и мониторинг
7 Рекомендации по оптимизации
| Проблема | Решение |
|---|---|
| Большой объем данных | Используйте пагинацию: отправляйте данные порциями по 100-200 записей |
| Частые изменения | Внедрите механизм инкрементального обмена: передавайте только измененные записи с меткой времени |
| Ошибки валидации | Добавьте предварительную проверку данных в 1С перед отправкой |
| Безопасность | Используйте IP-фильтрацию, сложные токены, HTTPS |
8 Мониторинг и логирование
// В начало метода syncManufacturers добавьте
\Bitrix\Main\Diag\Debug::writeToFile([
'timestamp' => date('Y-m-d H:i:s'),
'action' => 'sync_manufacturers',
'input_count' => count($data['manufacturers'] ?? [])
], '', '1c_rest_sync.log');
// В админке Битрикс можно создать страницу
// /bitrix/admin/1c_sync_log.php с отображением:
// 1. Статус последней синхронизации
// 2. Количество записей в справочниках
// 3. Ошибки последнего обмена
// 4. Кнопка для ручного запуска синхронизации
⚠️ Важные замечания
- Идентификаторы: Всегда используйте
UF_XML_IDдля связи записей между 1С и Битрикс. Это гарантирует правильное обновление, а не создание дубликатов. - Обработка удалений: Решите, как обрабатывать удаленные в 1С записи — помечать неактивными или физически удалять из Битрикс.
- Производительность: Для больших справочников (более 5000 записей) используйте пакетную обработку и индексацию полей.
- Тестирование: Всегда тестируйте интеграцию на тестовом стенде перед запуском на боевом сайте.
Заключение
Настройка обмена произвольными справочниками между 1С и Битрикс через REST API открывает широкие возможности для интеграции:
- Гибкость: Можете выгружать любые данные из 1С, не ограничиваясь стандартными схемами
- Производительность: Highload-блоки оптимальны для хранения справочных данных
- Масштабируемость: Архитектуру легко расширять для новых типов справочников
- Надежность: REST API обеспечивает стабильную и безопасную передачу данных
Представленная методика уже успешно применяется для интеграции справочников: Производители, Склады, Типы цен, Менеджеры, Статусы заказов, Пункты выдачи, Сервисные центры и многих других бизнес-объектов.