Как получить список марок (КИЗ/SGTIN) и их сроки годности из Честного ЗНАКа через API в 1С, особенно для товаров ОСУ?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← К списку

При работе с маркированными товарами в системе 1С и интеграции с Честным ЗНАКом (ЧЗ) часто возникает задача получения актуальной информации о кодах идентификации (КИЗ/SGTIN) и их сроках годности. Эта задача может быть особенно сложной для товаров, учитываемых по Объемно-Сортовому Учету (ОСУ), таких как молочная продукция, когда участник оборота не является владельцем марок. Давайте подробно разберем, как подойти к решению этой проблемы.

1. Общая стратегия получения данных из Честного ЗНАКа

Прежде всего, давайте выясним причину сложности. Честный ЗНАК не всегда предоставляет прямой API-метод для получения полного списка всех марок, числящихся на участнике оборота, особенно если речь идет о миллионах позиций. Рассмотрим два основных подхода:

  1. Прямые API-запросы: Подходят для получения информации по конкретным маркам или небольшим выборкам, с использованием фильтров и пагинации.
  2. Механизм "выгрузок": Рекомендуется Честным ЗНАКом для получения больших объемов данных. В этом случае вы заказываете выгрузку по нужным критериям, и через некоторое время (которое может зависеть от загруженности системы ЧЗ) получаете сформированный файл с запрошенными данными. Этот файл затем необходимо загрузить и обработать в 1С.

Важный момент: Если ваш товарооборот исчисляется миллионами марок в год, прямые API-запросы могут оказаться неэффективными или даже невозможными из-за ограничений на количество возвращаемых данных и необходимости циклической обработки пагинации. В таких сценариях механизм "выгрузок" будет предпочтительнее.

2. Использование API-метода `/api/v4/true-api/cises/search` для получения списка КИЗ

Для получения информации о списке кодов идентификации (КИ) по заданным фильтрам, Честный ЗНАК предоставляет актуальный POST-метод /api/v4/true-api/cises/search. Этот метод позволяет запросить коды маркировки группы товаров за определенный период.

2.1. Формирование HTTP-запроса

Для взаимодействия с API Честного ЗНАКа нам потребуется:

  1. Защищенное соединение: Используем ЗащищенноеСоединениеOpenSSL.
  2. HTTP-соединение: Создаем объект HTTPСоединение с адресом markirovka.crpt.ru и портом 443.
  3. Заголовки HTTP: Обязательно передаем Content-Type: application/json, Accept: application/json, а также Authorization с вашим Bearer-токеном.
  4. Тело запроса (JSON): Это самый важный элемент, содержащий параметры фильтрации и пагинации.

Рассмотрим пример формирования запроса на стороне 1С (на основе примеров из обсуждения):


&НаКлиенте
Функция ПолучитьКИЗПоФильтрам(ТокенДоступа, GTIN, СтатусМарки, ДатаЭмиссииС)
            
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
    HTTPСоединение = Новый HTTPСоединение("markirovka.crpt.ru",443,,,,60,ЗащищенноеСоединение);

    ЗаголовокHTTP = Новый Соответствие();
    ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=UTF-8");
    ЗаголовокHTTP.Вставить("Accept", "application/json");
    ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
    ЗаголовокHTTP.Вставить("Authorization",   "Bearer " + ТокенДоступа);
    
    // Формируем тело запроса
    ТелоЗапросаJSON = СформироватьТелоЗапросаДляCisesSearch(GTIN, СтатусМарки, ДатаЭмиссииС); // Отдельная функция для формирования тела
    
    URLЗапроса = "/api/v4/true-api/cises/search";
    
    HTTPЗапрос  = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапросаJSON, КодировкаТекста.UTF8); // Тело запроса передается в POST-запросе
        
    Ответ = HTTPСоединение.Отправить(HTTPЗапрос); // Для POST используем Отправить
    
    ИДДок = Ответ.ПолучитьТелоКакСтроку();

    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(ИДДок);
    
    РезультатРазбора = ПрочитатьJSON(Чтение, ложь);
        
    Возврат РезультатРазбора;
    
