Как выбрать API торгового каталога

В торговом каталоге API выбирают по задаче. Чтение, запись данных, карточка товара и складские операции работают через разные классы. Если перепутать их, цена не попадет в расчет. Остаток изменится без складского движения, элемент инфоблока не станет товаром, а события модуля не сработают.

Сначала определите, что меняется: карточка товара, товарные параметры, цена, складской остаток, скидка, купон, комплект, подписка или профиль обмена. Затем выберите, чем работать: ORM-таблицей, D7-моделью или классическим API. После записи проверьте данные через ORM-таблицу, например \Bitrix\Catalog\ProductTable или \Bitrix\Catalog\PriceTable.

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

Перед операциями с товарами подключите модули iblock и catalog. Для купонов, корзины, заказа и расчета скидок может понадобиться модуль sale.

Как выбрать между ORM, D7-моделями и классическим API

Разделите задачу по ответственности. Чтение, запись и операции с внутренними правилами каталога решают разные группы классов.

Читайте через ORM-таблицы D7. Если нужно получить товары, цены, остатки, склады, типы цен или справочники, используйте классы вида \Bitrix\Catalog\*Table. Например, \Bitrix\Catalog\ProductTable::getList() или \Bitrix\Catalog\PriceTable::getList(). Эти классы подходят для выборок, фильтров, сортировки и проверки результата после записи.

Записывайте товарные данные через D7-модели. Если нужно создать, обновить или удалить товарные параметры, цену или НДС, используйте классы \Bitrix\Catalog\Model\Product, \Bitrix\Catalog\Model\Price, \Bitrix\Catalog\Model\Vat. Модели проверяют данные и возвращают объект результата. Он содержит ошибки валидации, которые можно обработать сразу.

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

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

Не заменяйте API прямой записью в таблицы. Прямая запись может обойти проверки, события и пересчет доступности.

Товары и торговые предложения

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

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

Задача

Метод

Пояснение

Создать инфоблок товаров

\CIBlock::Add()

Инфоблок хранит карточки товаров: названия, коды, свойства, разделы и изображения

Зарегистрировать инфоблок как каталог

\CCatalog::Add()

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

Шаг 1: создать карточку товара

\CIBlockElement::Add()

Карточка товара остается элементом инфоблока, поэтому контентные поля создают через API инфоблоков

Шаг 2: добавить товарные параметры

\Bitrix\Catalog\Model\Product::add()

Без товарной записи элемент останется карточкой и не станет товаром каталога

Создать родительский товар

\Bitrix\Catalog\Model\Product::add() с типом TYPE_SKU

Родительская карточка хранит общее описание товара, а цена и остаток относятся к торговым предложениям

Создать торговое предложение

\Bitrix\Catalog\Model\Product::add() с типом TYPE_OFFER

Торговое предложение хранит конкретный вариант товара, его цену и остаток

Создать услугу

\Bitrix\Catalog\Model\Product::add() с типом TYPE_SERVICE

Услуга продается как позиция каталога без складского остатка

Получить товарные параметры

\Bitrix\Catalog\ProductTable::getList()

ORM-таблица подходит для чтения типа товара, остатка и флага доступности без изменения данных

Обновить товарные параметры

\Bitrix\Catalog\Model\Product::update()

D7-модель меняет товарную запись и возвращает ошибки, если данные не прошли проверку

Получить торговые предложения товара

\CCatalogSKU::getOffersList()

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

Получить предложения перед удалением товара

\CCatalogSKU::getOffersList()

Метод возвращает варианты товара, которые нужно обработать до удаления родительской карточки

Удалить карточку товара или предложения

\CIBlockElement::Delete()

Карточку предложения удаляют до родительского товара, чтобы не оставить варианты без товара

Правило для торговых предложений: если у товара есть варианты, передавайте в PRODUCT_ID идентификатор предложения $offerId. Не используйте идентификатор родительского товара $productId для цены и остатка продаваемого варианта.

Базовые настройки: типы цен, НДС и единицы измерения

Подготовьте базовые настройки до массового создания товаров. Тип цены определяет, кто видит цену и может купить товар. НДС влияет на расчет налога. Единица измерения и коэффициент продажи задают, в каких количествах товар можно заказать.

Задача

Метод

Пояснение

Получить базовый тип цены

\Bitrix\Catalog\GroupTable::getBasePriceType()

Базовый тип цены нужен перед созданием первой цены товара

Создать тип цены

\CCatalogGroup::Add()

Классический метод сразу задает тип цены, языковые названия и права групп

Проверить права на тип цены

\Bitrix\Catalog\GroupAccessTable::getList()

