Как выгрузить номенклатуру из 1С в торговый каталог

Scope: catalog

Кто может выполнять методы: чтобы пройти сценарий целиком, нужно самое строгое из перечисленных прав — права администратора Битрикс24

Выберите инструмент для разработки с AI-агентом:

  • используйте Битрикс24 Вайбкод, чтобы создать приложение для Битрикс24 по описанию задачи без знания языков программирования. Агент напишет код и разместит приложение на сервере без ручной настройки хостинга
  • используйте MCP-сервер, чтобы разрабатывать интеграцию через REST API в своем проекте. Агент будет обращаться к официальной REST-документации

Номенклатура в 1С — справочник товаров с ценами и единицами измерения. В Битрикс24 это торговый каталог CRM: товар и его цены хранятся отдельно, поэтому выгрузка идет в два вызова — сначала товар, затем цена.

Порядок вызовов:

  1. catalog.catalog.list — получаем идентификатор торгового каталога
  2. catalog.measure.list — получаем единицы измерения
  3. catalog.priceType.list — получаем тип цены
  4. catalog.product.list — ищем товар по внешнему коду
  5. catalog.product.add или catalog.product.update — создаем или обновляем товар
  6. catalog.price.add или catalog.price.update — записываем цену

Перед началом

Для выполнения примеров нужны:

Вебхук работает с правами создавшего его пользователя. Если вебхук создал не администратор, методы catalog.product.add и catalog.product.update вернут ошибку прав доступа, хотя scope catalog будет выдан.

Как использовать примеры в документации

1. Получаем справочники каталога

Перед выгрузкой номенклатуры нужны три значения: идентификатор каталога, идентификатор единицы измерения и идентификатор типа цены. Они отличаются на разных Битрикс24, поэтому получаем их запросами, а не записываем в код.

&НаСервере
Функция ПараметрыКаталога()
	
	Результат = Новый Структура;
	
	// Торговый каталог CRM
	ОтветКаталога = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.catalog.list",
		Новый Структура("filter", Новый Структура("iblockTypeId", "CRM_PRODUCT_CATALOG")));
	
	Если НЕ ОтветКаталога.Успешно Тогда
		ВызватьИсключение "Не удалось получить торговый каталог: " + ОтветКаталога.ОписаниеОшибки;
	КонецЕсли;
	
	Каталоги = ОтветКаталога.Результат.Получить("catalogs");
	Результат.Вставить("ИдентификаторКаталога",
		ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Каталоги[0].Получить("iblockId")));
	
	// Единица измерения по умолчанию
	ОтветЕдиниц = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.measure.list");
	Единицы = ОтветЕдиниц.Результат.Получить("measures");
	
	Результат.Вставить("ЕдиницаПоУмолчанию", 0);
	Для Каждого Единица Из Единицы Цикл
		Если Единица.Получить("isDefault") = "Y" Тогда
			Результат.Вставить("ЕдиницаПоУмолчанию",
				ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Единица.Получить("id")));
		КонецЕсли;
	КонецЦикла;
	
	// Базовый тип цены
	ОтветТиповЦен = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.priceType.list");
	ТипыЦен = ОтветТиповЦен.Результат.Получить("priceTypes");
	
	Результат.Вставить("ТипЦены", 0);
	Для Каждого ТипЦены Из ТипыЦен Цикл
		Если ТипЦены.Получить("base") = "Y" Тогда
			Результат.Вставить("ТипЦены",
				ИнтеграцияБитрикс24.ИдентификаторИзОтвета(ТипЦены.Получить("id")));
		КонецЕсли;
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

Ответ метода catalog.catalog.list:

{
    "result": {
        "catalogs": [
            {
                "iblockId": 55,
                "iblockTypeId": "CRM_PRODUCT_CATALOG",
                "id": 55,
                "name": "Товарный каталог CRM",
                "productIblockId": null,
                "vatId": 1
            }
        ]
    },
    "total": 2
}

Ответ метода catalog.measure.list:

{
    "result": {
        "measures": [
            { "code": 796, "id": 9, "isDefault": "Y", "symbolIntl": "pc. 1" },
            { "code": 166, "id": 7, "isDefault": "N", "symbolIntl": "kg" },
            { "code": 112, "id": 3, "isDefault": "N", "symbolIntl": "l" }
        ]
    },
    "total": 5
}

