Запрос в ЧЗ для разрешительного режима

1. krotik 27.03.24 11:21 Сейчас в теме
Здравствуйте!
1С:Предприятие 8.3 (8.3.18.1363) УТ 10.3

Хочу у Честного Знака получить информацию о коде маркировки для разрешительного режима:

WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
	попытка
		WinHttp.Open("POST", "https://markirovka.crpt.ru/api/v4/true-api/codes/check/",0); 
		WinHttp.SetRequestHeader("X-API-KEY", Токен);
		WinHttp.SetRequestHeader("Content-Type", "application/json; charset=utf-8");
  	        WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
		
		СтрокаЗапроса = "{""codes"":[""" + СтрЗаменить(Код, """", "\""")+"""], ""inn"":""здесь наш ИНН""}";
		WinHttp.SetTimeouts(1000, 1000, 1000, 1000);
		WinHttp.Send(СтрокаЗапроса);
		РезультатСтр = WinHttp.ResponseText(1400);
		Сообщить(ПреобразоватьСтрокуИзУТФ8(РезультатСтр))
	Исключение
		 Сообщить(СокрЛП(РезультатСтр) + " - " + ОписаниеОшибки());
	КонецПопытки;
Показать


Получаю в ответ:
{"timestamp":"2024-03-27T08:13:11.244+00:00","path":"/legacy/api/v1/codes/check/","status":404,"error":"Not Found","message":null,"requestId":"2c4b5a50-12200777"}

Вообще непонятно, при чем тут v1, когда я посылаю запрос на v4 ????
Может есть какие-нибудь советы, может сталкивались?

А если делаю через HTTPЗапрос, как описано у https://forum.infostart.ru/forum9/topic307065/
то вообще не происходит соединение:
Ошибка работы с Интернет: Не могу установить соединение
По теме из базы знаний
Найденные решения
3. krotik 27.03.24 12:25 Сейчас в теме
совсем разобрался:
в коде перед 8005 и пелед 93 и перед 240 надо ставить \u001d

Вот исходный код:
010460620309799921yEM1!K9800526900093CbP6240FA083231.05
вот что надо посылать в запросе:
010460620309799921yEM1!K9\u001d8005269000\u001d93CbP6\u001d240FA083231.05

теперь все возвращает правильно
Antoska; egorov_ivan; +2 Ответить
2. krotik 27.03.24 12:05 Сейчас в теме
В общем, кое в чем разобрался - теперь надо получить список площадок, выбрать одну из них и туда посылать запрос.
Теперь делаю запрос на площадку и получаю ответ:
{"code":0,"description":"ok","codes":[{"cis":"010460620309799921yEM1!K9800526900093CbP6","valid":false,"verified":false,"message":"cannot parse code. AiGroupNotSupportedException: AI group [P] is not supported","found":false,"realizable":false,"utilised":false,"isBlocked":false,"errorCode":8}],"reqId":"a4b3bab9-d425-4892-ad6d-7e5ec6d7f5e8","reqTimestamp":1711530107348}

Никто не знает - что бы такой ответ мог бы означать?
egorov_ivan; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. krotik 27.03.24 12:05 Сейчас в теме
В общем, кое в чем разобрался - теперь надо получить список площадок, выбрать одну из них и туда посылать запрос.
Теперь делаю запрос на площадку и получаю ответ:
{"code":0,"description":"ok","codes":[{"cis":"010460620309799921yEM1!K9800526900093CbP6","valid":false,"verified":false,"message":"cannot parse code. AiGroupNotSupportedException: AI group [P] is not supported","found":false,"realizable":false,"utilised":false,"isBlocked":false,"errorCode":8}],"reqId":"a4b3bab9-d425-4892-ad6d-7e5ec6d7f5e8","reqTimestamp":1711530107348}

Никто не знает - что бы такой ответ мог бы означать?
egorov_ivan; +1 Ответить
3. krotik 27.03.24 12:25 Сейчас в теме
совсем разобрался:
в коде перед 8005 и пелед 93 и перед 240 надо ставить \u001d

Вот исходный код:
010460620309799921yEM1!K9800526900093CbP6240FA083231.05
вот что надо посылать в запросе:
010460620309799921yEM1!K9\u001d8005269000\u001d93CbP6\u001d240FA083231.05

теперь все возвращает правильно
Antoska; egorov_ivan; +2 Ответить
4. egorov_ivan 26.10.24 00:29 Сейчас в теме
На случай если кому нужен полный код, т.к. у нас ут 10.3 старая (10.3 (10.3.72.2)

Функция ВставкаСимволаРазделителяGS1ВШтрихкод(ДанныеКодаТовара) Экспорт     
    Штрихкод = Base64ВШтрихкод(ДанныеКодаТовара.ШтрихкодBase64);
	//РазделительGS1 = "<0x1D>";
	//РазделительGS1 = Символ(29);
	РазделительGS1 = "\u001d"; //ВАЖНО!!!!!!!!!!!!!!!!!!!
    
    Если Найти(Штрихкод, РазделительGS1) > 0 Тогда
        Возврат ДанныеКодаТовара.ШтрихкодBase64;
    КонецЕсли;
    
    //ДанныеКодаТовара.СерийныйНомер=5Bm2J/KPuYgVT
    ПозицияСерийногоНомера = Найти(Штрихкод, ДанныеКодаТовара.СерийныйНомер);
    ДлинаСерийногоНомера = СтрДлина(ДанныеКодаТовара.СерийныйНомер);
    
    Если ПозицияСерийногоНомера > 0 Тогда
        
        ЛеваяЧастьШтрихкода = Лев(Штрихкод, (ПозицияСерийногоНомера-1)+ДлинаСерийногоНомера);
        СредняЧастьШтрихкода = РазделительGS1 + Сред(Штрихкод, СтрДлина(ЛеваяЧастьШтрихкода) + 1, 6) + РазделительGS1;
        ПраваяЧастьШтрихкода = Сред(Штрихкод, СтрДлина(ЛеваяЧастьШтрихкода) + 7);
        
        Штрихкод = ЛеваяЧастьШтрихкода + СредняЧастьШтрихкода + ПраваяЧастьШтрихкода;
        
    Иначе    
        Возврат ДанныеКодаТовара.ШтрихкодBase64;
    КонецЕсли;    
	
	Возврат Штрихкод;
	//Возврат ШтрихкодВBase64(Штрихкод);
    
КонецФункции

Функция Base64ВШтрихкод(ШтрихкодВBase64) Экспорт //ебала не нужно 
	
	ДвоичныеДанные = Base64Значение(ШтрихкодВBase64);
	Если ДвоичныеДанные = Неопределено Тогда
		Штрихкод = ШтрихкодВBase64;
	Иначе
		Штрихкод = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные);
	КонецЕсли;
	
	Возврат Штрихкод;
	
КонецФункции