Цена может существовать, но пользователь не увидит ее без прав на просмотр или покупку

Создать ставку НДС

\Bitrix\Catalog\Model\Vat::add()

D7-модель создает ставку с проверкой полей и возвращает ошибки в объекте результата

Назначить НДС товару

\Bitrix\Catalog\Model\Product::update()

НДС относится к товарной записи, поэтому его назначают через модель товара

Создать единицу измерения

\Bitrix\Catalog\MeasureTable::add()

Единицы измерения хранятся в справочнике каталога и затем назначаются товарам

Назначить единицу измерения товару

\Bitrix\Catalog\Model\Product::update()

Поле MEASURE находится в товарной записи, поэтому его меняют через модель товара

Добавить коэффициент продажи

\Bitrix\Catalog\MeasureRatioTable::add()

Метод создает шаг продажи для товара: например, покупать по одной штуке или упаковками

Обновить коэффициент продажи

\Bitrix\Catalog\MeasureRatioTable::update()

Метод меняет существующий шаг продажи, если коэффициент для товара уже задан

Если пользователь видит товар, но не видит цену или не может купить по ней, проверьте не только товар и остаток. Часто причина в правах на тип цены.

Цены

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

Перед обновлением цены найдите существующую запись по паре PRODUCT_ID и CATALOG_GROUP_ID. Если запись есть, обновите ее. Если записи нет, создайте новую. Такой порядок защищает от дублей цен.

Задача

Метод

Пояснение

Добавить цену товару

\Bitrix\Catalog\Model\Price::add()

Цена хранится отдельно от карточки и товарных параметров, поэтому ее создают отдельной моделью

Получить цены товара

\Bitrix\Catalog\PriceTable::getList()

ORM-таблица подходит для чтения всех цен товара по типам цен и валютам

Найти существующую цену перед изменением

\Bitrix\Catalog\Model\Price::getList()

Метод проверяет, есть ли цена для пары PRODUCT_ID и CATALOG_GROUP_ID

Обновить существующую цену

\Bitrix\Catalog\Model\Price::update()

Метод меняет найденную запись цены и не создает дубль для того же типа цены

Создать цену, если записи нет

\Bitrix\Catalog\Model\Price::add()

Метод создает новую цену, если для товара и типа цены еще нет записи

Создать диапазонную цену

\Bitrix\Catalog\Model\Price::add() с QUANTITY_FROM и QUANTITY_TO

Диапазонная цена нужна, когда стоимость зависит от количества товара

Получить цену для количества

\CCatalogProduct::GetNearestQuantityPrice()

Метод выбирает подходящую диапазонную цену для заданного количества

Рассчитать итоговую цену

\CCatalogProduct::GetOptimalPrice()

Метод учитывает права пользователя, скидки, купоны, диапазонные цены и сайт

Округлить цену по правилам типа цены

\Bitrix\Catalog\Product\Price::roundPrice()

Метод применяет правила округления, настроенные для типа цены

Не храните рабочую цену только в свойстве инфоблока. Корзина, заказ, скидки и права на типы цен работают с ценами каталога.

Склады и остатки

Остаток можно менять двумя способами. Если складской учет выключен, общий остаток хранится в товарной записи. Если складской учет включен и товар реально движется между складами, работайте через складские документы.

Задача

Метод

Пояснение

Обновить общий остаток и доступность

\Bitrix\Catalog\Model\Product::update()

Подходит для общего остатка, если складской учет выключен и движение по складам не нужно фиксировать документом

Создать склад

\CCatalogStore::Add()

Склад нужен до записи складских остатков и оформления складских документов

Получить список складов

\Bitrix\Catalog\StoreTable::getList()

ORM-таблица помогает выбрать склад для остатка, документа или проверки данных

Создать поставщика

\CCatalogContractor::add()

Поставщик нужен для приходных документов и истории поступления товаров

Добавить начальный остаток при первичной загрузке

\CCatalogStoreProduct::Add()

Метод создает запись остатка для стартовой загрузки, а не для обычного движения товара

Обновить начальный остаток при первичной загрузке

\CCatalogStoreProduct::UpdateFromForm()

Метод меняет существующую запись остатка при служебной корректировке

Проверить остатки по складам

\Bitrix\Catalog\StoreProductTable::getList()

Таблица показывает остатки конкретного товара или предложения по складам

Создать складской документ

\CCatalogDocs::add()

Документ сохраняет причину движения товара: приход, списание, перемещение или возврат

Провести документ

\CCatalogDocs::conductDocument()

Только проведенный документ меняет складские остатки

Отменить проведение

