До начала работы по новым правилам остаются считанные дни, а чёткой конкретной технической информации практически нет. В основном ищется только "вода", как это будет в общем, но в конфигураторе это не пропишешь.
Ждать 30 июня, когда 1С выпустит хоть какой-то функционал - не вариант. Начинать автоматизировать, менять бизнес-процессы, писать инструкции, обучать персонал нужно уже сейчас. Поэтому в данный момент разбираюсь в этом вопросе.
Тут решил в виде заметок попытаться внести хоть какую-то ясность в процесс маркировки обуви с технической стороны. Может, это окажется кому-то полезным, может, кто-то продвинулся дальше и сможет поделиться своим опытом.
Как на текущий момент я понимаю процесс.
Есть три основные информационные системы, с которыми придётся работать для выполнения требований нового закона:
- система работы с кодами GTIN от организации GS1,
- система управления заказами от организации ЦРПТ (СУЗ),
- система маркировки и прослеживаемости от организации ЦРПТ (ИС МП).
Хорошая новость в том, что эти системы предоставляют API, т. е. через HTTP запросы можно подать JSON / XML документы и получить что-то на выходе. Описание API в системах есть.
Как можно получить готовый код маркировки (а в конечном итоге работа идёт именно с ним) вручную:
1) В систему GS1 загружается Excel файл с описанием товара (материал, размер, производитель и т.д.), на выходе получаем код GTIN. Этот код будет целиком включён в итоговый код маркировки.
2) В системе СУЗ создаётся заявка на выпуск кодов маркировки, указывается GTIN и некоторая служебная информация.
3) В системе ИС МП нужно отправить в работу черновик, созданный на предыдущем этапе. Тут будет нужна цифровая подпись.
4) В системе СУЗ через некоторое время можно скачать готовые коды в виде PDF файла.
Если попробовать автоматизировать пункты выше:
1) С этим API пока не разбирался, есть автоматическое формирование Excel файла по шаблону, пока этого достаточно.
2) Тут наконец-то начинается что-то интересное. Нужно сформировать JSON объект и отправить его на нужный HTTP адрес, это есть в описании API.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Accept", "application/json");
Заголовки.Вставить("clientToken", Токен_указанный_в_документации);
Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");
Соединение = Новый HTTPСоединение("suz.crpt.ru", Порт);
Запрос = Новый HTTPЗапрос("/api/orders", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Сообщить("Код состояния: " + Ответ.КодСостояния);
Для каждого ЗаголовокОтвета Из Ответ.Заголовки Цикл
Сообщить(" " + ЗаголовокОтвета.Ключ + " : " + ЗаголовокОтвета.Значение);
КонецЦикла;
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать
Вот что представляет собой строковая переменная Запрос:
orderLineId - идентификатор строки, потом по этому ID можно будет получить готовые коды,
gtin - уникальный код продукции из системы организации GS1,
codeTnVed - "Товарная номенклатура внешнеэкономической деятельности Евразийского экономического союза",
releaseMethodType - PRODUCTION - сами произвели, IMPORT - ввозим,
quantity - сколько хотим этикеток.
Далее идёт служебная информация, полный смысл которой пока для меня загадка.
identificationType - PRINTED - печатные, GLUED - наклейки, HINGED - навесные,
serialNumberType - SELF_MADE - выпускаем сами, OPERATOR - выпускает ИС МП,
markingType - PRODUCT_PACKAGE - на потребительскую упаковку, PRODUCT - на товар, PRODUCT_LABEL - на товарный ярлык,
templateId - 1 - Обувь, 2 - Фарма, 3 - Сиг/блк, 4 - Сиг/пач.
productionOrderId - свой произвольный идентификатор, по которому потом можно будет запрашивать состояние заказа.
Показать
После выполнения запроса сервер выдаёт ответ:
{
"orderId":"<новый внутренний идентификатор заявки в системе СУЗ>",
"expectedCompleteTimestamp":5000
}
3) При работе с ИС МП используется электронная подпись, поэтому, для её использования в запросах API, разработчики придумали генерацию специальных токенов, которые нужно указывать в заголовках HTTP запросов.
Сперва получаем от сервера исходные данные:
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");
Соединение = Новый HTTPСоединение("ismp.crpt.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/api/v3/auth/cert/key", Заголовки);
Попытка
Ответ = Соединение.Получить(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать
После выполнения запроса сервер выдаёт ответ вида:
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");
Соединение = Новый HTTPСоединение("ismp.crpt.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/api/v3/auth/cert/", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать
Вот что представляет собой строковая переменная Запрос:
{
"uuid": "b7b1abc9-f4ee-47db-8a20-f80ac83504e8",
"data": "<сгенерированный текст в Base64>"
}
uuid - получен ранее вместе с данными для подписи
После выполнения запроса сервер выдаёт ответ:
{"token":"<ваш новый сгенерированный токен>"}
Этот токен можно использовать для следующего шага - отправить в работу черновик заказа кодов маркировки.
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Authorization", "Bearer " + ВашНовыйСгенерированныйТокен);
Соединение = Новый HTTPСоединение("ismp.crpt.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/api/v3/facade/order/" + IDЗаказаИзСистемыСУЗ, Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать
Вот что представляет собой строковая переменная Запрос:
На данном моменте я пока и остановился, не могу понять по документации что записывать в "document" и в "signature".
К тому же через сутки сервер стал отвечать, что сгенерированный "Bearer token" истёк, и появился вопрос, как часто его нужно перегенерировать и нужно ли.
На этом у меня пока всё, буду писать в поддержку. Если тема будет кому-то интересна - напишу о результатах.
Спасибо за материал. Сейчас сам воюю с этой аутентификацией.
Но у меня выдает ошибку метод POST /api/v3/auth/cert/
<UnauthorizedException>
<error>unauthorized</error>
<error_description>Full authentication is required to access this resource</error_description>
</UnauthorizedException>
Данные подписал по ссылке в твоем посте(отдельное спасибо! не знал о существовании такого!)
Не подскажешь, бывало у тебя такое или нет? в веб морду по данному ключу я спокойно захожу, без проблем. А вот по API затык.
При обращении к "POST /api/v3/auth/cert/" такой ошибки точно не было. Нечто похожее было при обращении к методам, где нужен уже готовый Bearer токен.
Они же недавно какие-то глобальные работы проводили, две недели до 4 июня коды нельзя было заказывать. И сейчас, по крайней мере у нас, даже к СУЗу нет доступа (suz.crpt.ru:11127). Так что возможно, у них какие-то ошибки сейчас есть. А возможно они API поменяли, нужно смотреть, не обновилась ли у них документация по API (на ismp.crpt.ru в разделе помощи, я пока не смотрел).
Как вариант - писать в техподдержку на support@crpt.ru, мне в течении суток отвечали.
Сейчас ещё выложу сюда немного наработок. Получилось программно подписывать строки, без использования того сервиса по ссылке.
Мне обычно по 5 дней отвечают с суппорта ((
После проведенных работ нам пришел новый адрес СУЗ-а. Думаю тебе стоит обратиться к ним с уточнениями. Нам пришла инфа с изменениями в СУЗ-е в этот понедельник.
Я хочу попробовать проверить свой ключ. У меня вообще нифега не получается пройти этап получения токена. Поддержка мне морочит голову по поводу переводов строки, но я их выпиливаю так же как и ты.
(9)
подсмотрено в УТ11.4, думаю можно не хранить в регистре дату токена ее можно декодировать из самого токена
заменил в твоём коде запись на "декодировку" даты из token
// Сохранение токена.
//Запись = РегистрыСведений.Токены.СоздатьМенеджерЗаписи();
//Запись.Пользователь = Пользователь; // Измерение.
//Запись.Организация = Организация; // Измерение.
//Запись.Токен = РазборОтвета.token; // Ресурс.
//Запись.ДействуетДо = ТекущаяДатаСеанса() + 36000; // Токен действует 10 часов, потом его нужно перегенерировать. // Ресурс.
//Запись.Записать(Истина);
РезультатРазбораТокена = РасшифроватьТокенJWT(РазборОтвета.token);
Если РезультатРазбораТокена <> Неопределено Тогда
ДействуетДо = ДатаИзСтрокиUNIX(РезультатРазбораТокена.exp, 1);
КонецЕсли;
Сообщить(ДействуетДо);
Показать
функции которые взяты из УТ11.4
#Область JWT
Функция РасшифроватьТокенJWT(Токен) Экспорт
ВозвращаемоеЗначение = Новый Структура;
ВозвращаемоеЗначение.Вставить("РезультатРасшифровки", Неопределено);
ВозвращаемоеЗначение.Вставить("ТекстОшибки", "");
ЭлементыТокена = _СтрРазделить(Токен, ".");
Если ЭлементыТокена.Count() <> 3 Тогда
ВозвращаемоеЗначение.ТекстОшибки = НСтр("ru = 'Токен не соответствует формату JWT'");
Возврат ВозвращаемоеЗначение;
КонецЕсли;
ЭлементТокенаДанные = ЭлементыТокена[1];
Данные = ТекстJSONВОбъект(
ПолучитьСтрокуИзДвоичныхДанных(
ДвоичныеДанныеЭлементаТокенаJWT(ЭлементТокенаДанные)));
Возврат Данные;
КонецФункции
Функция ДвоичныеДанныеЭлементаТокенаJWT(Знач Значение)
Значение = СтрЗаменить(Значение, "-", "+");
Значение = СтрЗаменить(Значение, "_", "/");
Остаток = СтрДлина(Значение) % 4;
Если Остаток = 1 Тогда
Возврат Неопределено;
ИначеЕсли Остаток = 2 Тогда
Значение = Значение + "==";
ИначеЕсли Остаток = 3 Тогда
Значение = Значение + "=";
КонецЕсли;
Возврат Base64Значение(Значение);
КонецФункции
#КонецОбласти
#Область JSON
// Получить из текста JSON структуру.
//
// Параметры:
// ТекстJSON - Строка - Текст JSON.
// ПреобразовыватьВСоответствие - Булево - Признак преобразования в соответствие.
// Возвращаемое значение:
// Структура, Неопределено - Результат преобразования JSON.
Функция ТекстJSONВОбъект(ТекстJSON, ПреобразовыватьВСоответствие = Ложь) Экспорт
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстJSON);
Попытка
РезультатРазбора = ПрочитатьJSON(Чтение, ПреобразовыватьВСоответствие);
Исключение
РезультатРазбора = Неопределено;
КонецПопытки;
Возврат РезультатРазбора;
КонецФункции
// Формирует из структуры текст JSON
//
// Параметры:
// Структура - Структура - Произвольная структура данных
// Возвращаемое значение:
// Строка - Текст JSON
Функция ОбъектВТекстJSON(Структура, УдалитьПробелыИПереносыСтрок = Ложь) Экспорт
Если УдалитьПробелыИПереносыСтрок Тогда
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
Иначе
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " ");
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON();
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, Структура);
ТекстJSON = ЗаписьJSON.Закрыть();
Возврат ТекстJSON;
КонецФункции
#КонецОбласти
#Область РаботаСЧасовымиПоясами
Функция ДатаИзСтрокиUNIX(Значение, Делитель = 1000) Экспорт
Возврат МестноеВремя('19700101' + Цел(Значение / Делитель));
КонецФункции
#КонецОбласти
(3) Суть то в том, что у них 40% готово. Остальная часть багами и недоработками(Пытались заказать штрих коды через лк) Технической поддержки можно сказать нету
По результатам обращения в поддержку выяснилось, что:
- действительно, нужно каждый день генерировать новый "Bearer token";
- в параметр "document" помещается JSON или XML строка с описанием того же самого, что уже есть в черновике, а в параметр "signature" помещается этот же текст, но уже зашифрованный цифровой подписью с помощью сервиса КриптоПро (ссылка есть в первом посте).
Т. о. сейчас всё сводится к сервису КриптоПро. Каждый день руками генерировать новый токен грустно, и без этого сервиса не заполнить параметр "signature".
Буду пытаться программно воспользоваться сервисом. Сертификаты цифровой подписи, да через плагин в браузере... ммм, чудеса!
Может кто-нибудь сталкивался. с такой проблемой. Токен получаю нормально. а при подписи документа (в частности ввод в оборот импорт) приходит ответ со статусом 201, при чтении документа ошибка загрузки "Не пройдена проверка подпись".
Чтобы заработало подписание документа, необходимо в ПодписатьЭЦПЧерезСОМОбъекты передавать строку, закодированную в base64, и параметр СтрокаВBase64 устанавливать в Истину
После того как я создал и отправил документ с остатками обуви, как мне получить GTIN только что отправленных товаров? И какой запрос генерирует коды маркировки для заказа?
(21) https://demo.lp.crpt.tech Адрес из описания API ключ jwt токен получите дальше будет редирет и ошибка Full authentication is required to access this resource
Здравствуйте Не могу получить токен честный знак обувь.
Может кто знает как подписать сгенерированный текст через утилиту csptest пробую так:
csptest -sfsign -sign -in F:\doc.txt -out F:\signed_doc.txt -my xxx@mail.ru -detached -base64 -add
но полученный файл не проходит валидацию.
Делаю через сервис:
https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sample.html файл получается длинней валидацию проходит.
Подскажите куда копать?
(24) (57) Прошу помощи в понимании процесса. у меня 1С 7.7,
пытаюсь подписать X-Signature и совсем ничего не получается :-(
сначала что получается: получается подписать прикрепленной подписью запрос на токен командой
в файл TextForSigning.txt помещаю ТекстJSON, сделал его одной строкой и в нём нет "лишних" пробелов
подписывать пытаюсь ТекстJSON как без кодирования в base64, так и с кодирование в base64
из подписи удаляю переносы строк, вставляю в X-Signature
в тело запроса вставляю ТекстJSON без кодирования в base64
в результате orderStatus=DECLINED
может есть мысли что ещё подправить?
Добрый день.
Подскажите каким запросом заказывать коды маркировки в документации есть лишь пример тела документа. Если через /api/v3/lk/documents/create то какое значение указывать в параметре type? Может у кого есть более свежая документация по API чем эта https://честныйзнак.рф/upload/iblock/8b6/Opisanie-API-GIS-MP.pdf
Подскажите, где в итоге можно взять OMS ID и Токен?
Судя по всему нужно через интерфейс в личном кабинете добавить устройство и получить информацию оттуда. Но интерфейсе отсутствует такая возможность.
Кто-нибудь может рассказать, как через 1С вставить подпись при создании бизнес-заказа на эмиссию кодов маркировки в СУЗе? Без подписи - всё замечательно работает, но приходится вручную на сайте подписывать, а заказов может быть много. Какой день бьюсь - ничего не получается. У кого-то получилось вставить подпись в СУЗе?
После нескольких попыток создать документ с подписью вместе со специалистом СУЗа, вроде бы нашли ошибку, которая могла влиять на неработоспособность подписи. Мне хотя бы было понятно, в каком направлении копать. После уже моих многочисленных экспериментов, я, наконец-то, добился автоматического подписания документов в СУЗе. Всё дело было в передаваемом запросе Json, его обязательно необходимо преобразовать в одну строку. Причём, без подписи преобразовывать не обязательно, а с подписью - просто необходимо.
(35) А в какой формате подаете преобразованный json в строку? просто вместо {"products":[{"gtin":"... пишете <строка в base64> ? или это всё-равно json формат?
Чтото СУЗ отвечает, что подпись не прошла валидацию:
Order declined: Signature validation failed: message-digest attribute value does not match calculated value
Для генерации X_Signature
ДокВBase64 = СоздатьСтрокуBase64(ТекстСообщенияJSON);
///********************
Функция СоздатьСтрокуBase64(Строка) Экспорт
ДД_Файла = ПреобразованиеСтрокиВДвоичныеДанные(Строка);
СтрокаBase64 = Base64Строка(ДД_Файла);
Возврат СтрокаBase64;
КонецФункции
Функция ПреобразованиеСтрокиВДвоичныеДанные(Строка)Экспорт
Птк = Новый ПотокВПамяти;
ЗаписьТекста = Новый ЗаписьТекста(Птк, "UTF-8");
ЗаписьТекста.Записать(Строка);
ЗаписьТекста.Закрыть();
ДД_Файла = Птк.ЗакрытьИПолучитьДвоичныеДанные();
Возврат ДД_Файла;
КонецФункции
(60) Да.
Формирую тело файла как структуру. Работаю блочно, т.к. объединяю GTIN по 10 штук в 1 заказе.
Перевожу в каждую строку формата JSON
Для каждого Блок Из БлокЗаказов Цикл
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("contactPerson", Объект.КонтактноеЛицо.Наименование);
ТелоЗапроса.Вставить("releaseMethodType", Объект.СпособВыпускаТоваровВОборот.СУЗ);
ТелоЗапроса.Вставить("createMethodType", Объект.СпособИзготовления_СИ.СУЗ);
//ТелоЗапроса.Вставить("productionOrderId", Объект.ИдентификаторЗаявкиСУЗ);
ТелоЗапроса.Вставить("products", Новый Массив);
Для каждого Эл Из Блок.GTINs Цикл
Стр_ = Новый Структура;
GTIN_ = Эл.GTIN;
Пока СтрДлина(GTIN_)<14 Цикл
GTIN_ = "0"+GTIN_;
КонецЦикла;
Стр_.Вставить("gtin", GTIN_);
Стр_.Вставить("quantity", Эл.Количество_КМ);
Стр_.Вставить("serialNumberType", Эл.СпособФормированияСерийногоНомера.СУЗ);
//Стр_.Вставить("serialNumbers",);
Стр_.Вставить("templateId", 1);
ТелоЗапроса.products.Добавить(Стр_);
КонецЦикла;
Блок.ТекстСообщенияJSON = ВзаимодействиеИСМПСлужебный.ОбъектВТекстJSON(ТелоЗапроса, Истина);
КонецЦикла;
Функция ОбъектВТекстJSON(Структура, УдалитьПробелыИПереносыСтрок = Ложь) Экспорт
Если УдалитьПробелыИПереносыСтрок Тогда
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
Иначе
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, " ");
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON();
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, Структура);
ТекстJSON = ЗаписьJSON.Закрыть();
Возврат ТекстJSON;
КонецФункции
Показать
Подпись храню в 1С, проверяю на валидность, действительность и пр.
Поэтому получаю из неё отпечаток, для поиска и подписания по процедуре рекомендуемой ЦРПТ, указанной в 9.
Если ОтпечатокПодписи <> Неопределено и ОтпечатокПодписи <> "" тогда
Для каждого Блок Из РеквизитыИсходящегоСообщения.БлокЗаказов Цикл
ДокВBase64 = ВзаимодействиеИСМПСервер.СоздатьСтрокуBase64(Блок.ТекстСообщенияJSON);
ПодписанныйДокумент = ВзаимодействиеИСМП.ПодписатьЭЦПЧерезСОМОбъекты(ДокВBase64, Истина, ОтпечатокПодписи);
Блок.X_Signature = ВзаимодействиеИСМПСервер.УбратьСимволы1013(ПодписанныйДокумент);
КонецЦикла;
КонецЕсли;
Функция ПолучениеОтпечаткаСертификатаОрганизации(Организация_, ПеревестиВСтроку=Ложь) Экспорт
Отпечаток = "";
Если ЗначениеЗаполнено(Организация_.СертификатДляВзаимодействияС_ИСМП) тогда
Серт = Организация_.СертификатДляВзаимодействияС_ИСМП;
Если ПеревестиВСтроку тогда
Отпечаток = СтрЗаменить(Строка(Base64Значение(Серт.Отпечаток))," ","");
Иначе
Отпечаток = Base64Значение(Серт.Отпечаток);
КонецЕсли;
КонецЕсли;
Возврат Отпечаток;
КонецФункции
Функция СоздатьСтрокуBase64(Строка) Экспорт
ДД_Файла = ПреобразованиеСтрокиВДвоичныеДанные(Строка);
СтрокаBase64 = Base64Строка(ДД_Файла);
Возврат СтрокаBase64;
КонецФункции
Функция ПреобразованиеСтрокиВДвоичныеДанные(Строка)Экспорт
Птк = Новый ПотокВПамяти;
ЗаписьТекста = Новый ЗаписьТекста(Птк, "UTF-8");
ЗаписьТекста.Записать(Строка);
ЗаписьТекста.Закрыть();
ДД_Файла = Птк.ЗакрытьИПолучитьДвоичныеДанные();
Возврат ДД_Файла;
КонецФункции
Показать
Ну в принципе и все.
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("clientToken", ПараметрыСУЗ.Токен);
Если X_Signature <> Неопределено и X_Signature <> "" Тогда
ЗаголовокHTTP.Вставить("X-Signature", X_Signature);
КонецЕсли;
URLЗапроса = СтрШаблон(
URLЗапроса_V2("api/v2/extension/orders?omsId=%1", ВидПродукции),
ПараметрыСУЗ.Идентификатор);
Единственный форум нашел посвященный API в честном знаке. Пытаюсь через запрос в браузере получить токен, но не получается. Пишет ошибку <UnauthorizedException><error>unauthorized</error><error_description>Full authentication is required to access this resource</error_description></UnauthorizedException>
Можете прислать пример как это должно выглядеть в тексте?
(38)
Какое API имеете в виду для СУЗа токен можно получить в личном кабинете в разделе <Станция управления заказами><Устройства><Создать устройство>.
Для API МП если хотите попробовать в ручную получить токин, то делаете GET запрос https://ismp.crpt.ru/api/v3/auth/cert/key В ответ получаете JSON с атрибутами uuid и data это рандомная строка которую нужно подписать. Пишите данные из атрибута data в файлик doc.txt потом подписываете электронной подписью я использовал утилиту csptest такой командой
csptest -sfsign -sign -in F:\doc.txt -out F:\signed_doc.txt -my xxx@mail.ru -base64 -add
на выходе получаете signed_doc.txt убираете из файлика все переносы можно в notepad++ через найти и заманить включив галочку регулярные выражения указав в поиске сначала \n потом \r
Делаете POST запрос https://ismp.crpt.ru/api/v3/auth/cert/ с телом {"uuid": "ваш uuid","data": "подписанная строка"}
Как ни странно, но заработало... наверное. Проблема вроде кроется в инструменте для отправки запроса. На WEB сервере Текущая версия CURL 7.19 и возможно что то с ней не так. Сделал то же в Delphi(RIO) через Indy компоненту. Но Indy не возвращает нормальный ответ для кодов = > 400. Поэтому сменил компонент на TNetHttpClient и ответ стал приходить в JSON. Так как под рукой живых кодов нет пока, получаю STATUS = 404 ERROR = "Not found" и больше ничего.
Все сделано вроде как правильно, запросил GTIN, получил все GTINы, запросил коды маркировки, весит в документе статус: Обрабатывается в суз (генерация кодов) уже вторые сутки, делаю обмен, крутит обменивается с ИС МП минут 40 потом выдается измененные документы 0, статус в документе не меняется, кто сталкивался с такой проблемой, что можно предпринять в таком случае!???
Добрый день! Подскажите, плиз... Есть отдельно напечатанные наклейки, есть остатки обуви. Как сопоставить код и номенклатуру в 1С ут 11? В документе "Маркировка товаров ИС МП"? Есть сканер подключенный... Но к номенклатуре не привязаны штрих-коды.... как мне внести маркировку?
Добрый день! А у кого-нибудь получилось подписать открепленной подписью исходящий документ, например, отгрузку? Я сколько не мучил CADES - не получается, сервер возвращает ошибку "201" и каждый раз разный UID и всё... И этот UID не документа точно, документов новых не появляется.
Есть у кого нормальный пример получения открепленной УКЭП ?
Двоичные данные на 8.2 я разматывал через ТекстовыйДокумент
Функция ЗашифроватьBase64ЧерезФайл(ИсходнаяСтрока) Экспорт
ВремФайл = ПолучитьИмяВременногоФайла();
Тхт = Новый ТекстовыйДокумент;
Тхт.УстановитьТекст(ИсходнаяСтрока);
Тхт.Записать(ВремФайл, "CESU-8");
Бинарник = Новый ДвоичныеДанные(ВремФайл);
Тхт = Неопределено;
УдалитьФайлы(ВремФайл);
Возврат Base64Строка(Бинарник);
КонецФункции //ЗашифроватьBase64ЧерезФайл()
Функция РасшифроватьBase64ЧерезФайл(ВходСтр) Экспорт
ВремФайл = ПолучитьИмяВременногоФайла();
Бинарник = Base64Значение(ВходСтр);
Если Бинарник = Неопределено Или Бинарник.Размер() = 0 Тогда
Сообщить("Входная строка не является строкой в формате Base64");
Возврат "";
КонецЕсли;
Бинарник.Записать(ВремФайл);
Тхт = Новый ТекстовыйДокумент();
Тхт.Прочитать(ВремФайл, "CESU-8");
Стр = Тхт.ПолучитьТекст();
Тхт = Неопределено;
УдалитьФайлы(ВремФайл);
Возврат Стр;
КонецФункции //РасшифроватьBase64ЧерезФайл()
ый UID и всё... И этот UID не документа точно, документов новых не появляется.
Есть у кого нормальный пример получения открепленной УКЭП ?
У меня получилось подписать.
Причём подписывал так же как и DATA для Токена....
Кстати "ошибку "201"" - это не ошибка =) Документ появится позже, может например через день. Смотрю дату поста, 2 дня назад, наверное они у вас уже появились! =)
Помогите, пожалуйста, разобраться с маркировкой, чтобы получить токен.. я получил гетом data, закинул data на КриптоПро, выбрал сертификат, подписал. теперь отправляю, чтобы получить токен, но выходит ошибка 401. как перевести файл в base64?
Делаю соединение на php. Вроде все получилось, токен получил, заказ отправил, теперь надо подписать.
Строку сформировал, но подпись не валидна, подписывал по аналогии с дата.
попробую пробелы порезать и все в одну строку впихнуть, может поможет...
Добрый день. Пытаюсь отправить акт списания, ни в какую. Ошибка 400.
Вопрос: X-Signature это подписанный документ в двоичных данных ? Что это вообще за заголовок ?
Запись = Новый записьJSON;
Запись.УстановитьСтроку();
Запись.ЗаписатьНачалоОбъекта();
запись.ЗаписатьИмяСвойства("address"); Запись.ЗаписатьЗначение(ст.адрес);
запись.ЗаписатьИмяСвойства("participantId"); Запись.ЗаписатьЗначение(параметрыСеанса.мрТекущаяОрганизация.головное.Код);
запись.ЗаписатьИмяСвойства("sourceDocNum"); Запись.ЗаписатьЗначение(ст.номерДок);
запись.ЗаписатьИмяСвойства("sourceDocDate"); Запись.ЗаписатьЗначение(формат(ст.датаДок, "ДФ=yyyy-MM-dd"));
запись.ЗаписатьИмяСвойства("dropoutReason"); Запись.ЗаписатьЗначение(ст.причина);
запись.ЗаписатьИмяСвойства("withChild"); Запись.ЗаписатьЗначение(true);
запись.ЗаписатьИмяСвойства("sntins");
Запись.ЗаписатьНачалоМассива();
для каждого пп из ст.массивКодов цикл
запись.ЗаписатьЗначение(пп);
конецЦикла;
Запись.ЗаписатьКонецМассива();
Запись.ЗаписатьКонецОбъекта();
СериализованнаяСтрока = Запись.Закрыть();
ПолеФормы = Новый Структура;
ПолеФормы.Вставить("ИмяПоля", "jsonFile");
ПолеФормы.Вставить("ИмяФайла", "data.json");
ПолеФормы.Вставить("Тип", "application/json");
ПолеФормы.Вставить("Тело", СериализованнаяСтрока);
ПоляФормы = Новый Массив;
ПоляФормы.Добавить(ПолеФормы);
ДанныеПреобразования = ДвоичныеДанныеPOSTЗапросаКакФорма(ПоляФормы);
ТелоЗапроса = ДанныеПреобразования.ДвоичныеДанные;
Размер = ДанныеПреобразования.Размер;
ТокенДоступа = вернутьТокен();
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
HTTPСоединение = Новый HTTPСоединение("markirovka.crpt.ru", 443, ,,, 60, ЗащищенноеСоединение);
ЗаголовокHTTP = Новый Соответствие();
а = СоздатьСтрокуBase64(мрМаркировка.подписатьЭлементомСписка(СоздатьСтрокуBase64(СериализованнаяСтрока), 1, истина));
отв = мрМаркировка.ОбъектВТекстJSON(ДанныеПреобразования.запросСтрокой);
отв1 = мрМаркировка.ОбъектВТекстJSON(СериализованнаяСтрока);
размер = стрДлина(отв);
ЗаголовокHTTP.Вставить("X-Signature", а);
ЗаголовокHTTP.Вставить("Content-Type", "multipart/form-data; boundary="+ДанныеПреобразования.Разделитель);
//ЗаголовокHTTP.Вставить("Content-Type", "multipart/form-data");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
//Размер = стрДлина(СоздатьСтрокуBase64(ДанныеПреобразования.запросСтрокой));
ЗаголовокHTTP.Вставить("Content-Lenght", Формат(Размер, "ЧН=0; ЧГ=0;"));
ЗаголовокHTTP.Вставить("Authorization", "Bearer " + ТокенДоступа);
URLЗапроса = "/api/v3/true-api/documents/dropped-out/create";
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
HTTPЗапрос.УстановитьТелоИзСтроки(отв);
Ответ1 = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ответ = Ответ1.ПолучитьТелоКакСтроку();