|
Работа с документами по API "Честный знак" | ☑ | ||
---|---|---|---|---|
0
Saari
14.10.24
✎
10:00
|
Изучаю работу с Честным знаком по API из 1С.
Данные по остаткам получил. Теперь нужно научиться создавать документы "Вывод из оборота (ОСУ)", "Отмена вывода из оборота (ОСУ)". В описании True API сказано, что тело запроса должно быть вида: "document_format":"string", "product_document":"<Документ в формате base64>", "type":"string", "signature":"<Открепленная УКЭП формата Base64>" Вопрос к последнему параметру "signature". Как получить открепленную УКЭП? Научите, пожалуйста. |
|||
1
MWWRuza
14.10.24
✎
10:29
|
Ровно так-же, как и прикрепленную... Один параметр отвечает за это.
В случаее прикрепленной - ЭЦП "встраивается" в тело документа, в случае открепленной - это отдельный файл. Сказать что-то более конкретно - надо понимать, в чем и как Вы это вообще делаете... Вариантов может быть много. |
|||
2
Saari
14.10.24
✎
10:48
|
Вот как я пытаюсь создать документ:
Процедура КнопкаОтправитьЗапросНажатие(Элемент) Соединение = Новый HTTPСоединение(Сервер, 443, ,,,, Новый ЗащищенноеСоединениеOpenSSL); HTTPЗапрос = Новый HTTPЗапрос(Запрос); HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer " + Токен); HTTPЗапрос.Заголовки.Вставить("Accept", "application/json"); HTTPЗапрос.Заголовки.Вставить("Accept-Charset", "utf-8"); HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json"); СтрокаДляЗапроса = СформироватьЗапрос(); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаДляЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос, ИмяФайлаОтвета); Если Ответ.КодСостояния = 200 Тогда Сообщить("Код ответа на запрос: " + Ответ.КодСостояния + " - выполнен успешно."); Иначе Сообщить("Код ответа на запрос: " + Ответ.КодСостояния + " - ошибка!" ); КонецЕсли; КонецПроцедуры функция СформироватьЗапрос() //LK_GTIN_RECEIPT - тип документа "Вывод из оборота (ОСУ)" СтрокаДляЗапроса = ""; СтрокаДляЗапросаТелоДокумента = ""; //-- документ (тело) ИНН = СокрЛП(ВыбОрганизация.ИНН); ПричинаВыбытияТекст = "UTILIZATION"; //Утилизация ПричинаВыбытия_Дата = Формат(ВыбДатаВыводаИзОборота,"ДФ=yyyy-MM-dd"); ДокументТип = "DESTRUCTION_ACT"; //Акт уничтожения (утраты/утилизации) ДокументНомер = СокрЛП(ВыбНомерДокумента); ДокументДата = Формат(ВыбДатаДокумента,"ДФ=yyyy-MM-dd"); ДанныеДляЗапроса = Новый Структура; ДанныеДляЗапроса.Вставить("inn", ИНН); ДанныеДляЗапроса.Вставить("action", ПричинаВыбытияТекст); ДанныеДляЗапроса.Вставить("action_date", ПричинаВыбытия_Дата); ДанныеДляЗапроса.Вставить("document_type", ДокументТип); ДанныеДляЗапроса.Вставить("document_number", ДокументНомер); ДанныеДляЗапроса.Вставить("document_date", ДокументДата); ДанныеДляЗапроса.Вставить("products", Новый Массив); Для Каждого Стр Из ТабТовары Цикл СтрокаТЧ = Новый Структура; СтрокаТЧ.Вставить("gtin", Стр.gtin); СтрокаТЧ.Вставить("gtin_quantity", Стр.Количество); ДанныеДляЗапроса.products.Добавить(СтрокаТЧ); КонецЦикла; Запись_JSON_ТелоДокумента = Новый ЗаписьJSON; Запись_JSON_ТелоДокумента.УстановитьСтроку(); ЗаписатьJSON(Запись_JSON_ТелоДокумента, ДанныеДляЗапроса); СтрокаДляЗапросаТелоДокумента = Запись_JSON_ТелоДокумента.Закрыть(); // ВременныйФайл = ПолучитьИмяВременногоФайла(); ЗаписьТекста = Новый ЗаписьТекста(ВременныйФайл, "CESU-8"); ЗаписьТекста.Записать(СтрокаДляЗапросаТелоДокумента); ЗаписьТекста.Закрыть(); ДД_Файла = Новый ДвоичныеДанные(ВременныйФайл); СтрокаДляЗапросаBase64 = Base64Строка(ДД_Файла); Попытка УдалитьФайлы(ВременныйФайл); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; //-- документ (шапка) ТелоДокументаБейс64 = СтрокаДляЗапросаBase64; Подпись = ???; ДокументДанныеДляЗапроса = Новый Структура; ДокументДанныеДляЗапроса.Вставить("document_format", "MANUAL"); ДокументДанныеДляЗапроса.Вставить("product_document", ТелоДокументаБейс64); ДокументДанныеДляЗапроса.Вставить("type", "LK_GTIN_RECEIPT"); ДокументДанныеДляЗапроса.Вставить("signature", Подпись); //JSON Запись_JSON = Новый ЗаписьJSON; Запись_JSON.УстановитьСтроку(); ЗаписатьJSON(Запись_JSON, ДокументДанныеДляЗапроса); СтрокаДляЗапроса = Запись_JSON.Закрыть(); Возврат СтрокаДляЗапроса; КонецФункции |
|||
3
Saari
14.10.24
✎
10:52
|
и пока мне непонятно как получить открытую часть подписи.
|
|||
4
MWWRuza
14.10.24
✎
10:58
|
Ну, понятно... Вы это делаете в каком-то восьмерошном решении...
Опять-же в каком? Просто в современных конфах, на БСП, наверняка есть какие-то готовые процедуры/функции для этого. Я например, в конфе, которая принципиально ничего общего с этим не имеет - использую универсальное, браузерное средство - CAPICOM или CADESCOM, типа так: OutSignedData=SignedData.SignCades(Signer,1,1,0); // параметр 3 - открепленная/прикрепленная(1 - открепленная), пар 4 - кодировка(0 - Base64) Но, это от безысходности, в Вашем случае, должно быть что-то штатное, я особо в это не вникал, тут, местные знатоки скорее подскажут. |
|||
5
MWWRuza
14.10.24
✎
11:00
|
(3) Я получаю по отпечатку(у меня - хранится в справочнике) объект самой КЭП, тем-же капикомом, который потом он-же использует для дальнейших действий...
|
|||
6
MWWRuza
14.10.24
✎
11:42
|
Если с типовыми методами совсем всё грустно, то у КриптоПро есть даже утилита командной строки:
C:\Program Files\Crypto Pro\CSP\csptest.exe С помощью нее можно всё это делать вплоть до того, что скриптом (батником или CMD)... Но в Вашем случае надо трясти штатные методы. |
|||
7
MWWRuza
14.10.24
✎
11:42
|
Судя по Вашему коду:
HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer " + Токен); токен Вы как-то получаете, откуда-то Вы его пихаете в заголовок запроса. А значит, подписываете как-то данные для его получения. Ну, всё остальное делается теми же средствами. |
|||
8
Saari
14.10.24
✎
11:11
|
(7) да, получаю. Сейчас покажу процедуры.
|
|||
9
Saari
14.10.24
✎
11:20
|
Вот процедуры, которые используются при получении Токена перед отправкой запроса:
Процедура ПриОткрытии() //Поиск доступных сертификатов CAPICOM_CURRENT_USER_STORE = 2; //2 - Искать сертификат в ветке "Личное" хранилища. CAPICOM_MY_STORE = "My"; // Указываем, что ветку "Личное" берем из хранилища текущего пользователя CAPICOM_STORE_OPEN_READ_ONLY = 0; // Открыть хранилище только на чтение oStore = Новый COMОбъект("CAdESCOM.Store"); // Объект описывает хранилище сертификатов oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_READ_ONLY); // Открыть хранилище сертификатов //2 вариант: обходом по коллекции и сравнение с отпечатком Для Каждого ТекСертификат Из oStore.Certificates Цикл НоваяСтрока = Сертификаты.Добавить(); НоваяСтрока.Владелец = ТекСертификат.SubjectName; НоваяСтрока.ПериодС = ТекСертификат.ValidFromDate; НоваяСтрока.ПериодДо = ТекСертификат.ValidToDate; НоваяСтрока.Контейнер = ТекСертификат.PrivateKey.UniqueContainerName; НоваяСтрока.Отпечаток = ТекСертификат.Thumbprint; КонецЦикла; КонецПроцедуры Процедура КнопкаПолучитьТокенНажатие(Элемент) // Получение данных для получения токена HTTPСоединение = Новый HTTPСоединение(Сервер,443,,,,,Новый ЗащищенноеСоединениеOpenSSL); HTTPЗапрос = новый HTTPЗапрос("/api/v3/auth/cert/key"); HTTPОтвет = HTTPСоединение.ВызватьHTTPМетод("GET",HTTPЗапрос); ОтветСтрока = HTTPОтвет.ПолучитьТелоКакСтроку("UTF-8"); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(ОтветСтрока); ДанныеJSON = ПрочитатьJSON(ЧтениеJSON); ЧтениеJSON.Закрыть(); УИД = ДанныеJSON.uuid; ДанныеДляПолученияТокена = ДанныеJSON.data; // Подписание данных для получения токена ДанныеДляПолученияТокена = ПодписатьТекст(ЗашифроватьBase64(ДанныеДляПолученияТокена, КодировкаТекста.UTF8),СертификатДляОбмена,Ложь); // Получение токена с использованием подписанных данных Соединение = Новый HTTPСоединение(Сервер,443,,,,,Новый ЗащищенноеСоединениеOpenSSL); Заголовки = Новый Соответствие; Заголовки.Вставить("Content-Type", "application/json; charset=UTF-8"); Заголовки.Вставить("Accept", "application/json"); HTTPЗапрос = Новый HTTPЗапрос("/api/v3/auth/cert/",Заголовки); ЗаписьJOIN = Новый ЗаписьJSON; ЗаписьJOIN.УстановитьСтроку(); ДанныеДляЗапроса = Новый Структура; ДанныеДляЗапроса.Вставить("uuid",УИД); ДанныеДляЗапроса.Вставить("data",ДанныеДляПолученияТокена); ЗаписатьJSON(ЗаписьJOIN,ДанныеДляЗапроса); СтрокаДляЗапроса = ЗаписьJOIN.Закрыть(); HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаДляЗапроса,КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать); Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос); ЧтениеJSON = Новый ЧтениеJSON; ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку()); Токен = ПрочитатьJSON(ЧтениеJSON, Ложь).token; КонецПроцедуры Функция ПодписатьТекст(ТекстДляПодписи, sThumbprint, bDetached) CADESCOM_BASE64_TO_BINARY = 1; // Входные данные пришли в Base64 CADESCOM_CADES_TYPE = 1; // Тип усовершенствованной подписи CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0; // Атрибут штампа времени подписи oSigner = Новый COMОбъект("CAdESCOM.CPSigner"); // Объект, задающий параметры создания и содержащий информацию об усовершенствованной подписи. oSigner.Certificate = ПолучитьСертификатПоОтпечатку(sThumbprint); oSigningTimeAttr = Новый COMОбъект("CAdESCOM.CPAttribute"); oSigningTimeAttr.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME; oSigningTimeAttr.Value = ТекущаяДата(); oSigner.AuthenticatedAttributes2.Add(oSigningTimeAttr); ТекстДляПодписи = СокрЛП(ТекстДляПодписи); oSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData"); // Объект CadesSignedData предоставляет свойства и методы для работы с усовершенствованной подписью. oSignedData.ContentEncoding = CADESCOM_BASE64_TO_BINARY; oSignedData.Content = СокрЛП(ТекстДляПодписи); EncodingType = 0; sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType); // Метод добавляет к сообщению усовершенствованную подпись. Возврат sSignedMessage; // Подпись в формате Base64 КонецФункции Функция ЗашифроватьBase64(Строка, Кодировка) Экспорт ИмяВременногоФайла = ПолучитьИмяВременногоФайла(); ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, Кодировка); ЗаписьТекста.Записать(Строка); ЗаписьТекста.Закрыть(); Двоичные = Новый ДвоичныеДанные(ИмяВременногоФайла); Результат = Base64Строка(Двоичные); Если Лев(Результат, 4) = "77u/" Тогда Результат = Сред(Результат, 5); КонецЕсли; Результат = СтрЗаменить(Результат, Символы.ПС, ""); УдалитьФайлы(ИмяВременногоФайла); Возврат Результат; КонецФункции Функция ПолучитьСертификатПоОтпечатку(ОтпечатокСтр) Рез = Неопределено; // Найденный сертификат (Com-объект) CAPICOM_CURRENT_USER_STORE = 2; //2 - Искать сертификат в ветке "Личное" хранилища. CAPICOM_MY_STORE = "My"; // Указываем, что ветку "Личное" берем из хранилища текущего пользователя CAPICOM_STORE_OPEN_READ_ONLY = 0; // Открыть хранилище только на чтение oStore = Новый COMОбъект("CAdESCOM.Store"); // Объект описывает хранилище сертификатов oStore.Open(CAPICOM_CURRENT_USER_STORE, CAPICOM_MY_STORE, CAPICOM_STORE_OPEN_READ_ONLY); // Открыть хранилище сертификатов // 1 вариант: поиск сертификата по отпечатку //CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0; //Certificates = oStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_SHA1_HASH, ОтпечатокСтр); //Рез = Certificates.Item(1); //2 вариант: обходом по коллекции и сравнение с отпечатком Для Каждого ТекСертификат Из oStore.Certificates Цикл ТекОтпечаток = ТекСертификат.Thumbprint; // возвращается отпечаток в шестнадцатеричном виде Если ВРЕГ(ТекОтпечаток) = ВРЕГ(ОтпечатокСтр) Тогда Рез = ТекСертификат; Прервать; КонецЕсли; КонецЦикла; oStore.Close(); // Закрыть хранилище сертификатов и освободить объект 61 Возврат Рез; КонецФункци Они из работающего примера. Хочу до конца разобраться в их применении. |
|||
10
Saari
14.10.24
✎
11:21
|
Сертификат у меня есть. Теперь надо какой-то командой получить его открытую часть и зашифровать в Base64.
|
|||
11
MWWRuza
14.10.24
✎
11:24
|
Ну, я пока не видел Ваши процедуры, да и вообще - что их смотреть - на последнем этапе получения токена(беарер), Вы подписываете строку данных, которую Вам вернул ЧЗ на первый запрос, и ее отправляете назад, в ответ получаете токен.
Для этого, вы что-то используете, какое-то средство ЭЦП, но, для получения токена, Вы эту строку подписываете прикрепленной ЭЦП. Для подписи документа, делаете все то-же, только в этом средстве параметр меняете на "открепленная", и собственно все. |
|||
12
Saari
14.10.24
✎
11:26
|
(11) Спасибо! Сейчас подумаю и попробую. Буду сообщать свои попытки и результат.
|
|||
13
MWWRuza
14.10.24
✎
11:27
|
Много букфф...
Вот это: // Подписание данных для получения токена ДанныеДляПолученияТокена = ПодписатьТекст(ЗашифроватьBase64(ДанныеДляПолученияТокена, КодировкаТекста.UTF8),СертификатДляОбмена,Ложь); Смотрите эту функцию. Скорее всего, последний ее параметр "Ложь", это и есть "Открепленная". Но, Вам виднее. |
|||
14
MWWRuza
14.10.24
✎
11:29
|
Ну, да:
sSignedMessage = oSignedData.SignCades(oSigner, CADESCOM_CADES_TYPE, bDetached, EncodingType); Вот это и есть этот параметр. |
|||
15
Saari
14.10.24
✎
13:30
|
Пробую...
в параметр "signature" передаю значение переменной "ДанныеДляПолученияТокена" из процедуры "КнопкаПолучитьТокенНажатие()" В ответе получаю "405 Not Allowed"... |
|||
16
ptiz
14.10.24
✎
13:46
|
(0) В типовой это делается через отдельную ВК, ибо штатными методами 1С такое не умеет.
А вообще, в конце описания TrueAPI есть пример на 1С. |
|||
17
Saari
14.10.24
✎
13:50
|
(16) Я примеры посмотрел. Токен получаю (все процедуры/функциии показал выше). Я явно чего-то недопонимаю... Поэтому прошу помочь в понимании и реализации по созданию документа.
|
|||
18
ptiz
14.10.24
✎
13:56
|
(17) Я поставил УТ 11, и её использую в качестве прокси. И не пришлось этим всем заморачиваться.
|
|||
19
Saari
14.10.24
✎
14:09
|
(18) мне осталось каким-то образом добавить подпись в структуру json. И вот пытаюсь понять как это сделать.
|
|||
20
MWWRuza
14.10.24
✎
14:52
|
(15) в параметр "signature" передаю значение переменной "ДанныеДляПолученияТокена" из процедуры "КнопкаПолучитьТокенНажатие()"
При чем тут это вообще? Что у Вас в Данных для получения токена (исходных) - ? Если на то пошло, то должно быть что-то типа того: ОтсоединеннаяЭЦПДокумента = ПодписатьТекст(ЗашифроваьBase64(ВашДокументВФорматеUTF8, КодировкаТекста.UTF8),СертификатДляОбмена,Ложь) Тогда, в "ОтсоединеннаяЭЦПДокумента" будет строка ЭЦП исходного документа. Не большая, порядка 4-10 кб. Если присоединенная - то значительно больше - это объем Вашего документа + ЭЦП. Можно сохранить ее в текстовый файл, и проверить ЭЦП с помощью инструментов КриптоПро. (для отсоединенной нужно указать и файл ЭЦП, и исходнфй документ, для присоединенной только один этот файл). И если все нормально, тогда уже двигаться дальше. |
|||
21
Saari
14.10.24
✎
15:00
|
(20) ВашДокументВФорматеUTF8 - что будет в этой переменной?
В инструкции True API в разделе 4.1.10 показано тело документа: { "inn":"1111111111", "buyer_inn":"7777777777", "action":"DONATION", "action_date":"2022-08-05", "document_type":"CONSIGNMENT_NOTE", "document_number":"56783", "document_date":"2022-07-05", "products":[ { "gtin":"04611111111111", "gtin_quantity":4, "product_cost":0.00 }, { "gtin":"04622222222222", "gtin_quantity":1, "product_cost":0.00 } ] } Мне это "тело" нужно присвоить переменной ВашДокументВФорматеUTF8? |
|||
22
Saari
14.10.24
✎
15:06
|
Написал следующее:
ОтсоединеннаяЭЦПДокумента = ПодписатьТекст(ЗашифроватьBase64(СтрокаДляЗапросаТелоДокумента, КодировкаТекста.UTF8), СертификатДляОбмена, Ложь); ДокументДанныеДляЗапроса = Новый Структура; ДокументДанныеДляЗапроса.Вставить("document_format", "MANUAL"); ДокументДанныеДляЗапроса.Вставить("product_document", ТелоДокументаБейс64); ДокументДанныеДляЗапроса.Вставить("type", "LK_GTIN_RECEIPT"); ДокументДанныеДляЗапроса.Вставить("signature", ОтсоединеннаяЭЦПДокумента); //JSON Запись_JSON = Новый ЗаписьJSON; Запись_JSON.УстановитьСтроку(); ЗаписатьJSON(Запись_JSON, ДокументДанныеДляЗапроса); СтрокаДляЗапроса = Запись_JSON.Закрыть(); Результат тот же... |
|||
23
ptiz
14.10.24
✎
15:09
|
(22) Попробуй в УТ 11 проделать аналогичные операции - там можно будет посмотреть логи и понять разницу.
|
|||
24
MWWRuza
14.10.24
✎
15:36
|
(23) Там черт ногу сломит... Хотя, кому что привычнее и понятнее.
ТС, хотите, в своей конфе наставлю "точек сохранения в файлы" всего этого безобразия, и выложу? Может так понятнее будет. |
|||
25
MWWRuza
14.10.24
✎
15:41
|
(21) Мне это "тело" нужно присвоить переменной ВашДокументВФорматеUTF8?
Ну, да, а что Вас смущает? Все так и есть. Формируете аналогичное со своими даннными, и подписываете. |
|||
26
Saari
14.10.24
✎
16:05
|
Сделал так:
ВременныйФайл = ПолучитьИмяВременногоФайла(); ЗаписьТекста = Новый ЗаписьТекста(ВременныйФайл, "CESU-8"); ЗаписьТекста.Записать(СтрокаДляЗапросаТелоДокумента); ЗаписьТекста.Закрыть(); ДД_Файла = Новый ДвоичныеДанные(ВременныйФайл); СтрокаДляЗапросаBase64 = Base64Строка(ДД_Файла); Попытка УдалитьФайлы(ВременныйФайл); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; //-- документ (шапка) ТелоДокументаБейс64 = СтрокаДляЗапросаBase64; ОтсоединеннаяЭЦПДокумента = ПодписатьТекст(ТелоДокументаБейс64, СертификатДляОбмена, Ложь); Подпись = ОтсоединеннаяЭЦПДокумента; ДокументДанныеДляЗапроса = Новый Структура; ДокументДанныеДляЗапроса.Вставить("document_format", "MANUAL"); ДокументДанныеДляЗапроса.Вставить("product_document", ТелоДокументаБейс64); ДокументДанныеДляЗапроса.Вставить("type", "LK_GTIN_RECEIPT"); ДокументДанныеДляЗапроса.Вставить("signature", Подпись); //JSON Запись_JSON = Новый ЗаписьJSON; Запись_JSON.УстановитьСтроку(); ЗаписатьJSON(Запись_JSON, ДокументДанныеДляЗапроса); СтрокаДляЗапроса = Запись_JSON.Закрыть(); И по прежнему в ответ: 405 Not Allowed |
|||
27
U4Me2
15.10.24
✎
06:51
|
А так не пробовали
ОтсоединеннаяЭЦПДокумента = ПодписатьТекст(ТелоДокументаБейс64, СертификатДляОбмена, Истина); |
|||
28
Saari
15.10.24
✎
08:40
|
(27) только что попробовал. Результат тот же: 405 Not Allowed.
Возвращается файл с ответом на запрос: <html> <head><title>405 Not Allowed</title></head> <body> <center><h1>405 Not Allowed</h1></center> <hr><center>nginx</center> </body> </html> |
|||
29
Saari
15.10.24
✎
08:44
|
В переменной "Сертификат для обмена" содержится Отпечаток подписи, получаемый при получении Токена:
oStore = Новый COMОбъект("CAdESCOM.Store"); oStore.Open(2, "My", 0); Для Каждого ТекСертификат Из oStore.Certificates Цикл Отпечаток = ТекСертификат.Thumbprint; КонецЦикла; |
|||
30
Saari
15.10.24
✎
09:48
|
еще добавлю: тестирую обработку на демонстрационном контуре (markirovka.sandbox.crptech.ru).
|
|||
31
MWWRuza
15.10.24
✎
10:49
|
В песочнице содержатся не все марки. Точнее, их там совсем мало, специальные тестовые.
Но, ошибка будет другая из-за этого, запрос будет успешно отрабатывать, 200 возвращать, а уже в тексте ответа будет ошибка, что марка не найдена. Или, 403, если пользователь не зарегистрирован в тестовом контуре и нет доступа. А 405... Не знаю, ни разу такой ошибки не было. |
|||
32
MWWRuza
15.10.24
✎
10:54
|
А вообще, тут надо пошагово отлаживать, и смотреть, на каком шаге у Вас что-то не то.
Получили джейсон запроса, посмотрели на него, насколько он корректный... Получили отпечаток - проверили, правильный или нет. Подписали текст - сохранили, проверили через инструменты КриптоПро... Ну, и так далее. |
|||
33
Saari
31.10.24
✎
08:56
|
Продолжаю осваивать работу с документами по API. Пока работаю с демонстрационным контуром.
На отправленный запрос приходит ответ 201 и уникальный идентификатор документа. Т.е. в личном кабинете документ создается (ура!), но с ошибкой: "Данные электронной подписи не соответствуют текущему участнику." Структура JSON-файла такова: ДокументДанныеДляЗапроса = Новый Структура; ДокументДанныеДляЗапроса.Вставить("document_format", "MANUAL"); ДокументДанныеДляЗапроса.Вставить("product_document", ТелоДокументаСтрокаJSONBase64); ДокументДанныеДляЗапроса.Вставить("type", "LK_GTIN_RECEIPT"); ДокументДанныеДляЗапроса.Вставить("signature", ПодписанноеТелоДокументаСтрокаJSONBase64); Перед отправкой запроса получаю Токен. При получении Токена подпись принимается системой, а при отправке документа подпись почему-то не хочет приниматься. Можете подсказать где ошибка? |
|||
34
Saari
31.10.24
✎
09:48
|
только что отправил запрос. Получил ответ с кодом 200, но документа в разделе "Документы" в личном кабинете ЧЗ не увидел...
|
|||
35
Saari
31.10.24
✎
09:51
|
ага... ответ 200 я получил когда забыл перед отправкой запроса получить токен. Поэтому в личном кабинете не находу документа.
Но почему после получения токена и создания документа приходит ответ 201 с ошибкой "Данные электронной подписи не соответствуют текущему участнику."? |
|||
36
Saari
31.10.24
✎
13:40
|
Получлось создать документ без ошибки подписания!
Сначала нужно зашифровать тело документа в Base64, которое поместить в реквизит "product_document". Затем нужно подписать зашифрованное тело документа в Base64 и поместить результат в реквизит "signature". Только в функции "ПодписатьТекст()" третий параметр должен быть "Истина". Текст функции можно увидеть в инструкции по API в Приложении2. В результате документ создался с ошибкой "Код товара <код товара> не найден в базе данных.". Это потому что в демонстрационном контуре на остатках ничего нет. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |