Маркировка обуви, автоматизация через 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 101 26.04.19 10:06 Сейчас в теме
А отсрочку не утвердили?
3. zer0911 26.04.19 10:10 Сейчас в теме
(2) Не слышал о таком. Счётчик на сайте "Честного знака" до старта обязательной маркировки c 1 Июля 2019 г. неумолимо стремится к нулю )
4. ranis888 101 26.04.19 10:15 Сейчас в теме
(3) Нам отправили документ, где написано, что на рассмотрении отсрочка
5. ranis888 101 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
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, его обязательно необходимо преобразовать в одну строку. Причём, без подписи преобразовывать не обязательно, а с подписью - просто необходимо.
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 Сейчас в теме
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 11 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.ПолучитьТелоКакСтроку();

Показать
Оставьте свое сообщение
Вакансии
1С аналитик
Москва
зарплата от 210 000 руб.
Полный день

Руководитель направления 1С
Москва
зарплата от 350 000 руб.
Полный день

1С Программист
Москва
зарплата от 180 000 руб.
Полный день

Программист 1С
Москва
зарплата от 180 000 руб. до 220 000 руб.
Полный день

Аналитик 1С / Бизнес-аналитик
Нижний Новгород
зарплата от 100 000 руб. до 250 000 руб.
Временный (на проект)