Маркировка обуви, автоматизация через API

1. zer0911 26.04.19 08:57 Сейчас в теме
Всем привет.

До начала работы по новым правилам остаются считанные дни, а чёткой конкретной технической информации практически нет. В основном ищется только "вода", как это будет в общем, но в конфигураторе это не пропишешь.
Ждать 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", Заголовки);
Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);

Попытка
	Ответ = Соединение.ОтправитьДляОбработки(Запрос);
	Сообщить("Код состояния: " + Ответ.КодСостояния);
	Для каждого ЗаголовокОтвета Из Ответ.Заголовки Цикл
		Сообщить(" " + ЗаголовокОтвета.Ключ + " : " + ЗаголовокОтвета.Значение);
	КонецЦикла;
	ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
	Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать


Вот что представляет собой строковая переменная Запрос:
{
"products": [
{
"orderLineId": "<Новый УникальныйИдентификатор>",
"gtin": "<ваш GTIN, 14 символов>",
"codeTnVed": "<ваш ТН ВЭД, 4-10 символов>",
"releaseMethodType": "PRODUCTION",
"quantity": 1,
"identificationType": "GLUED",
"serialNumberType": "OPERATOR",
"markingType": "PRODUCT",
"templateId": 1
}
],
"productionOrderId": "<произвольный идентификатор>"
}

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", Заголовки);

Попытка
	Ответ = Соединение.Получить(Запрос);
	ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
Исключение
	Сообщить(ОписаниеОшибки());
КонецПопытки;
Показать


После выполнения запроса сервер выдаёт ответ вида:
{
"uuid":"b7b1abc9-f4ee-47db-8a20-f80ac83504e8",
"data":"QNRPNPFGJZFUXCERQMTWLRMBRNRAAP"
}


Далее нужно подписать строку "data" цифровой подписью используя сервис:
https://www.cryptopro.ru/sites/default/files/products/cades/demopage/cades_bes_sam­ple.html
После подписи получаем большой текст - данные в Base64.

Эти данные нужны для генерации самого токена:
Заголовки = Новый Соответствие;
Заголовки.Вставить("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": "",
"document_format": "MANUAL",
"signature": ""
}


На данном моменте я пока и остановился, не могу понять по документации что записывать в "document" и в "signature".
К тому же через сутки сервер стал отвечать, что сгенерированный "Bearer token" истёк, и появился вопрос, как часто его нужно перегенерировать и нужно ли.

На этом у меня пока всё, буду писать в поддержку. Если тема будет кому-то интересна - напишу о результатах.
whitedeath; AnimusKsy; oleg-x; clev; JedBez; sasha777666; +6
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
7. bruho 06.06.19 11:10 Сейчас в теме
(1) День добрый !

Спасибо за материал. Сейчас сам воюю с этой аутентификацией.

Но у меня выдает ошибку метод POST /api/v3/auth/cert/

<UnauthorizedException>
<error>unauthorized</error>
<error_description>Full authentication is required to access this resource</error_description>
</UnauthorizedException>

Данные подписал по ссылке в твоем посте(отдельное спасибо! не знал о существовании такого!)

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

Спасибо заранее за ответ
+
8. zer0911 07.06.19 05:29 Сейчас в теме
(7) Привет.

При обращении к "POST /api/v3/auth/cert/" такой ошибки точно не было. Нечто похожее было при обращении к методам, где нужен уже готовый Bearer токен.

Они же недавно какие-то глобальные работы проводили, две недели до 4 июня коды нельзя было заказывать. И сейчас, по крайней мере у нас, даже к СУЗу нет доступа (suz.crpt.ru:11127). Так что возможно, у них какие-то ошибки сейчас есть. А возможно они API поменяли, нужно смотреть, не обновилась ли у них документация по API (на ismp.crpt.ru в разделе помощи, я пока не смотрел).
Как вариант - писать в техподдержку на support@crpt.ru, мне в течении суток отвечали.

Сейчас ещё выложу сюда немного наработок. Получилось программно подписывать строки, без использования того сервиса по ссылке.
+
10. bruho 07.06.19 14:10 Сейчас в теме
(8)
ении суток о


Мне обычно по 5 дней отвечают с суппорта ((
После проведенных работ нам пришел новый адрес СУЗ-а. Думаю тебе стоит обратиться к ним с уточнениями. Нам пришла инфа с изменениями в СУЗ-е в этот понедельник.

В Целом спасибо за инфу.
+
19. vladnest 20.11.19 12:36 Сейчас в теме
(7) Ресурс для получения токена изменили на "/api/v3/facade/auth"
+
9. zer0911 07.06.19 05:43 Сейчас в теме
Делюсь наработками, надеюсь сэкономлю кому-то время.

Выделили общий модуль под нужды маркировки, вот что там самое интересное.

Функция УбратьСимволы1013(Строка) Экспорт
	Возврат СтрЗаменить(СтрЗаменить(Строка, Символы.ПС, ""), Символы.ВК, ""); // Ещё бывают символы "77u/", при необходимости удалять и их.
КонецФункции

Функция ПолучитьBase64СтрокуИзСтроки(Строка) Экспорт
	Возврат УбратьСимволы1013(ПолучитьBase64СтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(УбратьСимволы1013(Строка))));
КонецФункции

Функция ПолучитьСтрокуИзBase64Строки(Base64Строка) Экспорт
	Возврат ПолучитьСтрокуИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзBase64Строки(Base64Строка));