КонецФункции

// Пример вспомогательной функции для формирования тела запроса (на основе 1С 7.7, адаптировано)
Функция СформироватьТелоЗапросаДляCisesSearch(GTIN, СтатусМарки, ДатаЭмиссииС)
    // В 1С 8.3 используем объекты типа Структура, Массив, Соответствие для формирования JSON
    Фильтр = Новый Соответствие();
    
    // Параметры фильтрации
    ПараметрыФильтра = Новый Соответствие();
    Если ЗначениеЗаполнено(GTIN) Тогда
        МассивGTIN = Новый Массив();
        МассивGTIN.Добавить(GTIN);
        ПараметрыФильтра.Вставить("gtins", МассивGTIN);
    КонецЕсли;

    Если ЗначениеЗаполнено(СтатусМарки) Тогда
        МассивСтатусов = Новый Массив();
        Статус = Новый Соответствие();
        Статус.Вставить("status", СтатусМарки);
        МассивСтатусов.Добавить(Статус);
        ПараметрыФильтра.Вставить("states", МассивСтатусов);
    КонецЕсли;
    
    // Дополнительные фильтры, например, productGroups
    МассивГруппПродукции = Новый Массив();
    МассивГруппПродукции.Добавить("milk"); // Пример для молочной продукции
    ПараметрыФильтра.Вставить("productGroups", МассивГруппПродукции);

    Фильтр.Вставить("filter", ПараметрыФильтра);
    
    // Параметры пагинации
    Пагинация = Новый Соответствие();
    Пагинация.Вставить("perPage", 1000); // Максимальное количество марок на странице
    // lastEmissionDate - дата "ПО", а не "С"
    // sgtin - SGTIN, с которого начинать вывод (для последующих страниц)
    Если ЗначениеЗаполнено(ДатаЭмиссииС) Тогда
        // Форматируем дату в формат "YYYY-MM-DDTHH:MM:SS.000Z"
        Пагинация.Вставить("lastEmissionDate", Формат(ДатаЭмиссииС, "ДФ=yyyy-MM-ddTHH:mm:ss.000Z"));
    КонецЕсли;
    //Пагинация.Вставить("sgtin", "SGTINПоследнейМаркиПредыдущегоЗапроса"); // Передавать для получения следующей страницы

    Фильтр.Вставить("pagination", Пагинация);

    Возврат ЗаписатьJSON(Фильтр, , , Ложь); // Записываем структуру в JSON-строку
КонецФункции

Обратите внимание, что URL запроса для метода /cises/search не содержит параметров в строке, они передаются в теле POST-запроса.

2.2. Параметры фильтрации и пагинации

Давайте подробнее разберем ключевые параметры, которые передаются в теле запроса:

  1. filter: Объект, содержащий критерии отбора марок.
    • gtins: Массив GTIN'ов, по которым нужно получить информацию.
    • states: Массив статусов КИЗ (например, EMITTED - эмитирован, APPLIED - нанесен).
    • productGroups: Массив товарных групп (например, milk для молочной продукции).
    • Можно также использовать другие фильтры, такие как дата производства (productionDate).
  2. pagination: Объект для управления страничным выводом.
    • perPage: Количество марок на одной странице (максимально 1000).
    • lastEmissionDate: Важная особенность! В документации этот параметр может быть описан как "дата С которой выводится результат", но фактически он работает как "дата ПО". То есть, он определяет верхнюю границу даты эмиссии для выбираемых марок. Если передать дату заведомо меньше даты эмиссии самого первого КМ, список может быть пустым.
    • sgtin: Для получения следующей страницы результатов, сюда необходимо передавать SGTIN последней марки, полученной в предыдущем ответе.
    • direction: Направление выборки.

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

Лимиты: Максимальный лимит кодов в ответе с учётом пагинации составляет 10 000. Если вам нужно больше, придется использовать механизм "выгрузок".

2.3. Получение срока годности

Хотя напрямую отфильтровать по сроку годности в запросе /cises/search нельзя, в ответе API присутствует поле expirationDate. Это означает, что вы получите срок годности вместе с остальной информацией по марке. Вам останется только обработать полученный JSON-ответ и извлечь нужные данные.

Пример фрагмента JSON-ответа:


{
    "filter": {...},
    "pagination": {...},
    "cisList": [
        {
            "sgtin": "0104600600000000021200000000000000000000000",
            "gtin": "04600600000000",
            "expirationDate": "2027-02-14T00:00:00Z", // Срок годности
            "cisStatus": "EMITTED",
            // ... другие поля ...
        },
        // ... другие КИЗ ...
    ],
    "isLastPage": false // true, если это последняя страница
}

3. Особенности работы с товарами Объемно-Сортового Учета (ОСУ)

Для молочной продукции и некоторых других товарных групп часто применяется Объемно-Сортовой Учет (ОСУ). Это означает, что на определенных этапах движения товара (например, от оптовика к рознице) в систему маркировки передается только код товара (GTIN) и количество отгружаемого маркированного товара, без поштучной (помарочной) детализации.

Что это значит для нас:

  1. Отсутствие "собственных" марок: Участник оборота (например, розничный магазин), работающий по ОСУ, не является владельцем марок в системе ЧЗ. Марки числятся на производителе или импортере, который их заказал, нанес и ввел в оборот. Соответственно, через API вы не сможете получить список марок, "числящихся на вас", потому что их на вас нет.
  2. Проблема со сроками годности: Если марок нет в вашей базе ЧЗ, то и получить их сроки годности через API по списку GTIN'ов не получится.
  3. Решение для ОСУ: Единственный надежный способ проверить сроки годности для товаров ОСУ — это физическое сканирование фактически имеющихся в наличии марок (например, с помощью ТСД с 2D-сканером). После сканирования вы получите конкретный SGTIN, по которому уже сможете сделать запрос к API ЧЗ (используя /api/v4/true-api/cises/search с фильтром по конкретному SGTIN) и получить его expirationDate.

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

4. Получение списка GTIN'ов участника оборота

Для получения списка кодов товаров (GTIN) участника оборота товаров (УОТ) существует метод /api/v4/true-api/product/gtin. Однако, как показала практика, этот метод может возвращать только те GTIN, которые сам участник оборота регистрировал в "Национальном каталоге". GTIN'ы, полученные от поставщиков (например, через ЭДО), могут в этом списке не отображаться.

Поэтому, если вам нужен полный список GTIN'ов товаров, которые вы продаете, скорее всего, придется использовать данные из вашей учетной системы (1С), а не только из API ЧЗ.

5. Токены авторизации TrueAPI

Для аутентификации в TrueAPI используются JWT-токены. Существуют разные типы токенов:

  1. "Единый токен в формате UUID": Может использоваться для определенных операций.
  2. "Длинный" токен в формате JWT: Действует дольше (например, до 01.03.2026), но его получение может быть более сложным.
  3. Динамический токен авторизации: Действует до 10 часов, после чего его необходимо получать повторно. Для получения такого токена необходимо пройти цепочку от метода /auth/key к методу /auth/simpleSignIn, каждый раз взаимодействуя по одному и тому же УКЭП.

Важно: Убедитесь, что используемый токен актуален и имеет необходимые права для выполнения запросов к TrueAPI.

Заключение

Мы видим, что получение списка марок и их сроков годности из Честного ЗНАКа через API в 1С — это задача, требующая детального понимания работы API и особенностей учета товаров. Для небольших объемов и целевых запросов метод /api/v4/true-api/cises/search является рабочим инструментом, позволяющим получить нужные данные, включая сроки годности. Однако для товаров ОСУ и больших объемов, где марки не числятся на текущем участнике оборота, или количество марок превышает API-лимиты, необходимо рассматривать альтернативные подходы, такие как физическое сканирование или использование механизма "выгрузок" Честного ЗНАКа. Всегда внимательно изучайте актуальную документацию API и тестируйте запросы, чтобы избежать неожиданных результатов.

← К списку