Как создать документ "Вывод из оборота (ОСУ)" в «Честный знак» через API из 1С и сформировать открепленную подпись?

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

При интеграции 1С с системой маркировки «Честный знак» (ГИС МТ) одной из самых сложных задач является корректное подписание документов. Система True API требует передачи данных в строгом формате, где тело документа и его электронная подпись должны быть представлены в виде Base64. В этой статье мы подробно разберем, как автоматизировать создание документа "Вывод из оборота (ОСУ)" и научимся формировать открепленную электронную подпись программно.

Общая схема взаимодействия с True API

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

  1. Получить токен авторизации (Bearer-токен) с использованием вашей УКЭП (ранее мы рассматривали схожее получение токена авторизации для других систем).
  2. Сформировать структуру JSON самого документа (данные о товарах, ИНН, причина выбытия).
  3. Преобразовать JSON документа в строку Base64.
  4. Подписать полученную Base64-строку с помощью криптографического объекта (CAdESCOM), получив открепленную подпись.
  5. Сформировать финальный конверт запроса, содержащий Base64 документа и Base64 подписи.
  6. Отправить POST-запрос на сервер «Честного знака».

Шаг 1: Формирование тела документа (JSON)

Рассмотрим создание структуры документа для объемно-сортового учета (ОСУ) — есть автоматизация формирования выбытия для объемно-сортового учета. Здесь нам не нужны коды маркировки каждой единицы, достаточно GTIN и количества. Разберем пример формирования данных на языке 1С. Чтобы гарантировать корректность данных, полезно реализовать проверку на заполненность обязательных полей в строке JSON перед кодированием:


ДанныеДляЗапроса = Новый Структура;
ДанныеДляЗапроса.Вставить("inn", СокрЛП(ВыбОрганизация.ИНН));
ДанныеДляЗапроса.Вставить("action", "UTILIZATION"); // Причина: Утилизация
ДанныеДляЗапроса.Вставить("action_date", Формат(ТекущаяДата(), "ДФ=yyyy-MM-dd"));
ДанныеДляЗапроса.Вставить("document_type", "DESTRUCTION_ACT"); // Акт уничтожения
ДанныеДляЗапроса.Вставить("document_number", "123");
ДанныеДляЗапроса.Вставить("document_date", Формат(ТекущаяДата(), "ДФ=yyyy-MM-dd"));
ДанныеДляЗапроса.Вставить("products", Новый Массив);

Для Каждого Стр Из ТабТовары Цикл
    СтрокаТЧ = Новый Структура;
    СтрокаТЧ.Вставить("gtin", Стр.gtin);
    СтрокаТЧ.Вставить("gtin_quantity", Стр.Количество);
    ДанныеДляЗапроса.products.Добавить(СтрокаТЧ);
КонецЦикла;

// Сериализация в JSON
Запись_JSON = Новый ЗаписьJSON;
Запись_JSON.УстановитьСтроку();
ЗаписатьJSON(Запись_JSON, ДанныеДляЗапроса);
СтрокаJSONДокумента = Запись_JSON.Закрыть();

Шаг 2: Подготовка данных и создание открепленной подписи

Проанализируем ключевой момент: «Честный знак» требует, чтобы подписывался не сам текст JSON, а его представление в Base64. Кроме того, подпись должна быть открепленной (detached). Это означает, что файл подписи не содержит в себе подписываемых данных.

Для работы с ЭЦП в 1С чаще всего используется библиотека CAdESCOM (КриптоПро ЭЦП Browser plug-in), однако в ряде случаев может применяться и универсальная подпись файла методами криптографии средствами платформы. Выясним, как реализовать функцию подписания:


Функция ПодписатьТекст(ТекстДляПодписиBase64, ОтпечатокСертификата, bDetached = Истина)
    
    // Константы CAdESCOM
    CADESCOM_BASE64_TO_BINARY = 1; // Входные данные — Base64
    CADESCOM_CADES_BES = 1;        // Тип подписи CAdES-BES
    
    Попытка
        oSigner = Новый COMОбъект("CAdESCOM.CPSigner");
        oSigner.Certificate = ПолучитьСертификатПоОтпечатку(ОтпечатокСертификата);
        
        // Опционально: добавляем время подписания
        oSigningTimeAttr = Новый COMОбъект("CAdESCOM.CPAttribute");
        oSigningTimeAttr.Name = 0; // CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
        oSigningTimeAttr.Value = ТекущаяДата();
        oSigner.AuthenticatedAttributes2.Add(oSigningTimeAttr);
        
        oSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
        oSignedData.ContentEncoding = CADESCOM_BASE64_TO_BINARY;
        oSignedData.Content = ТекстДляПодписиBase64;
        
        // Третий параметр Истина означает открепленную подпись
        // Четвертый параметр 0 — возвращать результат в Base64
        ПодписьBase64 = oSignedData.SignCades(oSigner, CADESCOM_CADES_BES, bDetached, 0);
        
        Возврат СтрЗаменить(ПодписьBase64, Символы.ПС, ""); // Убираем переносы строк
    Исключение
        Сообщить("Ошибка при подписании: " + ОписаниеОшибки());
        Возврат "";
    КонецПопытки;
    
КонецФункции

Важно: При конвертации JSON в Base64 перед подписанием, убедитесь, что вы не используете ByteOrderMark (BOM). Наличие лишних невидимых символов в начале строки сделает подпись невалидной.

Шаг 3: Сборка финального запроса

Теперь мы объединим все части. Финальный объект для отправки в POST запрос должен содержать формат документа, тип (для ОСУ это LK_GTIN_RECEIPT), тело документа в Base64 и саму подпись — для этого подойдёт автоматизация обмена с Честным знаком и вывода из оборота. Если вам необходимо работать с конкретными единицами товара, может потребоваться запрос информации кодов Честного знака или предварительное извлечение DataMatrix кодов из PDF документов для формирования списка products.


// 1. Кодируем JSON документа в Base64 (UTF-8 без BOM)
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, "UTF-8"); // Важно: без BOM
ЗаписьТекста.Записать(СтрокаJSONДокумента);
ЗаписьТекста.Закрыть();
ДД = Новый ДвоичныеДанные(ИмяВременногоФайла);
ТелоДокументаBase64 = Base64Строка(ДД);

// 2. Получаем открепленную подпись от Base64-строки документа
ПодписьBase64 = ПодписатьТекст(ТелоДокументаBase64, ОтпечатокСертификата, Истина);

// 3. Формируем финальную структуру для API
ФинальнаяСтруктура = Новый Структура;
ФинальнаяСтруктура.Вставить("document_format", "MANUAL");
ФинальнаяСтруктура.Вставить("product_document", ТелоДокументаBase64);
ФинальнаяСтруктура.Вставить("type", "LK_GTIN_RECEIPT");
ФинальнаяСтруктура.Вставить("signature", ПодписьBase64);

// 4. Отправляем через HTTPСоединение
// URL: /api/v3/true-api/documents/create

Типичные ошибки и способы их решения

Рассмотрим ситуации, с которыми часто сталкиваются разработчики:

Мы проанализировали процесс работы с True API и выяснили, что секрет успеха заключается в правильной последовательности кодирования и использования флага bDetached = Истина в объекте CAdESCOM. Следуя этой инструкции, вы сможете настроить обмен документами с «Честным знаком» в любой конфигурации 1С.

← На главную