КонецФункции

Функция ПодписатьЭЦПЧерезСОМОбъекты(СтрокаДляПодписи, СтрокаВBase64 = Истина) Экспорт
	
	Попытка
		comStore = Новый COMОбъект("CAdESCOM.Store");
		comCPSigner = Новый COMОбъект("CAdESCOM.CPSigner"); // Аналог "CAPICOM.Signer".
		comSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
	Исключение
		Сообщить("Не установлен КриптоПро!");
		Возврат "";
	КонецПопытки;
	
	comStore.Open(
		2, // StoreLocation - CAPICOM_CURRENT_USER_STORE.
		"MY", // StoreName
		); // OpenMode - CAPICOM_STORE_OPEN_READ_ONLY.
	comCertificates = comStore.Certificates;
	comStore.Close();
	comStore = Неопределено;
	КоличествоСертификатов = comCertificates.Count;
	
	Если КоличествоСертификатов > 0 Тогда
		// Убрать "сертификаты, в которых отсутствует закрытый ключ".
		comCertificates = comCertificates.Find(6, 2); // (CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, CAPICOM_PROPID_KEY_PROV_INFO)
		КоличествоСертификатов = comCertificates.Count;
	КонецЕсли;
	Если КоличествоСертификатов > 0 Тогда
		// Оставить "только сертификаты, действительные в настоящее время".
		comCertificates = comCertificates.Find(9, ); // (CAPICOM_CERTIFICATE_FIND_TIME_VALID, "the current time is assumed")
		КоличествоСертификатов = comCertificates.Count;
	КонецЕсли;
	
	Если КоличествоСертификатов = 1 Тогда
		comСертификат = comCertificates.Item(1); // Выбрать единственный.
		
	ИначеЕсли КоличествоСертификатов = 0 Тогда
		comCertificates = Неопределено;
		comCPSigner = Неопределено;
		comSignedData = Неопределено;
		Сообщить("Не найдены актуальные ключи ЭЦП для подписи данных!");
		Возврат "";
		
	Иначе
		СертификатыДляВыбора = Новый СписокЗначений;
		Для i = 1 По КоличествоСертификатов Цикл
			СертификатыДляВыбора.Добавить(i, comCertificates.Item(i).SubjectName);
		КонецЦикла;
		
		i = СертификатыДляВыбора.ВыбратьЭлемент();
		Если i = Неопределено Тогда
			comCertificates = Неопределено;
			comCPSigner = Неопределено;
			comSignedData = Неопределено;
			Сообщить("Не выбран ключ ЭЦП!");
			Возврат "";
			
		Иначе
			comСертификат = comCertificates.Item(i.Значение); // Выбрать указанный пользователем.
			
		КонецЕсли;
		
	КонецЕсли;
	comCertificates = Неопределено;
	
	comCPSigner.Certificate = comСертификат;
	// + Что-то из этого может быть нужным.
//	comCPSigner.TSAAddress = "http://cryptopro.ru/tsp/";
//	comCPSigner.Options = 0; // CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT. Ещё есть CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN и CAPICOM_CERTIFICATE_INCLUDE_END_ENTITY_ONLY.
	// -
	comСертификат = Неопределено;
	
	Если СтрокаВBase64 Тогда // Очень важно!
		comSignedData.ContentEncoding = 1; // CADESCOM_BASE64_TO_BINARY
	//Иначе // Так и остаётся 0 - CADESCOM_ENCODE_BINARY
	КонецЕсли;
	comSignedData.Content = СтрокаДляПодписи;
	ПодписанныеДанные = comSignedData.SignCades(
		comCPSigner, // Signer
		1, // CadesType, CADESCOM_CADES_BES.
		Ложь, // bDetached - "флаг открепленной подписи (исходное сообщение не включается в итоговый CMS-контейнер)".
		); // EncodingType - по умолчанию CAPICOM_ENCODE_BASE64.
	
	comCPSigner = Неопределено;
	comSignedData = Неопределено;
	Возврат УбратьСимволы1013(ПодписанныеДанные);
	
КонецФункции

Функция РазобратьОтветJSON(ТекстJSON) Экспорт
	ЧтениеJSON = Новый ЧтениеJSON;
	ЧтениеJSON.УстановитьСтроку(ТекстJSON);
	Результат = ПрочитатьJSON(ЧтениеJSON);
	ЧтениеJSON.Закрыть();
	Возврат Результат;