\CCatalogDocs::cancellationDocument()

Отмена снимает влияние документа без удаления истории операции

При рабочем складском учете не меняйте остатки прямой записью для сценариев с движением товара. Складской документ сохраняет саму операцию и меняет остатки после проведения.

Комплекты и наборы

Комплект продается как составной товар. Набор хранит рекомендации или связанные товары. Оба сценария работают через \CCatalogProductSet, но используют разные типы: TYPE_SET для комплекта и TYPE_GROUP для набора.

Задача

Метод

Пояснение

Создать товар-комплект

\Bitrix\Catalog\Model\Product::add() с типом \Bitrix\Catalog\ProductTable::TYPE_SET

Тип TYPE_SET сообщает каталогу, что товар продается как составной

Добавить состав комплекта

\CCatalogProductSet::add() с \CCatalogProductSet::TYPE_SET

Состав комплекта хранится отдельно от карточки товара и задается через \CCatalogProductSet

Получить состав комплекта

\CCatalogProductSet::getAllSetsByProduct()

Метод возвращает товары, которые входят в комплект

Изменить состав комплекта

\CCatalogProductSet::update()

Обновление заменяет состав на массив ITEMS, поэтому передавайте старые элементы заново, если они должны остаться

Создать набор рекомендаций

\CCatalogProductSet::add() с \CCatalogProductSet::TYPE_GROUP

Тип TYPE_GROUP описывает рекомендованные товары, а не состав продаваемого комплекта

Удалить комплект или набор

\CCatalogProductSet::delete()

Удаление убирает связь товаров из комплекта или набора

Не путайте комплект и набор. Комплект участвует в продаже как составной товар, а набор описывает рекомендации.

Скидки, купоны и подписки

Цена хранит исходную стоимость. Скидка меняет итоговую стоимость при расчете. Купон включает условие для скидки, а подписка помогает оформить уведомление о поступлении товара.

Задача

Метод

Пояснение

Создать скидку на товар

\CCatalogDiscount::Add()

Скидка хранит правило изменения цены и участвует в расчете итоговой стоимости

Создать купон

\Bitrix\Catalog\DiscountCouponTable::add()

Купон создают отдельной записью и связывают со скидкой через DISCOUNT_ID

Включить купоны для скидки

\Bitrix\Catalog\DiscountTable::setUseCoupons()

Флаг включает расчет скидки только по купону

Добавить купон в расчет

\Bitrix\Sale\DiscountCouponsManager::add()

Менеджер купонов передает купон в расчет цены с учетом модуля sale

Получить список активных скидок

\CCatalogDiscount::GetDiscountByProduct()

Метод показывает, какие скидки подходят товару, группам пользователя, типу цены и сайту

Подписать пользователя на наличие товара

\Bitrix\Catalog\Product\SubscribeManager::addSubscribe()

Подписка привязана к товару или предложению и хранит контакт для уведомления о поступлении

Не рассчитывайте скидку вручную. \CCatalogProduct::GetOptimalPrice() учитывает группы пользователя, купоны, диапазонные цены и сайт.

Импорт и экспорт

Импорт и экспорт работают через профили и PHP-шаблоны. Профиль отвечает за запуск, а шаблон выполняет обработку данных проекта.

Задача

Метод

Пояснение

Подготовить шаблон экспорта

PHP-шаблон экспорта

Шаблон описывает, какие данные выгружать и в каком формате

Создать профиль экспорта

\CCatalogExport::Add()

Профиль хранит настройки запуска экспорта и связывает их с шаблоном

Запустить экспорт по профилю

\CCatalogExport::PreGenerateExport()

Метод запускает профиль и подключает рабочий шаблон экспорта

Получить список профилей экспорта

\CCatalogExport::GetList()

Метод возвращает профили экспорта для программной проверки настроек

Получить профиль экспорта по идентификатору

\CCatalogExport::GetByID()

Метод возвращает настройки одного профиля экспорта

Обновить профиль экспорта

\CCatalogExport::Update()

Метод меняет настройки существующего профиля без ручной настройки в интерфейсе

Подготовить шаблон импорта

PHP-шаблон импорта

Шаблон описывает, как файл или внешний источник обновляет карточки, товарные параметры и цены

Создать профиль импорта

\CCatalogImport::Add()

Профиль хранит настройки запуска импорта и связывает их с шаблоном

Запустить импорт по профилю

\CCatalogImport::PreGenerateImport()

Метод запускает профиль и подключает рабочий шаблон импорта

Получить список профилей импорта

\CCatalogImport::GetList()

Метод возвращает профили импорта для программной проверки настроек

Получить профиль импорта по идентификатору

\CCatalogImport::GetByID()

Метод возвращает настройки одного профиля импорта

Обновить профиль импорта

\CCatalogImport::Update()

Метод меняет настройки существующего профиля импорта

Шаблон импорта или экспорта — это PHP-код проекта. Не передавайте в имя шаблона значения из запроса пользователя.

Типичные ошибки в коде каталога

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

Ошибка

Почему возникает проблема

Как делать

Создать элемент инфоблока и не добавить товарные параметры

Элемент останется карточкой, но не станет товаром каталога

После создания карточки вызывайте \Bitrix\Catalog\Model\Product::add()

Добавить цену родительскому товару с торговыми предложениями

Покупатель выбирает предложение, а цена должна относиться к продаваемому варианту

Передавайте идентификатор предложения в PRODUCT_ID

Создать новую цену без проверки существующей

Для одной пары товар и тип цены может появиться дубль

Сначала ищите цену через \Bitrix\Catalog\Model\Price::getList()

Хранить рабочую цену в свойстве инфоблока

Корзина, заказы, скидки и права на типы цен читают цены каталога

Работайте с ценой через модель \Bitrix\Catalog\Model\Price

Менять складские остатки напрямую при рабочем складском учете

Система не сохранит движение товара в документе

Проводите изменение остатка через складской документ

Читать цены или остатки в цикле по списку товаров

Возникают лишние запросы к базе. На большом каталоге страница начнет работать медленнее

Соберите идентификаторы товаров в массив и сделайте одну выборку с фильтром по списку

Рассчитывать скидку вручную

Ручной расчет может пропустить права пользователя, купоны, диапазонные цены и настройки сайта

Используйте \CCatalogProduct::GetOptimalPrice()

Сводная таблица устаревших методов

Старые методы могут встречаться в проектах, которые давно используют модуль catalog. При поддержке такого кода сначала проверьте текущий сценарий и риски замены. Для нового кода, новых примеров и автоматической генерации используйте классы из колонки Актуальная замена.

Задача

Устаревшие методы

Актуальная замена

Создать товарные параметры

\CCatalogProduct::Add()

\Bitrix\Catalog\Model\Product::add()

Обновить товарные параметры

\CCatalogProduct::Update()

\Bitrix\Catalog\Model\Product::update()

Удалить товарные параметры

\CCatalogProduct::Delete()

\Bitrix\Catalog\Model\Product::delete()

Создать цену

\CPrice::Add()

\Bitrix\Catalog\Model\Price::add()

Обновить цену

\CPrice::Update()

\Bitrix\Catalog\Model\Price::update()

Удалить цену

\CPrice::Delete()

\Bitrix\Catalog\Model\Price::delete()

Получить базовый тип цены

\CCatalogGroup::GetBaseGroup()

\Bitrix\Catalog\GroupTable::getBasePriceType()

Получить идентификатор базового типа цены

\CCatalogGroup::GetBaseGroupId()

\Bitrix\Catalog\GroupTable::getBasePriceTypeId()

Создать ставку НДС

\CCatalogVat::Add()

\Bitrix\Catalog\Model\Vat::add()

Обновить ставку НДС

\CCatalogVat::Update()

\Bitrix\Catalog\Model\Vat::update()

Удалить ставку НДС

\CCatalogVat::Delete()

\Bitrix\Catalog\Model\Vat::delete()

Создать единицу измерения

\CCatalogMeasure::add()

\Bitrix\Catalog\MeasureTable::add()

Обновить единицу измерения

\CCatalogMeasure::update()

\Bitrix\Catalog\MeasureTable::update()

Удалить единицу измерения

\CCatalogMeasure::delete()

\Bitrix\Catalog\MeasureTable::delete()

Передать купон в расчет скидки

\CCatalogDiscount::SetCoupon()

\Bitrix\Sale\DiscountCouponsManager::add()

Получить купоны для расчета

\CCatalogDiscount::GetCoupons()

\Bitrix\Sale\DiscountCouponsManager

Очистить купоны расчета

\CCatalogDiscount::ClearCoupon()

\Bitrix\Sale\DiscountCouponsManager

Определить инфоблок предложений по товару

\CCatalog::GetSkuInfoByProductID()

\CCatalogSKU::GetInfoByProductIBlock()

Определить связь предложений по свойству

\CCatalog::GetSkuInfoByPropID()

\CCatalogSKU::GetInfoByLinkProperty()

Получить расширенную информацию о каталоге

\CCatalog::GetByIDExt()

\CCatalogSKU::GetInfoByIBlock()