Код единицы и идентификатор единицы — разные значения

В поле measure товара передают id единицы измерения — в примере это 9. В товарных позициях документов CRM поле называется measureCode и принимает код ОКЕИ — для штуки это 796. Если перепутать значения, товар сохранится с неверной единицей.

Ответ метода catalog.priceType.list:

{
    "result": {
        "priceTypes": [
            {
                "id": 1,
                "name": "BASE",
                "base": "Y",
                "xmlId": "BASE",
                "sort": 100
            }
        ]
    },
    "total": 1
}

2. Ищем товар по внешнему коду

GUID номенклатуры записываем в поле xmlId товара — по нему находим товар при повторной выгрузке.

&НаСервере
Функция НайтиТовар(ИдентификаторКаталога, ВнешнийКод)
	
	Фильтр = Новый Структура;
	Фильтр.Вставить("iblockId", ИдентификаторКаталога);
	Фильтр.Вставить("xmlId", ВнешнийКод);
	
	Параметры = Новый Структура;
	Параметры.Вставить("filter", Фильтр);
	// iblockId в select обязателен: без него метод вернет ошибку Required select fields
	Параметры.Вставить("select", СтрРазделить("id,name,xmlId,iblockId", ","));
	
	Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.product.list", Параметры);
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение "Не удалось найти товар: " + Ответ.ОписаниеОшибки;
	КонецЕсли;
	
	Товары = Ответ.Результат.Получить("products");
	
	Если Товары.Количество() = 0 Тогда
		Возврат 0;
	КонецЕсли;
	
	Возврат ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Товары[0].Получить("id"));
	
КонецФункции

Ответ метода:

{
    "result": {
        "products": [
            {
                "iblockId": 55,
                "id": 127,
                "name": "Бумага офисная А4, 500 л.",
                "xmlId": "1c-nom-000000042"
            }
        ]
    },
    "total": 1
}

Поле iblockId обязательно указывать в select методов catalog.product.*. Без него метод возвращает ошибку с кодом состояния 400 и текстом Required select fields: iblockId.

3. Создаем или обновляем товар

&НаСервере
Функция ЗаписатьТовар(Номенклатура, ПараметрыКаталога)
	
	ВнешнийКод = Строка(Номенклатура.Ссылка.УникальныйИдентификатор());
	ИдентификаторТовара = НайтиТовар(ПараметрыКаталога.ИдентификаторКаталога, ВнешнийКод);
	
	Поля = Новый Структура;
	Поля.Вставить("iblockId", ПараметрыКаталога.ИдентификаторКаталога);
	Поля.Вставить("name", Номенклатура.Наименование);
	Поля.Вставить("xmlId", ВнешнийКод);
	Поля.Вставить("measure", ПараметрыКаталога.ЕдиницаПоУмолчанию);
	Поля.Вставить("active", ?(Номенклатура.ПометкаУдаления, "N", "Y"));
	Поля.Вставить("previewText", Номенклатура.Комментарий);
	Поля.Вставить("vatIncluded", "Y");
	
	Параметры = Новый Структура;
	Параметры.Вставить("fields", Поля);
	
	Если ИдентификаторТовара = 0 Тогда
		Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.product.add", Параметры);
	Иначе
		Параметры.Вставить("id", ИдентификаторТовара);
		Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.product.update", Параметры);
	КонецЕсли;
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение СтрШаблон("Не удалось записать товар «%1»: %2",
			Номенклатура.Наименование, Ответ.ОписаниеОшибки);
	КонецЕсли;
	
	Элемент = Ответ.Результат.Получить("element");
	
	Возврат ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Элемент.Получить("id"));
	
КонецФункции

Оба метода возвращают товар целиком в ключе element:

{
    "result": {
        "element": {
            "id": 127,
            "iblockId": 55,
            "name": "Бумага офисная А4, 500 л.",
            "xmlId": "1c-nom-000000042",
            "code": "paper-a4",
            "active": "Y",
            "measure": 9,
            "vatId": 1,
            "vatIncluded": "Y",
            "purchasingPrice": "300.00000000",
            "purchasingCurrency": "RUB",
            "dateCreate": "2026-08-21T13:45:31+03:00",
            "timestampX": "2026-08-21T13:45:31+03:00",
            "type": 1
        }
    }
}

Часть числовых полей каталога возвращается строкой с восемью знаками после запятой — например, "purchasingPrice": "300.00000000", тогда как price в методах цен приходит числом. Перед сравнением с данными 1С приводите значение к числу.

4. Записываем цену

Цена — отдельный объект: она связана с товаром и типом цены. При первой выгрузке цену создают, при повторной — обновляют.

&НаСервере
Процедура ЗаписатьЦену(ИдентификаторТовара, ТипЦены, Цена)
	
	Фильтр = Новый Структура;
	Фильтр.Вставить("productId", ИдентификаторТовара);
	Фильтр.Вставить("catalogGroupId", ТипЦены);
	
	ПараметрыПоиска = Новый Структура;
	ПараметрыПоиска.Вставить("filter", Фильтр);
	ПараметрыПоиска.Вставить("select", СтрРазделить("id,price,currency", ","));
	
	ОтветПоиска = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.price.list", ПараметрыПоиска);
	
	Если НЕ ОтветПоиска.Успешно Тогда
		ВызватьИсключение "Не удалось получить цены товара: " + ОтветПоиска.ОписаниеОшибки;
	КонецЕсли;
	
	Цены = ОтветПоиска.Результат.Получить("prices");
	
	Поля = Новый Структура;
	Поля.Вставить("price", Цена);
	Поля.Вставить("currency", "RUB");
	
	Параметры = Новый Структура;
	
	Если Цены.Количество() = 0 Тогда
		Поля.Вставить("productId", ИдентификаторТовара);
		Поля.Вставить("catalogGroupId", ТипЦены);
		Параметры.Вставить("fields", Поля);
		Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.price.add", Параметры);
	Иначе
		Параметры.Вставить("id", ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Цены[0].Получить("id")));
		Параметры.Вставить("fields", Поля);
		Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("catalog.price.update", Параметры);
	КонецЕсли;
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение "Не удалось записать цену: " + Ответ.ОписаниеОшибки;
	КонецЕсли;
	
КонецПроцедуры

Ответ метода catalog.price.add:

{
    "result": {
        "price": {
            "id": 65,
            "productId": 127,
            "catalogGroupId": 1,
            "price": 450,
            "currency": "RUB",
            "priceScale": 450,
            "quantityFrom": null,
            "quantityTo": null,
            "timestampX": "2026-08-21T13:45:43+03:00"
        }
    }
}

5. Собираем сценарий целиком

&НаСервере
Процедура ВыгрузитьНоменклатуру(МассивНоменклатуры) Экспорт
	
	ПараметрыКаталога = ПараметрыКаталога();
	
	Для Каждого Номенклатура Из МассивНоменклатуры Цикл
		
		Попытка
			
			ИдентификаторТовара = ЗаписатьТовар(Номенклатура, ПараметрыКаталога);
			
			// ЦенаНоменклатуры — ваша функция: в типовых конфигурациях цену получают
			// запросом к регистру сведений «ЦеныНоменклатуры» на нужную дату и вид цены
			ЗаписатьЦену(ИдентификаторТовара, ПараметрыКаталога.ТипЦены, ЦенаНоменклатуры(Номенклатура));
			
		Исключение
			
			ЗаписьЖурналаРегистрации("Битрикс24.Номенклатура",
				УровеньЖурналаРегистрации.Ошибка,
				,
				,
				СтрШаблон("%1: %2",
					Номенклатура.Наименование,
					КраткоеПредставлениеОшибки(ИнформацияОбОшибке())));
			
		КонецПопытки;
		
		// Пауза, чтобы не превысить лимит интенсивности запросов.
		// Метод ВызватьПаузу доступен начиная с версии платформы 8.3.25.
		ВызватьПаузу(500);
		
	КонецЦикла;
	
КонецПроцедуры

Выгрузка одной позиции — это до четырех запросов: поиск товара, запись товара, поиск цены, запись цены. Для справочника в тысячи позиций так выгружать долго, поэтому большие объемы передают пакетами.

6. Ускоряем выгрузку пакетами

Метод batch выполняет до 50 вызовов за один HTTP-запрос. Сначала одним пакетом ищем товары по внешним кодам, затем вторым пакетом их создаем или обновляем.

&НаСервере
Функция НайтиТоварыПакетом(ИдентификаторКаталога, ВнешниеКоды)
	
	Команды = Новый Соответствие;
	
	Для Индекс = 0 По ВнешниеКоды.Количество() - 1 Цикл
		
		Фильтр = Новый Структура;
		Фильтр.Вставить("iblockId", ИдентификаторКаталога);
		Фильтр.Вставить("xmlId", ВнешниеКоды[Индекс]);
		
		ПараметрыПоиска = Новый Структура;
		ПараметрыПоиска.Вставить("filter", Фильтр);
		ПараметрыПоиска.Вставить("select", СтрРазделить("id,xmlId,iblockId", ","));
		
		Команды.Вставить("find" + Строка(Индекс),
			"catalog.product.list?" + ПараметрыВСтрокуЗапроса(ПараметрыПоиска));
		
	КонецЦикла;
	
	Параметры = Новый Структура;
	Параметры.Вставить("halt", 0);
	Параметры.Вставить("cmd", Команды);
	
	Ответ = ИнтеграцияБитрикс24.ВыполнитьМетод("batch", Параметры);
	
	Если НЕ Ответ.Успешно Тогда
		ВызватьИсключение "Не удалось выполнить пакет поиска товаров: " + Ответ.ОписаниеОшибки;
	КонецЕсли;
	
	// Соответствие: внешний код — идентификатор товара в Битрикс24
	НайденныеТовары = Новый Соответствие;
	РезультатыКоманд = Ответ.Результат.Получить("result");
	
	Для Индекс = 0 По ВнешниеКоды.Количество() - 1 Цикл
		
		РезультатКоманды = РезультатыКоманд.Получить("find" + Строка(Индекс));
		
		Если РезультатКоманды = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Товары = РезультатКоманды.Получить("products");
		
		Если Товары <> Неопределено И Товары.Количество() > 0 Тогда
			НайденныеТовары.Вставить(ВнешниеКоды[Индекс],
				ИнтеграцияБитрикс24.ИдентификаторИзОтвета(Товары[0].Получить("id")));
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат НайденныеТовары;
	
КонецФункции

Функция ПараметрыВСтрокуЗапроса описана в туториале Как выгрузить список объектов Битрикс24 в 1С. Разбивайте номенклатуру на порции по 50 позиций — это максимум подзапросов в одном пакете.

Ошибки и диагностика

Если метод вернул ошибку, проверьте данные запроса.

Ошибка

Причина и решение

200040300040

Недостаточно прав для создания товара. Вебхук должен быть создан администратором Битрикс24

200040300000

Инфоблок с указанным iblockId не существует. Возьмите идентификатор из ответа catalog.catalog.list

Required select fields: iblockId

В параметре select методов catalog.product.* не переданы обязательные поля id и iblockId

200040300020 в catalog.price.add

Недостаточно прав на изменение цены продажи товара

Validate price error. Catalog price group is wrong

Неверный тип цены. Получите его идентификатор методом catalog.priceType.list

Validate price error. Catalog product is allowed has only single price without ranges in price group

Цена такого типа у товара уже есть. Обновите ее методом catalog.price.update

100

Не указан или пустой параметр fields

Что важно учитывать

  • Услуги. Поле type товара доступно только для чтения, задать тип при создании нельзя. Услуги добавляют отдельным методом catalog.product.service.add
  • Разделы каталога. Группы номенклатуры переносят методами catalog.section.* и указывают раздел в поле iblockSectionId товара
  • Ставка НДС. Ставки хранятся отдельно: список возвращает метод catalog.vat.list, идентификатор ставки передают в поле vatId
  • Остатки. Складской учет ведут методы catalog.storeproduct.*. Поле quantity товара показывает общий остаток
  • Пометка удаления. Товары в Битрикс24 удобнее не удалять, а деактивировать: передайте active = "N". Тогда товар исчезнет из выбора, но останется в старых документах
  • Картинки. Изображение передают в поле previewPicture или detailPicture структурой {"fileData": ["имя_файла.jpg", "содержимое в Base64"]} — как файлы в других методах

Продолжите изучение