Функция ВыполнитьОнлайнКонтрольМаркиЧестныйЗнак(Марка,Токен,ИНН,НомерФН,ТестовыйКонтур,ПлощадкаCDN) Экспорт
	
	
	Рез = Новый Структура();
	Рез.Вставить("ПродажаРазрешена",Истина);
	Рез.Вставить("ИдЗапроса","");
	Рез.Вставить("ВременнаяМетка","");
	Рез.Вставить("ТекстОшибки","");
	Рез.Вставить("ОтветПолучен",Ложь);
	Рез.Вставить("ВремяЗапроса",0);
	
	Заголовки = Новый Соответствие();
	Заголовки.Вставить("X-API-KEY",Токен);
	Заголовки.Вставить("Accept-Charset","utf-8");
	Заголовки.Вставить("Content-Type","application/json; charset=utf-8");
	
	HTTPЗапрос = Новый HTTPЗапрос("api/v4/true-api/codes/check",Заголовки);
	
	Если ЗначениеЗаполнено(ИНН) Тогда
		ЧастьЗапросаИНН = ",""inn"":"""+СокрЛП(ИНН)+"""";
	Иначе
		ЧастьЗапросаИНН = "";
	КонецЕсли;
	
	Если ЗначениеЗаполнено(НомерФН) Тогда
		ЧастьЗапросаФН  = ",""fiscalDriveNumber"":"""+СокрЛП(НомерФН)+"""";
	Иначе
		ЧастьЗапросаФН  = "";
	КонецЕсли;
	
	//Green+ 25.10.2024 23:10:49
	ТекущаяПозиция = Новый Структура("КонтрольнаяМарка",Неопределено);
	
	ТекущаяПозиция.КонтрольнаяМарка = Марка;
	ДанныеКодаТовара = МенеджерОборудованияМаркировкаКлиентСервер.РазобратьШтриховойКодТовара(ТекущаяПозиция.КонтрольнаяМарка);
	РеквизитКодаТовара = ДанныеКодаТовара.РеквизитКодаТовара;
	Если НЕ ПустаяСтрока(РеквизитКодаТовара) И Не ПустаяСтрока(ДанныеКодаТовара.ШтрихкодBase64) Тогда // Запись тега 1163
		ШтрихкодBase64 = ВставкаСимволаРазделителяGS1ВШтрихкод(ДанныеКодаТовара); //ВАЖНО ШтрихкодВBase64 не используется
	КонецЕсли;
	
	ТелоЗапросаJSON = "{""codes"":[""" + СтрЗаменить(ШтрихкодBase64, """", "\""")+"""]" +ЧастьЗапросаИНН+ЧастьЗапросаФН+"}";
	//Green-

	
	Сообщить("Текст запроса: "+ТелоЗапросаJSON);
	
	HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапросаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
	
	Если ЗначениеЗаполнено(ПлощадкаCDN) Тогда
		
		ДанныеУРЛ = РазобратьСерверПортИзСтроки(ПлощадкаCDN);
		
		АдресРесурса  = ДанныеУРЛ.Адрес;
		ПортРесурса   = ?(ДанныеУРЛ.Порт<>0,ДанныеУРЛ.Порт,443);
		ИспШифрование = ДанныеУРЛ.Шифрование;
		
	Иначе	
	
		АдресРесурса  = ?(ТестовыйКонтур=Истина,"markirovka.sandbox.crptech.ru","markirovka.crpt.ru");
		ПортРесурса   = 443;
		ИспШифрование = Истина;
		
	КонецЕсли;	
	
	ВремяЗапроса = 0;
	
	Попытка
		
		Если ИспШифрование Тогда
			ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено,Неопределено);
		Иначе	                   
			ЗащищенноеСоединение = Неопределено;
		КонецЕсли;	
		
		Соединение = Новый HTTPСоединение(АдресРесурса,ПортРесурса,,,Неопределено,15,ЗащищенноеСоединение);
		
		ВремяНачала = ТекущаяУниверсальнаяДатаВМиллисекундах();
		
		HTTPОтвет = Соединение.ОтправитьДляОбработки(HTTPЗапрос); //post
		
		ВремяОкончания = ТекущаяУниверсальнаяДатаВМиллисекундах();
		
		ВремяЗапроса = ВремяОкончания - ВремяНачала;
		
	Исключение
		
		//Нет соединения или таймаут - продажа разрешена
		
		Рез.ТекстОшибки = ОписаниеОшибки();
		
		Возврат Рез;
		
	КонецПопытки;
	
	ТелоОтветаJSON = HTTPОтвет.ПолучитьТелоКакСтроку();
	
	Сообщить("Код состояния: "+HTTPОтвет.КодСостояния);
	Сообщить("Текст ответа: "+ТелоОтветаJSON);
		
	Если HTTPОтвет.КодСостояния=200 Тогда
		
		Рез.ОтветПолучен = Истина;
		Рез.ВремяЗапроса = ВремяЗапроса;
		
		КодОшибки       = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"errorCode");
		
		ТекстОшибки     = "";
				
		Если (ЗначениеЗаполнено(КодОшибки))И(КодОшибки<>"0") Тогда
			
			ТекстОшибкиГИСМТ = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"message");
			
			Если КодОшибки = "1" Тогда
				ТекстОшибки = "Ошибка валидации КМ в ГИС МТ.";
			ИначеЕсли КодОшибки = "2" Тогда
				ТекстОшибки = "КМ не содержит GTIN.";
			ИначеЕсли КодОшибки = "3" Тогда
				ТекстОшибки = "КМ не содержит серийный номер.";
			ИначеЕсли КодОшибки = "4" Тогда
				ТекстОшибки = "КМ содержит недопустимые символы.";
			ИначеЕсли КодОшибки = "5" Тогда
				ТекстОшибки = "Ошибка верификации крипто-подписи КМ в ГИС МТ (формат крипто-подписи не соответствует типу КМ).";
			ИначеЕсли КодОшибки = "6" Тогда
				ТекстОшибки = "Ошибка верификации крипто-подписи КМ в ГИС МТ (крипто-подпись не валидная).";
			ИначеЕсли КодОшибки = "7" Тогда
				ТекстОшибки = "Ошибка верификации крипто-подписи КМ в ГИС МТ (крипто-ключ не валиден).";
			ИначеЕсли КодОшибки = "8" Тогда
				ТекстОшибки = "КМ не прошел верификацию в стране эмитента/ошибка разбора КМ.";
			ИначеЕсли КодОшибки = "9" Тогда
				ТекстОшибки = "Найденные AI в КМ не поддерживаются.";
			ИначеЕсли КодОшибки = "10" Тогда
				ТекстОшибки = "КМ не найден в ГИС МТ.";
			Иначе
				ТекстОшибки = "Неклассифицированная ошибка отправки запроса по КМ в ГИС МТ: "+КодОшибки+".";
			КонецЕсли;
			
			Рез.ТекстОшибки = ТекстОшибки+" "+ТекстОшибкиГИСМТ;
			Рез.ПродажаРазрешена = Ложь;
			Возврат Рез;
			
		Иначе     
			
			Валидность  = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"valid");
			Наличие     = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"found");
			Продан      = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"sold");
			Нанесен     = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"utilised");
			СераяЗона   = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"grayZone");
			БлокПродажи = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"isBlocked");
			Принадлежность = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"isOwner");
						
			УспешнаяПроверкаКриптоподписи = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"verified");
			ВозможностьРеализации         = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"realizable");
			
			Если Продан = "true" Тогда
				СтатусМарки = "Продан";
			ИначеЕсли ВозможностьРеализации = "true" Тогда
				Если Принадлежность="false" тогда
					СтатусМарки = "Принадлежит другой организации";
				Иначе	
					СтатусМарки = "В обороте";
				КонецЕсли;	
			ИначеЕсли (ВозможностьРеализации <> "true")И(Нанесен = "true") Тогда
				СтатусМарки = "Нанесен";
			ИначеЕсли Нанесен <> "true" Тогда
				СтатусМарки = "Эмитирован";
			Иначе
				СтатусМарки = "Неизвестен";
			КонецЕсли;
			
			Если СтатусМарки = "Неизвестен" Тогда
				
				Если Валидность <> "true" Тогда
					
					ТекстОшибки = "Структура данных кода маркировки некорректна.";
					
				ИначеЕсли УспешнаяПроверкаКриптоподписи <> "true" Тогда
					
					ТекстОшибки = "Проверка крипто-подписи кода маркировки в ГИС МТ завершилась с ошибкой.";
					
				ИначеЕсли Наличие <> "true" Тогда
					
					ТекстОшибки = "Код маркировки не найден в ГИС МТ.";
					
				КонецЕсли;
				
			КонецЕсли;	
			
			Если БлокПродажи = "true" Тогда
				
				ТекстОшибки = "Продажа заблокирована контролирующей организацией.";
				
			КонецЕсли;	
			
			Если СтатусМарки <> "В обороте" Тогда
				
				ТекстОшибки = ТекстОшибки +"; Недопустимый статус марки: "+СтатусМарки;
				
			КонецЕсли;	
			
			Если ТекстОшибки = "" Тогда
				
				Рез.ИДЗапроса = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"reqId");
				
				Рез.ВременнаяМетка = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"reqTimestamp");
				
				Возврат Рез;				
				
			Иначе 
				
				Рез.ТекстОшибки = ТекстОшибки;
				Рез.ПродажаРазрешена = Ложь;
				Возврат Рез;
				
			КонецЕсли;					
			
		КонецЕсли;	
				
	Иначе
		
		ТекстОшибкиГИСМТ = ПолучитьИзСтрокиJSON(ТелоОтветаJSON,"description");
		
		Рез.ТекстОшибки = "Не удалось выполнить проверку марки. Код ответа: "+Строка(HTTPОтвет.КодСостояния)+". "+ТекстОшибкиГИСМТ;
		Рез.ПродажаРазрешена = Ложь;
		Возврат Рез;
		
	КонецЕсли;	
	
	
КонецФункции
Показать
oskarsan; +1 Ответить
5. egorov_ivan 26.10.24 00:32 Сейчас в теме
итоги которые подметил:
1. марка нужна полная(полный маркировки)
2. разделитель "\u001d"
3. вставку разделителя нужно делать только с разделителем из п.2
4. ШтрихкодВBase64 не нужно будет BAD-request
5. "\" нужно экранировать
Оставьте свое сообщение

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