КонецФункции
Показать


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

Функция СгенерироватьНовыйТокен(Пользователь = Неопределено, Организация) Экспорт
	
	Если Пользователь = Неопределено Тогда
		Пользователь = ПараметрыСеанса.ТекущийПользователь;
	КонецЕсли;
	
	// Получить случайные данные.
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");
	
	Соединение = Новый HTTPСоединение("ismp.crpt.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
	Запрос = Новый HTTPЗапрос("/api/v3/auth/cert/key", Заголовки);
	
	Попытка
		Ответ = Соединение.Получить(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
	Исключение
		Сообщить(ОписаниеОшибки());
		Соединение = Неопределено;
		Возврат "";
	КонецПопытки;
	
	РазборОтвета = МодульМаркировки.РазобратьОтветJSON(ТекстОтвета);
	ПодписанныеДанные = МодульМаркировки.ПодписатьЭЦПЧерезСОМОбъекты(РазборОтвета.data, Ложь);
	Если ПодписанныеДанные = "" Тогда
		Соединение = Неопределено;
		Возврат "";
	КонецЕсли;
	
	// Отправить подписанные случайные данные для получения токена.
	Запрос = Новый ЗаписьJSON;
	Запрос.ПроверятьСтруктуру = Ложь;
	Запрос.УстановитьСтроку();
	
	Запрос.ЗаписатьНачалоОбъекта();
	Запрос.ЗаписатьИмяСвойства("uuid");
	Запрос.ЗаписатьЗначение(РазборОтвета.uuid);
	Запрос.ЗаписатьИмяСвойства("data");
	Запрос.ЗаписатьЗначение(ПодписанныеДанные);
	Запрос.ЗаписатьКонецОбъекта();
	ТекстЗапроса = Запрос.Закрыть();
	
	Запрос = Новый HTTPЗапрос("/api/v3/auth/cert/", Заголовки);
	Запрос.УстановитьТелоИзСтроки(ТекстЗапроса);
	
	Попытка
		Ответ = Соединение.ОтправитьДляОбработки(Запрос);
		ТекстОтвета = Ответ.ПолучитьТелоКакСтроку();
	Исключение
		Сообщить(ОписаниеОшибки());
		Соединение = Неопределено;
		Возврат "";
	КонецПопытки;
	
	РазборОтвета = МодульМаркировки.РазобратьОтветJSON(ТекстОтвета);
	
	// Сохранение токена.
	Запись = РегистрыСведений.Токены.СоздатьМенеджерЗаписи();
	Запись.Пользователь = Пользователь; // Измерение.
	Запись.Организация = Организация; // Измерение.
	Запись.Токен = РазборОтвета.token; // Ресурс.
	Запись.ДействуетДо = ТекущаяДатаСеанса() + 36000; // Токен действует 10 часов, потом его нужно перегенерировать. // Ресурс.
	Запись.Записать(Истина);
	
	Возврат РазборОтвета.token;
	
КонецФункции
Показать
Bale; zKosha; clev; JedBez; itrous; AlexeyK1; user756412; Sиlьver; aparinp; +9
11. bruho 11.06.19 11:47 Сейчас в теме
(9) как с тобой связаться можно?

Я хочу попробовать проверить свой ключ. У меня вообще нифега не получается пройти этап получения токена. Поддержка мне морочит голову по поводу переводов строки, но я их выпиливаю так же как и ты.
+
12. zer0911 13.06.19 05:12 Сейчас в теме
(11) Можно тут в личку, я увижу.

Функция СгенерироватьНовыйТокен (выше) работает нормально, переводы строк убираются когда нужно.

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

Токен возвращается в формате, который можно посмотреть на сайте (вставить в поле Encoded). Можно посмотреть, например, когда токен заканчивается.
+
13. bruho 24.06.19 15:37 Сейчас в теме
(12) при попытке отправить сообщение в личку ошибка высплывает ..

Подскажи, в каком виде ты передаешь содержимое документа в метод ПодписатьЭЦПЧерезСОМОбъекты когда уже нужно создать документ в ИСМП ?

строку JSON? убираешь ли переводы строк?

Спасибо
+
16. aparinp 52 13.08.19 12:37 Сейчас в теме
(9) Что из софта нужно чтобы было установлено на компе/сервере?
+
27. AlexeyK1 14 21.01.20 11:16 Сейчас в теме
(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' + Цел(Значение / Делитель));
	
КонецФункции
#КонецОбласти

Показать
+
2. ranis888 104 26.04.19 10:06 Сейчас в теме
А отсрочку не утвердили?
+
3. zer0911 26.04.19 10:10 Сейчас в теме
(2) Не слышал о таком. Счётчик на сайте "Честного знака" до старта обязательной маркировки c 1 Июля 2019 г. неумолимо стремится к нулю )
+
4. ranis888 104 26.04.19 10:15 Сейчас в теме
(3) Нам отправили документ, где написано, что на рассмотрении отсрочка
+
5. ranis888 104 26.04.19 10:16 Сейчас в теме
(3) Суть то в том, что у них 40% готово. Остальная часть багами и недоработками(Пытались заказать штрих коды через лк) Технической поддержки можно сказать нету
+
6. zer0911 26.04.19 11:54 Сейчас в теме
По результатам обращения в поддержку выяснилось, что:
- действительно, нужно каждый день генерировать новый "Bearer token";
- в параметр "document" помещается JSON или XML строка с описанием того же самого, что уже есть в черновике, а в параметр "signature" помещается этот же текст, но уже зашифрованный цифровой подписью с помощью сервиса КриптоПро (ссылка есть в первом посте).

Т. о. сейчас всё сводится к сервису КриптоПро. Каждый день руками генерировать новый токен грустно, и без этого сервиса не заполнить параметр "signature".
Буду пытаться программно воспользоваться сервисом. Сертификаты цифровой подписи, да через плагин в браузере... ммм, чудеса!
+
14. dimabarkov 10.07.19 15:13 Сейчас в теме
Может кто-нибудь сталкивался. с такой проблемой. Токен получаю нормально. а при подписи документа (в частности ввод в оборот импорт) приходит ответ со статусом 201, при чтении документа ошибка загрузки "Не пройдена проверка подпись".
+
17. aparinp 52 14.10.19 12:21 Сейчас в теме
(14) Удалось победить проблему?
+
63. MegasXIII 04.06.20 13:33 Сейчас в теме
(14)
Решил проблему?

А то у меня подпись сменилась и случилась та жа беда.
+
65. MegasXIII 03.08.20 13:08 Сейчас в теме
(63)Удалось победить, дело не в подписи, а в том что я неправильно указывал, прикрепленная/откреплённая подпись или что то в этом роде.
+
66. mofik 06.08.20 11:28 Сейчас в теме
(65)Где указывали? Можно подробнее?
+
15. ShoesConcept 08.08.19 12:23 Сейчас в теме
А кто и на каких регистрах учет в конфигурации 1С реализует? Кто делал полноценный учет? Или только проверку кодов из ИС МП?
+
18. aparinp 52 15.10.19 14:45 Сейчас в теме
Чтобы заработало подписание документа, необходимо в ПодписатьЭЦПЧерезСОМОбъекты передавать строку, закодированную в base64, и параметр СтрокаВBase64 устанавливать в Истину
+
20. user1323100 06.12.19 14:17 Сейчас в теме
После того как я создал и отправил документ с остатками обуви, как мне получить GTIN только что отправленных товаров? И какой запрос генерирует коды маркировки для заказа?
+
21. skart84 13.12.19 13:54 Сейчас в теме
Добрый день.
Подскажите адрес тестового api. Кто-нибудь тестировал обмен именно на тестовом сервисе?
+
23. user1334907 27.12.19 14:51 Сейчас в теме
(21) https://demo.lp.crpt.tech
Адрес из описания API ключ jwt токен получите дальше будет редирет и ошибка Full authentication is required to access this resource
+
22. antonprog888 26.12.19 13:35 Сейчас в теме
Здравствуйте Не могу получить токен честный знак обувь.
Может кто знает как подписать сгенерированный текст через утилиту 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_sam­­ple.html
файл получается длинней валидацию проходит.
Подскажите куда копать?
+
24. antonprog888 04.01.20 13:23 Сейчас в теме
(22)
Нашел решение может кому пригодится. Параметр detached не нужен
csptest -sfsign -sign -in F:\doc.txt -out F:\signed_doc.txt -my xxx@mail.ru -base64 -add
bigmal; +1
58. Mx00 247 17.03.20 13:18 Сейчас в теме
(24) (57) Прошу помощи в понимании процесса. у меня 1С 7.7,
пытаюсь подписать X-Signature и совсем ничего не получается :-(
сначала что получается: получается подписать прикрепленной подписью запрос на токен командой
csptest.exe -sfsign -sign -in TextForSigning.txt -out SigningResult.txt -my 250e--332c -base64 -addsigtime -add

при этом ФайлДляПодписи НЕ нужно кодировать в base64 иначе не формирует токен.

теперь пробую подписать ТекстJSON открепленной подписью и ничего не получается
csptest.exe -sfsign -sign -in TextForSigning.txt -out SigningResult.txt -my 250e--332c -base64 -addsigtime -add -detached


в файл TextForSigning.txt помещаю ТекстJSON, сделал его одной строкой и в нём нет "лишних" пробелов
подписывать пытаюсь ТекстJSON как без кодирования в base64, так и с кодирование в base64
из подписи удаляю переносы строк, вставляю в X-Signature
в тело запроса вставляю ТекстJSON без кодирования в base64
в результате orderStatus=DECLINED
может есть мысли что ещё подправить?
+
25. antonprog888 09.01.20 16:59 Сейчас в теме
Добрый день.
Подскажите каким запросом заказывать коды маркировки в документации есть лишь пример тела документа. Если через /api/v3/lk/documents/create то какое значение указывать в параметре type? Может у кого есть более свежая документация по API чем эта https://честныйзнак.рф/upload/iblock/8b6/Opisanie-API-GIS-MP.pdf
+
26. antonprog888 14.01.20 15:43 Сейчас в теме
(25)
Оказывается работа с марками ведется через API СУЗа может кому пригодится вот документация:
https://честныйзнак.рф/upload/iblock/07f/STANTSIYA-UPRAVLENIYA-ZAKAZAMI.pdf
OMS ID и Токен берется из веб-интерфейса СУЗа под администратором.
+
28. Eugene_Elhaz 28.01.20 08:17 Сейчас в теме
(26) в данный момент пропала кнопка администратора, может знаете где сейчас найти omsID?
+
29. antonprog888 28.01.20 09:09 Сейчас в теме
(28)Капец, задолбали они все менять. Токен сейчас в устройствах, а вот где сейчас брать omsID я не знаю. Если найдете напишите.
+
30. user870467 28.01.20 10:07 Сейчас в теме
(29)
Здравствуйте,

к сожалению, в данный момент такой функционал (просмотр OMSID) недоступен, ожидаем реализации в ближайшее время.

С уважением,
Служба поддержки единой национальной системы
цифровой маркировки Честный ЗНАК


Написал в поддержку, прислали на почту.
+
36. antonprog888 04.02.20 15:51 Сейчас в теме
(30) omsID сейчас появился в устройствах в правом верхнем углу.
+
46. user970393 11 24.02.20 14:16 Сейчас в теме
(36)
тройств

Подскажите, где в итоге можно взять OMS ID и Токен?
Судя по всему нужно через интерфейс в личном кабинете добавить устройство и получить информацию оттуда. Но интерфейсе отсутствует такая возможность.
+
31. Al777 30.01.20 02:00 Сейчас в теме
Кто-нибудь может рассказать, как через 1С вставить подпись при создании бизнес-заказа на эмиссию кодов маркировки в СУЗе? Без подписи - всё замечательно работает, но приходится вручную на сайте подписывать, а заказов может быть много. Какой день бьюсь - ничего не получается. У кого-то получилось вставить подпись в СУЗе?
+
32. AlexeyK1 14 30.01.20 19:26 Сейчас в теме
(31)
удалось?

и еще есть у кого документация API СУЗа?
+
33. Al777 30.01.20 23:41 Сейчас в теме
Нет, не удалось. У меня есть свежая документация API СУЗа. Релиз 2.67.
Прикрепленные файлы:
OMS API 2.0 revision 2.67.doc
AlexeyK1; +1
34. AlexeyK1 14 31.01.20 10:31 Сейчас в теме
35. Al777 02.02.20 20:32 Сейчас в теме
После нескольких попыток создать документ с подписью вместе со специалистом СУЗа, вроде бы нашли ошибку, которая могла влиять на неработоспособность подписи. Мне хотя бы было понятно, в каком направлении копать. После уже моих многочисленных экспериментов, я, наконец-то, добился автоматического подписания документов в СУЗе. Всё дело было в передаваемом запросе Json, его обязательно необходимо преобразовать в одну строку. Причём, без подписи преобразовывать не обязательно, а с подписью - просто необходимо.
RustIG; +1
37. user1355603 05.02.20 15:42 Сейчас в теме
(35) А в какой формате подаете преобразованный json в строку? просто вместо {"products":[{"gtin":"... пишете <строка в base64> ? или это всё-равно json формат?
+
39. lonis2007 11.02.20 09:58 Сейчас в теме
(37)
Используйте функцию из 9 сообщения: УбратьСимволы1013(ВашТекстJSON)
+
49. JedBez 28.02.20 04:19 Сейчас в теме
(35)
ричём, без подписи преобразовывать не обязательно

Чтото СУЗ отвечает, что подпись не прошла валидацию:
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");
	ЗаписьТекста.Записать(Строка);
	ЗаписьТекста.Закрыть();
	
	ДД_Файла = Птк.ЗакрытьИПолучитьДвоичныеДанные();
	
	Возврат ДД_Файла;
	
КонецФункции

Показать


И потом в функцию указаную выше

X_Signature = ПодписатьЭЦПЧерезСОМОбъекты(ДокВBase64, Истина);
X_Signature = УбратьСимволы1013(X_Signature);
+
57. JedBez 07.03.20 10:45 Сейчас в теме
(49) Разобрался.
Помимо того что, JSON запрос должен быть в 1 строку, так еще там не должно быть лишних пробелов.
+
60. brenli 2 26.03.20 08:35 Сейчас в теме
(57)
N запрос должен быть в 1 строку, так еще там не должно б

У вас заработало?
+
61. JedBez 27.03.20 01:49 Сейчас в теме
(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", ВидПродукции),
		ПараметрыСУЗ.Идентификатор);
Показать
+
38. user1357420 07.02.20 16:36 Сейчас в теме
Единственный форум нашел посвященный API в честном знаке. Пытаюсь через запрос в браузере получить токен, но не получается. Пишет ошибку <UnauthorizedException><error>unauthorized</error><error_des­cription>Full authentication is required to access this resource</error_description></UnauthorizedException>

Можете прислать пример как это должно выглядеть в тексте?
+
40. antonprog888 11.02.20 12:21 Сейчас в теме
(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": "подписанная строка"}
+
41. user829905 15.02.20 01:20 Сейчас в теме
Соединение = Новый HTTPСоединение("ismp.crpt.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);

А кто нибудь делал соединение с использованием не 1С-овских библиотек?
+
42. user866127 18.02.20 05:37 Сейчас в теме
(41) Только C++ Builder (TidIndy)
+
43. user1366453 21.02.20 11:13 Сейчас в теме
Та же история. Токен получен.
На запрос статуса КМ URL: https://ismp.crpt.ru/api/v3/facade/identifytools/010405915570452921HXRNJW15asP­kB2406405

https://xn--80ajghhoc2aj1c8b.xn--p1ai/upload/iblock/8b6/Opisanie-API-GIS-MP.pdf

Ошибка авторизации: Full authentication is required to access this resource
Блин какая .... авторизация если уже токен передаем?
+
45. dreamadv 155 22.02.20 21:47 Сейчас в теме
(43) Заголовок.Вставить("Authorization", "Bearer "+Токен) - точно не забыли ?
+
47. user1366453 25.02.20 15:32 Сейчас в теме
(43)
нет вроде;

$token='ТУТ ПРИСВАИВАЮ ПОЛУЧЕННЫЙ ТОКЕН';
$ch = curl_init( 'https://ismp.crpt.ru/api/v3/facade/identifytools/010405915570452921HXRNJW15asP­kB2406405' );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json',"Authorization : Bearer $token"));
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1);
# Send request.
$result = curl_exec($ch);
+
44. user1366654 21.02.20 17:39 Сейчас в теме
Прошу прощения, возможно немного не по теме, но вот полезная статья по маркировке, возможно поможет.
https://infostart.ru/public/1198659/
+
48. user1366453 25.02.20 23:24 Сейчас в теме
Как ни странно, но заработало... наверное. Проблема вроде кроется в инструменте для отправки запроса. На WEB сервере Текущая версия CURL 7.19 и возможно что то с ней не так. Сделал то же в Delphi(RIO) через Indy компоненту. Но Indy не возвращает нормальный ответ для кодов = > 400. Поэтому сменил компонент на TNetHttpClient и ответ стал приходить в JSON. Так как под рукой живых кодов нет пока, получаю STATUS = 404 ERROR = "Not found" и больше ничего.
+
67. user1497801 24.11.20 10:08 Сейчас в теме
(48) Нельзя ли с вами связаться?
+
50. user844451 28.02.20 06:50 Сейчас в теме
Все сделано вроде как правильно, запросил GTIN, получил все GTINы, запросил коды маркировки, весит в документе статус: Обрабатывается в суз (генерация кодов) уже вторые сутки, делаю обмен, крутит обменивается с ИС МП минут 40 потом выдается измененные документы 0, статус в документе не меняется, кто сталкивался с такой проблемой, что можно предпринять в таком случае!???
+
51. MegasXIII 28.02.20 13:40 Сейчас в теме
Всем привет.
Сделал API через 8.3 , но через 8.2 неполучается передать тело документа.
А дело в том что в 8.2 нет функций:

ПолучитьДвоичныеДанныеИзСтроки();
ПолучитьBase64СтрокуИзДвоичныхДанных();

Особенно ПолучитьДвоичныеДанныеИзСтроки(); - если кто знает как такое реализовать на 8.2 - буду благодарен.


ПолучитьBase64СтрокуИзДвоичныхДанных(); - в 8.2 наверное Base64Строка();
+
52. MegasXIII 28.02.20 14:18 Сейчас в теме
(51)
Получилось через ТекстовыйФайл

Функция ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПреобразования)
ИмяВремФайла = ПолучитьИмяВременногоФайла();
ЗаписьТекста = Новый ЗаписьТекста(ИмяВремФайла, "CESU-8", , , "");
ЗаписьТекста.Записать(СтрокаДляПреобразования);
ЗаписьТекста.Закрыть();
ДД = Новый ДвоичныеДанные(ИмяВремФайла);

Возврат ДД;
КонецФункции
+
53. НатальяАлекс 34 02.03.20 13:53 Сейчас в теме
Добрый день! Подскажите, плиз... Есть отдельно напечатанные наклейки, есть остатки обуви. Как сопоставить код и номенклатуру в 1С ут 11? В документе "Маркировка товаров ИС МП"? Есть сканер подключенный... Но к номенклатуре не привязаны штрих-коды.... как мне внести маркировку?
+
54. ZyZer 252 03.03.20 22:32 Сейчас в теме
Добрый день! А у кого-нибудь получилось подписать открепленной подписью исходящий документ, например, отгрузку? Я сколько не мучил CADES - не получается, сервер возвращает ошибку "201" и каждый раз разный UID и всё... И этот UID не документа точно, документов новых не появляется.
Есть у кого нормальный пример получения открепленной УКЭП ?

Двоичные данные на 8.2 я разматывал через ТекстовыйДокумент

Функция ЗашифроватьBase64ЧерезФайл(ИсходнаяСтрока) Экспорт
	ВремФайл 	= ПолучитьИмяВременногоФайла();
	
	Тхт 		= Новый ТекстовыйДокумент;
	Тхт.УстановитьТекст(ИсходнаяСтрока);
	Тхт.Записать(ВремФайл, "CESU-8");
	
	Бинарник 	= Новый ДвоичныеДанные(ВремФайл);
	
	Тхт 		= Неопределено;
	УдалитьФайлы(ВремФайл);
	
	Возврат Base64Строка(Бинарник);
КонецФункции //ЗашифроватьBase64ЧерезФайл()

Функция РасшифроватьBase64ЧерезФайл(ВходСтр) Экспорт
	ВремФайл = ПолучитьИмяВременногоФайла();
		
	Бинарник = Base64Значение(ВходСтр);
	
	Если Бинарник = Неопределено Или Бинарник.Размер() = 0 Тогда
		Сообщить("Входная строка не является строкой в формате Base64");
		Возврат "";
	КонецЕсли;
	
	Бинарник.Записать(ВремФайл);
	
	Тхт = Новый ТекстовыйДокумент();
	Тхт.Прочитать(ВремФайл, "CESU-8");
	Стр = Тхт.ПолучитьТекст();
	
	Тхт 		= Неопределено;
	УдалитьФайлы(ВремФайл);
	
	Возврат Стр;
КонецФункции //РасшифроватьBase64ЧерезФайл()

Показать
+
55. MegasXIII 05.03.20 18:38 Сейчас в теме
(54)
ый UID и всё... И этот UID не документа точно, документов новых не появляется.
Есть у кого нормальный пример получения открепленной УКЭП ?


У меня получилось подписать.
Причём подписывал так же как и DATA для Токена....
Кстати "ошибку "201"" - это не ошибка =) Документ появится позже, может например через день. Смотрю дату поста, 2 дня назад, наверное они у вас уже появились! =)
+
56. MegasXIII 05.03.20 18:42 Сейчас в теме
Не могу получить информацию по конкретному товару cis - причём для многих работает, а для некоторых нет!

Делаю так:
HTTPАдрес = "/api/v3/facade/identifytools/"+КодКМ;

КодКМ = "010290000119684021(Vs,oS?a;/_x-";

КодКМ - пробовал кодировать в URL разными способами, нефига не работает.

010290000119684021%28Vs%2CoS%3Fa%3B%2F%5Fx%2D 1с
010290000119684021(Vs%2CoS%3Fa%3B%2F_x- Ява
010290000119684021%28Vs%2CoS%3Fa%3B%2F_x- encod
010290000119684021%28Vs%2CoS%3Fa%3B%2F%5Fx%2D мой
+
69. warlomak 07.05.21 03:41 Сейчас в теме
(56) для тех, кто столкнулся с такой же проблемой, метод POST /api/v4/facade/cis/cis_list
норм все отрабатывает:

{"010290000119684021(Vs,oS?a;/_x-":{"cis":"010290000119684021(Vs,oS?a;/_x-","gtin":"02900001196840","producerName":"АО \"ОПТИКОМ\"","status":"RETIRED","emissionDate":"2020-02-21T07:19:13.157Z","emissionType":"REMAINS","packType":"UNIT","ownerName":"АО \"ОПТИКОМ\"","ownerInn":"7734523776","productName":"Остатки. Обувь. Унисекс. Произведен в РФ","brand":"Без товарного знака","prevCises":[],"nextCises":[],"countChildren":0,"introducedDate":"2020-02-27T16:15:09.106Z","agentName":"","productGroup":"shoes","markWithdraw":false}}
+
73. oskarsan 18.06.21 09:43 Сейчас в теме
(69)
v4/facade/cis/cis_list

Доброго.
для обуви у меня возвращает "code":400

КИТ = "010290000093591421':RqaYo.,XDZE";
	Url="https://ismp.crpt.ru/api/v4/facade/cis/cis_list/";
 	ЗапросJSON = "{""cises"":[" + РазделительСтрок + КИТ + РазделительСтрок + "]" + РазделительСтрок + "}";
 	//ЗапросJSON = "{""uit"":[" + РазделительСтрок + КИТ + РазделительСтрок + "]" + РазделительСтрок + "}";
  	WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.SetTimeouts(0, 0, 0, 0);    
	//WinHttp.Open("GET", Url, 0); //а так ошибка 500
	WinHttp.Open("POST", Url, 0);
	WinHttp.SetRequestHeader("Authorization","Bearer "+Токен);
	WinHttp.SetRequestHeader("Content-type", "application/json");
	WinHttp.SetRequestHeader("childrenPaging", "true");
	//WinHttp.SetRequestHeader("childrenPaging", "false");
	WinHttp.Send(ЗапросJSON);
Показать

или неправильный стенд?
+
72. oskarsan 18.06.21 09:39 Сейчас в теме
(56) Доброго. Получилось побороть?
Пробовал заменять
КИТ = "010290000093591421':RqaYo.,XDZE";
		КИТ = СтрЗаменить(КИТ,"%", "%25");
		КИТ = СтрЗаменить(КИТ,"""","%22"); 
		КИТ = СтрЗаменить(КИТ,"-", "%2D");
		КИТ = СтрЗаменить(КИТ,".", "%2E");
		КИТ = СтрЗаменить(КИТ,"<", "%3C");
		КИТ = СтрЗаменить(КИТ,">", "%3E");
		КИТ = СтрЗаменить(КИТ,"\", "%5C");
		КИТ = СтрЗаменить(КИТ,"^", "%5E");
		КИТ = СтрЗаменить(КИТ,"_", "%5F");
		КИТ = СтрЗаменить(КИТ,"`", "%60");
		КИТ = СтрЗаменить(КИТ,"{", "%7B");
		КИТ = СтрЗаменить(КИТ,"|", "%7C");
		КИТ = СтрЗаменить(КИТ,"}", "%7D"); 
		КИТ = СтрЗаменить(КИТ,"~", "%7E");
		КИТ = СтрЗаменить(КИТ,"!", "%21");
		КИТ = СтрЗаменить(КИТ,"#", "%23");
		КИТ = СтрЗаменить(КИТ,"$", "%24");
		КИТ = СтрЗаменить(КИТ,"&", "%26");
		КИТ = СтрЗаменить(КИТ,"'", "%27");
		КИТ = СтрЗаменить(КИТ,"(", "%28");
		КИТ = СтрЗаменить(КИТ,")", "%29");
		КИТ = СтрЗаменить(КИТ,"*", "%2A");
		КИТ = СтрЗаменить(КИТ,"+", "%2B");
		КИТ = СтрЗаменить(КИТ,",", "%2C");
		КИТ = СтрЗаменить(КИТ,"/", "%2F");
		КИТ = СтрЗаменить(КИТ,":", "%3A");
		КИТ = СтрЗаменить(КИТ,";", "%3B");
		КИТ = СтрЗаменить(КИТ,"=", "%3D");
		КИТ = СтрЗаменить(КИТ,"?", "%3F");
		КИТ = СтрЗаменить(КИТ,"@", "%40");
		КИТ = СтрЗаменить(КИТ,"[", "%5B");
		КИТ = СтрЗаменить(КИТ,"]", "%5D");
Url="https://ismp.crpt.ru/api/v3/facade/cis/cis_list?cis="+КИТ;
Показать

Присылает пустой ответ
+
59. пользователь 20.03.20 14:30
Сообщение было скрыто модератором.
...
62. jefs 13.05.20 04:00 Сейчас в теме
Помогите, пожалуйста, разобраться с маркировкой, чтобы получить токен.. я получил гетом data, закинул data на КриптоПро, выбрал сертификат, подписал. теперь отправляю, чтобы получить токен, но выходит ошибка 401. как перевести файл в base64?
+
64. ivt_2009 24.06.20 10:15 Сейчас в теме
Есть ли пример отправки табачного документа. меня больше чек интересует.
+
68. nollff 13 24.11.20 20:48 Сейчас в теме
Спасибо за наработки, удалось сделать заказ на эмиссию КМ и подписать его.
+
70. Sylver 04.06.21 08:32 Сейчас в теме
Доброго дня.
На чем реализовали?

Делаю соединение на php. Вроде все получилось, токен получил, заказ отправил, теперь надо подписать.
Строку сформировал, но подпись не валидна, подписывал по аналогии с дата.
попробую пробелы порезать и все в одну строку впихнуть, может поможет...
+
71. пользователь 04.06.21 08:35
Сообщение было скрыто модератором.
...
74. ivt_2009 12.11.21 08:15 Сейчас в теме
Добрый день. Пытаюсь отправить акт списания, ни в какую. Ошибка 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.ПолучитьТелоКакСтроку();

Показать
+
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот