Подпись документа api ЭДО Лайт

1. user5300 1021 20.10.22 08:07 Сейчас в теме
Добрый день, кто уже начал работать с api ЭДО Лайт?
Подскажите как правильно подписать и отправить документ ?
Как черновик документы успешно отправляются, а последующее подписание выдает ошибки "Ошибка подписи"... Поделитесь рабочим кодом
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
20. user5300 1021 20.10.22 12:06 Сейчас в теме
(19) Спасибо за наводку !) Получилось , но всё же надо переводить в строку ) Вот рабочий кусок кода:
Функция ПодписатьИОтправитьДокументВЭДОЛайт(ВыбранныйСертификат,Токен,ИД_ЭДО) Экспорт

	Результат = новый Структура("Выполнено,ТекстОшибки",Ложь,"");
	
	// 1. Получить документ
	HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ(),443,,,,,Новый ЗащищенноеСоединениеOpenSSL);		  		
	URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/content",ИД_ЭДО);
	
	ЗаголовокHTTP = Новый Соответствие();
	ЗаголовокHTTP.Вставить("Authorization", "Bearer "   + Токен);		
	
	HTTPЗапрос  = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);	

	HTTPОтвет 	= HTTPСоединение.ВызватьHTTPМетод("GET",HTTPЗапрос);
					
	//XMLДокумент = HTTPОтвет.ПолучитьТелоКакСтроку("windows-1251");	
	ДВXMLДокумент = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
	
	

	HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ(),443,,,,,Новый ЗащищенноеСоединениеOpenSSL);		  	
	URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/signature",ИД_ЭДО);
			
	
	ПодписанныйДокумент = ПодписатьСертификатомДокумент(
				ПолучитьСертификаты(ВыбранныйСертификат),	
				ПолучитьBase64СтрокуИзДвоичныхДанных(ДВXMLДокумент),
				Истина); 
	
	HTTPЗапрос = новый HTTPЗапрос(URLЗапроса);
	HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/plain");
	HTTPЗапрос.Заголовки.Вставить("Authorization","Bearer "+Токен);
	HTTPЗапрос.Заголовки.Вставить("content-encoding", "base64");
	
	HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(ПодписанныйДокумент,"windows-1251"));
	
	HTTPОтвет 	= HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос);
	
	Если HTTPОтвет.КодСостояния<>200 и HTTPОтвет.КодСостояния<>201 Тогда
		Результат.ТекстОшибки = "Отгрузка. Ошибка получения данных(ЭДО ЧЗ) с сервера="+HTTPОтвет.КодСостояния+":"+HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8");
	Иначе
		Результат.Выполнено = Истина;
	КонецЕсли;	
	
	Возврат Результат;	
	
	
КонецФункции
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. muskul 20.10.22 08:22 Сейчас в теме
есть же нормальные операторы
3. user5300 1021 20.10.22 08:23 Сейчас в теме
(2) ЭДО бесплатный, и мы как производители работаем с этим оператором
4. muskul 20.10.22 08:31 Сейчас в теме
(3)бесплатный для получения. отправка у всех платная
5. user5300 1021 20.10.22 08:31 Сейчас в теме
(4) Отправка тоже бесплатная
6. muskul 20.10.22 08:33 Сейчас в теме
(5)Хм, буду знать, если не маркированного эдо нет, тогда да, имеет смысл
7. sivin-alexey 508 20.10.22 10:29 Сейчас в теме
Ранее работал с этим оператором по API. Там нужна была присоединенная подпись.

Как получить присоединенную ЭП средствами платформы - https://infostart.ru/public/1493281/

Вот пример, как подписывать и отправлять УПД на ЭДО Лайт.
Процедура ОтправитьУПДнаЭДО(П,СФ,Отказ,ОписаниеОшибки) Экспорт
	
	ПолучитьТокен(П,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	УПД = ПолучитьУПД(П,СФ,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

	Подпись = Подписать(УПД.ДвоичныеДанные,П.Токен_Отпечаток,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

	Подпись = ПолучитьПрисоединеннуюПодпись(Подпись,УПД.ДвоичныеДанные,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

	ПолучитьТокен(П,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	
	ПС = Символы.ВК+Символы.ПС;
	Заголовки = Заголовки(П);
	
	Р = "---------------------------Lkjd09340ijk1nx94pi8md8nd8a23cgQr";
	Заголовки.Вставить("Content-Type","multipart/form-data; boundary="+Р);

	Тело = "";
	Тело = Тело + "--"+Р+ПС;
	Тело = Тело + "Content-Disposition: form-data; name=""content""; filename="""+УПД.ИДФайл+".xml"""+ПС;
	Тело = Тело + "Content-Type: application/xml"+ПС+ПС;
	Тело = Тело + ПолучитьСтрокуИзДвоичныхДанных(УПД.ДвоичныеДанные,КодировкаТекста.ANSI)+ПС;
	
	Тело = Тело + "--"+Р+ПС;
	Тело = Тело + "Content-Disposition: form-data; name=""signature"""+ПС;
	Тело = Тело + "Content-Type: text/plain"+ПС+ПС;
	Тело = Тело + Base64_Строка(Подпись) + ПС;

	Тело = Тело + "--"+Р+"--"+ПС;
	
	А = ПолучитьДвоичныеДанныеИзСтроки(Тело,КодировкаТекста.ANSI);
	
	ИмяСервера = ПолучитьИмяСервера(П.ОператорЭДО);
	Соединение  = Новый HTTPСоединение(ИмяСервера,,,,,,Новый ЗащищенноеСоединениеOpenSSL);
	Запрос = Новый HTTPЗапрос("/api/v1/outgoing-documents",Заголовки);
	Запрос.УстановитьТелоИзДвоичныхДанных(А);
	Состояние(ИмяСервера+"/api/v1/outgoing-documents");
	Ответ = Соединение.ОтправитьДляОбработки(Запрос);
	Состояние();
	Тело = Ответ.ПолучитьТелоКакСтроку();
	Если Ответ.КодСостояния<>201 Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка выполнения запроса outgoing-documents. Код состояния="+Ответ.КодСостояния+"  "+Тело;
		Возврат;
	КонецЕсли;
	
	Т = JSON_В_Значение(Тело);
	Если ТипЗнч(Т)<>Тип("Структура") Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка разбора JSON "+Тело;
		Возврат;
	КонецЕсли;
	
	
	Ссылка = Документы.ДокументЭДО.ПолучитьСсылку(Новый УникальныйИдентификатор(Т.id));
	Док = Документы.ДокументЭДО.СоздатьДокумент();
	Док.ОператорЭДО = П.ОператорЭДО;
	Док.УстановитьСсылкуНового(Ссылка);
	Док.ДокументыОснования.Добавить().ДокументОснование = СФ;
	Док.Дата = ТекущаяДата();
	Док.ОбменДанными.Загрузка = Истина;
	Док.Записать();
	
КонецПроцедуры

Функция Заголовки(П=Неопределено)
	Результат = Новый Соответствие;
	Результат.Вставить("Content-Type","application/json;charset=UTF-8");
	
	Если ТипЗнч(П)=Тип("Структура") Тогда
		Если П.Свойство("Токен") Тогда
			Результат.Вставить("Authorization","Bearer "+П.Токен);
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции

Процедура Авторизация(П,Отказ,ОписаниеОшибки)
	
	Соединение  = Новый HTTPСоединение(ПолучитьИмяСервера(П.ОператорЭДО),,,,,,Новый ЗащищенноеСоединениеOpenSSL);
	Запрос = Новый HTTPЗапрос("api/v1/session",Заголовки());
	Ответ = Соединение.Получить(Запрос);
	Тело = Ответ.ПолучитьТелоКакСтроку();

	Если Ответ.КодСостояния<>200 Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка запроса авторизации: "+Ответ.КодСостояния+" "+Тело;
		Возврат;
	КонецЕсли;
	
	
	Данные = JSON_В_Значение(Тело);
	Если ТипЗнч(Данные)<>Тип("Структура") Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка разбора JSON: "+Тело;
		Возврат;
	КонецЕсли;
	ДвоичныеДанные = ПолучитьДвоичныеДанныеИзСтроки(Данные.data,КодировкаТекста.UTF8,Ложь);
	
	
	МассивСертификатов =  .....

	
	П.Вставить("Токен_Отпечаток",МассивСертификатов[0].Отпечаток);
	
	Подпись = Подписать(ДвоичныеДанные,П.Токен_Отпечаток,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;

	Подпись = ПолучитьПрисоединеннуюПодпись(Подпись,ДвоичныеДанные,Отказ,ОписаниеОшибки);
	Если Отказ Тогда
		Возврат;
	КонецЕсли;
	
	//Получение токена
	Данные.Вставить("data",Base64_Строка(Подпись));
	
	Запрос = Новый HTTPЗапрос("api/v1/session",Заголовки());
	Запрос.УстановитьТелоИзСтроки(Значение_В_JSON(Данные),КодировкаТекста.UTF8,ИспользованиеByteOrderMark.НеИспользовать);
	Ответ = Соединение.ОтправитьДляОбработки(Запрос);
	Тело = Ответ.ПолучитьТелоКакСтроку();

	Если Ответ.КодСостояния<>200 Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка запроса авторизации: "+Ответ.КодСостояния+" "+Тело;
		Возврат;
	КонецЕсли;
	
	Данные = JSON_В_Значение(Тело);
	Если ТипЗнч(Данные)<>Тип("Структура") Тогда
		Отказ = Истина;
		ОписаниеОшибки = "Ошибка разбора JSON: "+Тело;
		Возврат;
	КонецЕсли;
	
	П.Вставить("Токен",Данные.token);
	
КонецПроцедуры


Процедура ПолучитьТокен(П,Отказ,ОписаниеОшибки) Экспорт
	
	Сервер = ПолучитьИмяСервера(П.ОператорЭДО);
	
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	Рег.Токен,
	|	Рег.СрокДействия,
	|	Рег.Отпечаток
	|ИЗ
	|	РегистрСведений.АутентификационныеТокены КАК Рег
	|ГДЕ
	|	Рег.Сервер = &Сервер
	|	И Рег.Организация = &Организация
	|	И Рег.СрокДействия > &ТекущаяДата");
	Запрос.УстановитьПараметр("Сервер",Сервер);
	Запрос.УстановитьПараметр("Организация",П.Организация);
	Запрос.УстановитьПараметр("ТекущаяДата",ТекущаяДата());
	Табл = Запрос.Выполнить().Выгрузить();
	
	Если Табл.Количество()>0 Тогда
		П.Вставить("Токен",Табл[0].Токен);
		П.Вставить("Токен_СрокДействия",Табл[0].СрокДействия);
		П.Вставить("Токен_Отпечаток",Base64Значение(Табл[0].Отпечаток));
	Иначе
		Авторизация(П,Отказ,ОписаниеОшибки);
		Если Отказ Тогда
			Возврат;
		КонецЕсли;
		
		СрокДействия = ТекущаяДата()+9*3600; //9 часов

		Набор = РегистрыСведений.АутентификационныеТокены.СоздатьНаборЗаписей();
		Набор.Отбор.Сервер.Установить(Сервер);
		Набор.Отбор.Организация.Установить(П.Организация);
		
		НовСтрока = Набор.Добавить();
		НовСтрока.Сервер = Сервер;
		НовСтрока.Организация = П.Организация;
		НовСтрока.Токен = П.Токен;
		НовСтрока.Отпечаток = Base64_Строка(П.Токен_Отпечаток);
		НовСтрока.СрокДействия = СрокДействия;
		
		Набор.Записать();

		П.Вставить("Токен_СрокДействия",СрокДействия);
		П.Вставить("Токен_Отпечаток",Base64Значение(П.Токен_Отпечаток));
	КонецЕсли;

КонецПроцедуры

Показать
8. user5300 1021 20.10.22 11:18 Сейчас в теме
(7) Нет, там требуется открепленная подпись, Но в любом случае ругается на ошибку подписи...
9. user5300 1021 20.10.22 11:22 Сейчас в теме
Вот мой кусок: Может чего то не хватает:

HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ(),443,,,,,Новый ЗащищенноеСоединениеOpenSSL);		  	
	URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/signature",ИД_ЭДО);
	
	
	ПодписанныйДокумент = ПодписатьСертификатомДокумент(
				ПолучитьСертификаты(ВыбранныйСертификат),	
				ЗашифроватьBase64(XMLДокумент, "windows-1251"),
				Ложь); 
	

	HTTPЗапрос = новый HTTPЗапрос(URLЗапроса);
	HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/plain");
	HTTPЗапрос.Заголовки.Вставить("Authorization","Bearer "+Токен);
	HTTPЗапрос.Заголовки.Вставить("content-encoding", "base64");
	
	
	HTTPЗапрос.УстановитьТелоИзСтроки(ПодписанныйДокумент, "windows-1251");
	
	HTTPОтвет 	= HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос);
	
	Если HTTPОтвет.КодСостояния<>200 и HTTPОтвет.КодСостояния<>201 Тогда
		Ошибка =  HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8");
                //Ошибка = "ошибка подписи"		
	КонецЕсли;	



Показать
10. sivin-alexey 508 20.10.22 11:32 Сейчас в теме
(9) Я рабоал еще с "API ЭДО Lite Версия 3.0".
Использовал другой метод: "3.1. Метод загрузки файла информации продавца УПД". С помощью multipart/form-data передавал сразу данные и подпись. Причем на открепленную подпись ругалась, с прикрепленной - работало. Сейчас может уже исправили.
11. user5300 1021 20.10.22 11:35 Сейчас в теме
(10) Да, ваш метод тоже вызывает "ошибку подписи"
Хотя с подписью все в порядке (Получаю токен, работаю в ГисМТ по такой же схеме - там все ок)
Подписываю средствами КриптоПро (comCPSigner = Новый COMОбъект("CAdESCOM.CPSigner"))

Черновики загружаются отдельно, и успешно, а вот подписать уже не дает
12. sivin-alexey 508 20.10.22 11:37 Сейчас в теме
(11) Да, вспомнил. Метод "3.5. Подписание исходящего документа" тоже пробовал, но не получилось. Выдавал ошибку, как у вас. Вроде бы как двоичные данные не совпадали с черновиком.
14. user5300 1021 20.10.22 11:42 Сейчас в теме
(13) Подписывать можно и так и так, там всё работает.


(12) Да, тоже где то в комментах прочитал что могут не совпадать черновики с подписываемым документом... но документ получаю методом "3.5. Получение содержимого XML документа" , Подписываю открепленной подписью и отправляю в таком же виде (Строка, кодировка: "windows-1251") и не дает
15. sivin-alexey 508 20.10.22 11:43 Сейчас в теме
(14) Попробуйте не "УстановитьТелоИзСтроки" а "УстановитьТелоИзДвоичныхДанных"
16. user5300 1021 20.10.22 11:47 Сейчас в теме
(15) Попробовал, к сожалению не помогает,
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(ПодписанныйДокумент,"windows-1251"));
17. sivin-alexey 508 20.10.22 11:48 Сейчас в теме
(14) Попробуйте не "УстановитьТелоИзСтроки" а "УстановитьТелоИзДвоичныхДанных".

Предварительно получайте содержимое XML-документа как двоичные данные и отправляйте как двоичные данные, иначе могут возникать перекодировки и изменение содержимого.
18. user5300 1021 20.10.22 11:51 Сейчас в теме
(17) А как подписывать двоичные данные? Переводить в строку, подписать и обратно получается?
19. sivin-alexey 508 20.10.22 11:53 Сейчас в теме +3.12 $m
(18) Нет, строки вообще не должно быть.

Предварительно получайте содержимое XML-документа как двоичные данные, подписывайте как двоичные данные и отправляйте подпись как двоичные данные.

Иначе могут возникать перекодировки и изменение содержимого. Никаких строк!
20. user5300 1021 20.10.22 12:06 Сейчас в теме
(19) Спасибо за наводку !) Получилось , но всё же надо переводить в строку ) Вот рабочий кусок кода:
Функция ПодписатьИОтправитьДокументВЭДОЛайт(ВыбранныйСертификат,Токен,ИД_ЭДО) Экспорт

	Результат = новый Структура("Выполнено,ТекстОшибки",Ложь,"");
	
	// 1. Получить документ
	HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ(),443,,,,,Новый ЗащищенноеСоединениеOpenSSL);		  		
	URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/content",ИД_ЭДО);
	
	ЗаголовокHTTP = Новый Соответствие();
	ЗаголовокHTTP.Вставить("Authorization", "Bearer "   + Токен);		
	
	HTTPЗапрос  = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);	

	HTTPОтвет 	= HTTPСоединение.ВызватьHTTPМетод("GET",HTTPЗапрос);
					
	//XMLДокумент = HTTPОтвет.ПолучитьТелоКакСтроку("windows-1251");	
	ДВXMLДокумент = HTTPОтвет.ПолучитьТелоКакДвоичныеДанные();
	
	

	HTTPСоединение = Новый HTTPСоединение(ПолучитьАдресГИС_МТ(),443,,,,,Новый ЗащищенноеСоединениеOpenSSL);		  	
	URLЗапроса = СтрШаблон("/api/v1/outgoing-documents/%1/signature",ИД_ЭДО);
			
	
	ПодписанныйДокумент = ПодписатьСертификатомДокумент(
				ПолучитьСертификаты(ВыбранныйСертификат),	
				ПолучитьBase64СтрокуИзДвоичныхДанных(ДВXMLДокумент),
				Истина); 
	
	HTTPЗапрос = новый HTTPЗапрос(URLЗапроса);
	HTTPЗапрос.Заголовки.Вставить("Content-Type", "text/plain");
	HTTPЗапрос.Заголовки.Вставить("Authorization","Bearer "+Токен);
	HTTPЗапрос.Заголовки.Вставить("content-encoding", "base64");
	
	HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзСтроки(ПодписанныйДокумент,"windows-1251"));
	
	HTTPОтвет 	= HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос);
	
	Если HTTPОтвет.КодСостояния<>200 и HTTPОтвет.КодСостояния<>201 Тогда
		Результат.ТекстОшибки = "Отгрузка. Ошибка получения данных(ЭДО ЧЗ) с сервера="+HTTPОтвет.КодСостояния+":"+HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8");
	Иначе
		Результат.Выполнено = Истина;
	КонецЕсли;	
	
	Возврат Результат;	
	
	
КонецФункции
Показать
21. sivin-alexey 508 20.10.22 12:10 Сейчас в теме
(20)
Значит здесь менялись данные в результате перекодировки:
//XMLДокумент = HTTPОтвет.ПолучитьТелоКакСтроку("windows-1251");

Рад был помочь.
22. user5300 1021 20.10.22 12:11 Сейчас в теме
13. sivin-alexey 508 20.10.22 11:38 Сейчас в теме
(11) Я подписывал средствами 1С
23. bobylev1980 21 21.10.22 12:22 Сейчас в теме
Отправка марок в ЭДО Lite (ЭДО Лайт) "Честный знак" с помощью методов API ЭДО Lite файл УПД/УПДи/УКД https://infostart.ru/public/1571233/
24. user5300 1021 21.10.22 12:25 Сейчас в теме
(23) Скачал, у вас подписание при загрузке, а у меня подписание черновиков ЭДО)
25. user1862869 21.10.22 17:06 Сейчас в теме
Отправляю УПД через ЭДО лайт клиентам с водой в том числе маркированной,с учетом того,что роуминг с клиентами настроен,ни один не видит у себя,ни диадок,ни особенно сбис.У кого нибудь есть практика что бы видели?
26. sivin-alexey 508 21.10.22 18:44 Сейчас в теме
(25) Клиент из СБИС должен отправить вам приглашение, указав "Через роуминг: ЦРПТ". У нас работает
Оставьте свое сообщение

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