При интеграции 1С с системой маркировки «Честный знак» (ГИС МТ) одной из самых сложных задач является корректное подписание документов. Система True API требует передачи данных в строгом формате, где тело документа и его электронная подпись должны быть представлены в виде Base64. В этой статье мы подробно разберем, как автоматизировать создание документа "Вывод из оборота (ОСУ)" и научимся формировать открепленную электронную подпись программно.
Для того чтобы документ был успешно принят системой, нам необходимо выполнить следующие шаги:
Рассмотрим создание структуры документа для объемно-сортового учета (ОСУ) — есть автоматизация формирования выбытия для объемно-сортового учета. Здесь нам не нужны коды маркировки каждой единицы, достаточно 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.Закрыть();
Проанализируем ключевой момент: «Честный знак» требует, чтобы подписывался не сам текст 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). Наличие лишних невидимых символов в начале строки сделает подпись невалидной.
Теперь мы объединим все части. Финальный объект для отправки в 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
Рассмотрим ситуации, с которыми часто сталкиваются разработчики:
POST. Также убедитесь, что адрес сервера указан верно (для продуктового контура и песочницы они разные).inn). Также проверьте, что вы подписываете именно ту строку, которую передаете в product_document.document_id из ответа и позже проверить статус обработки документа через запрос GET /api/v3/true-api/documents/{number}/info.Мы проанализировали процесс работы с True API и выяснили, что секрет успеха заключается в правильной последовательности кодирования и использования флага bDetached = Истина в объекте CAdESCOM. Следуя этой инструкции, вы сможете настроить обмен документами с «Честным знаком» в любой конфигурации 1С.