Имя: Пароль:
1C
1C 7.7
v7: Узнать статус кода идентификации товара API ЧЗ
0 oskarsan
 
07.06.21
14:14
Доброго всем. Появилась необходимость проверять КИ при приемке и продаже (в обороте/выбыл) 1с77 ТиС.
Сделал все одной процедурой для удобства отладки.

Процедура Сформировать()
       УИД = "";
    стрДата = "";
    Ответ = "";
    токен = "";
    ОтпечатокСтр = "01500F299ADC0F85C320EB27BA2F635F6F2C8A";
    КИТ = "010462005892774421Ehqj=O-Dlzm0R";
    ЗапросJSON = "{""cises"":[" + РазделительСтрок + КИТ + РазделительСтрок + "]" + РазделительСтрок + "}";
        ВремТекст = СоздатьОбъект("Текст");
        ВремТекст.ДобавитьСтроку(ЗапросJSON);
        ВремТекст.Записать("c:\1\test.json");
        
    // получаем uuid и data
    WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Option(2,"utf-8");
    WinHttp.SetTimeouts(0, 0, 0, 0);
    
    //Url = "https://ismotp.crptech.ru/v3/true-api/auth/key";
    Url = "https://ismotp.crptech.ru/api/v3/auth/cert/key";
    WinHttp.Open("GET", Url, 1);
    WinHttp.SetRequestHeader("Content-Type", "application/json");
    WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
    WinHttp.Send();
    
    RequestTimeout = 40;
    Попытка
        Рез = WinHttp.WaitForResponse(RequestTimeout);
    Исключение
        Рез = 0;
        Ответ = ОписаниеОшибки();
    КонецПопытки;
    
    Ответ = "";
    Если Рез = -1 Тогда
        Статус = WinHttp.status();
        Ответ = СокрЛП(WinHttp.ResponseText());
    КонецЕсли;  
    
    УИД = Сред(Ответ,10,36);
    
    стрДата = Сред(Ответ,56,30);    
    Сообщить(УИД);
    Сообщить(стрДата);
    
    // подписываем data
    infile = "c:\1\infile.txt";
    outfile = "c:\1\outfile.txt";
    //Если БезBOM = 1 Тогда
        ВремТекст = СоздатьОбъект("Текст");
        ВремТекст.ДобавитьСтроку(стрДата);
        ВремТекст.Записать(infile);
    //Иначе
    //    АдоДБСтрим = СоздатьОбъект("ADODB.Stream");
    //    АдоДБСтрим.Mode = 3;
    //    АдоДБСтрим.Type = 2;//текст
    //    
    //    АдоДБСтрим.charset="utf-8";
    //    АдоДБСтрим.Open();
    //    АдоДБСтрим.WriteText(стрДата);
    //    АдоДБСтрим.Position=0;
    //    АдоДБСтрим.SaveToFile(infile,2);
    //    АдоДБСтрим.Close();
    //КонецЕсли;
    Рез = ""; // Найденный сертификат (Com-объект)
    CAPICOM_CURRENT_USER_STORE = 2;    //2 - Искать сертификат в ветке "Личное" хранилища.
    CAPICOM_MY_STORE = "My";// Указываем, что ветку "Личное" берем из хранилища текущего пользователя
    CAPICOM_STORE_OPEN_READ_ONLY = 0; // Открыть хранилище только на чтение
    //oStore = СоздатьОбъект("CAdESCOM.Store"); // Объект описывает хранилище сертификатов
    oStore = СоздатьОбъект("CAPICOM.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, ОтпечатокСтр);
    Cert = Certificates.Item(1);
    
    //2 вариант: обходом по коллекции и сравнение с отпечатком
    //Для Каждого ТекСертификат Из oStore.Certificates Цикл
    //    ТекОтпечаток = ТекСертификат.Thumbprint; // возвращается отпечаток в шестнадцатеричном виде
    //    Если ВРЕГ(ТекОтпечаток) = ВРЕГ(ОтпечатокСтр) Тогда Рез = ТекСертификат;
    //        Прервать;
    //    КонецЕсли;
    //КонецЦикла;
    oStore.Close(); // Закрыть хранилище сертификатов и освободить объект 61
    ScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
    ScrptCtrl.Language = "vbscript";
    
    code = "
    |Function Signer(FileName, OutFileName, Cert)
    |Set FileIn = CreateObject(""ADODB.Stream"")
    |FileIn.Type = 1
    |FileIn.Mode = 3
    |FileIn.Open()
    |FileIn.LoadFromFile(FileName)
    |BinaryIn = FileIn.Read(-1)
    |Set Signer = CreateObject(""CAPICOM.Signer"")
    |Signer.Certificate = Cert
    |Signer.Options = 2
    |Set SignedData = CreateObject(""CAPICOM.SignedData"")
    |SignedData.Content = BinaryIn
    |SignData = SignedData.Sign(Signer, False, 1)
    |Set FileOut = CreateObject(""ADODB.Stream"")
    |FileOut.Type = 2
    |FileOut.Mode = 3
    |FileOut.Open()
    |FileOut.WriteText(SignData)
    |FileOut.SaveToFile OutFileName, 2
    |FileOut.Close()
    |FileIn.Close()
    |Set objFSO = CreateObject(""Scripting.FileSystemObject"")
    |Set writer = CreateObject(""Adodb.Stream"")
      |Set reader = CreateObject(""Adodb.Stream"")
      |reader.Open
      |reader.LoadFromFile OutFileName
      |writer.Mode=3
      |writer.Type=1
      |writer.Open
      |reader.position=2
      |reader.copyto writer,-1
      |writer.SaveToFile OutFileName,2
      |Set writer = Nothing
      |Set reader = Nothing
    |SignedData = Unassigned
    |Signer = Unassigned
    |FileIn = Unassigned
    |FileOut = Unassigned

    |End Function
    |";
      
    ScrptCtrl.AddCode(code);
    Попытка
        Рез  = ScrptCtrl.Modules("Global").CodeObject.Signer(infile, outfile, Cert);
    Исключение
        ТекстОшибки    =ОписаниеОшибки();
        Сообщить("Описание ошибки: " + ТекстОшибки,"!");        
    КонецПопытки;
    
    готДата = outfile;
    
    //Получаем токен
    сзJSONЗапрос    = СоздатьОбъект("СписокЗначений");
    сзJSONЗапрос.Установить("uuid",УИД);
    сзJSONЗапрос.Установить("data",готДата);  
    
    Url = "https://ismotp.crptech.ru/api/v3/auth/cert";
    
    WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Option(2,"utf-8");
    WinHttp.SetTimeouts(0, 0, 0, 0);    
        н = 0;
        Количество = сзJSONЗапрос.РазмерСписка();
        ЗапросJSON = "{";
        
        Для СчЦ = 1 По Количество Цикл
            Ключ = "";
            Значение = сзJSONЗапрос.ПолучитьЗначение(СчЦ,Ключ);
            ЗапросJSON = ЗапросJSON + """" + Ключ + """" + ": " + """" + Значение + """" + ?(СчЦ < Количество, ", ", "");
        КонецЦикла;
        ЗапросJSON = ЗапросJSON + "}";
    WinHttp.Open("POST",Url,1);
    WinHttp.SetRequestHeader("Content-Type", "application/json");
    WinHttp.SetRequestHeader("Accept-Charset", "utf-8");
    WinHttp.Send(ЗапросJSON);
    RequestTimeout = 40;
    Попытка
        Рез = WinHttp.WaitForResponse(RequestTimeout);
    Исключение
        //ошибка
        Рез = 0;
        Ответ = ОписаниеОшибки();
    КонецПопытки;

    Если Рез = -1 Тогда
        Статус = WinHttp.status();
        СтатусТекст = WinHttp.statusText();
        Ответ = СокрЛП(WinHttp.ResponseText());
    КонецЕсли;

    Токен = Сред(Ответ,11,СтрДлина(Ответ)-10-2);
    
    //получаем инфу о КИТ
    Url="https://ismp.crpt.ru/api/v3/facade/cis/cis_list/";
    ФайлJSON = "c:\1\test.json";
    
    WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Option(2,"utf-8");
    //Отключаем проверку сертификата
    Скрипт= СоздатьОбъект("MSScriptControl.ScriptControl");
    Скрипт.language="javascript";
    Скрипт.AddObject("WinHttp",WinHttp);
    Скрипт.Eval("WinHttp.Option(4)=13056");//intSslErrorIgnoreFlags
    Скрипт.Eval("WinHttp.Option(6)=true");//blnEnableRedirects
    Скрипт.Eval("WinHttp.Option(12)=true");//blnEnableHttpsToHttpRedirects
    //Сам запрос
    WinHttp.Open("POST", Url, 0);
    WinHttp.SetRequestHeader("Authorization","Bearer "+Токен);
    WinHttp.SetRequestHeader("Content-type", "application/json");

    oADOStream = СоздатьОбъект("ADODB.Stream");
    oADOStream.Type = 1; //Binary
    oADOStream.Open();
    oADOStream.LoadFromFile(ФайлJSON);

    Попытка
        WinHttp.Send(oADOStream);
        //При явном - строку запроса нужно получить из файла, тогда получится:
        // WinHttp.Send(строка запроса из файла);
        Ответ = WinHttp.ResponseText();
    Исключение
        Ответ = "Ошибка: "+ОписаниеОшибки();
    КонецПопытки;
    
    Поз = Найти(Ответ,"status");
    Ответ = Сред(Ответ,Поз+2,7);
    Сообщить(Ответ);

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


и вот тут готДата = outfile; загвоздка как вытянуть из файла подписанные данные? Готовые обработки находил, но нет возможности скачать.
1 oskarsan
 
17.06.21
17:06
(0) С этим разобрался

    //Прочитаем подписанную data и уберем лишнее
    oADOStream = СоздатьОбъект("ADODB.Stream");
    //oADOStream.Type = 1; //Binary
    oADOStream.Mode = 3;
    oADOStream.Type = 2;//текст
    oADOStream.charset="utf-8";
    oADOStream.Open();
    oADOStream.LoadFromFile(outfile);
    oADOStream.Position = 0;
    ТекстДата = oADOStream.ReadText(-1);
    oADOStream.Close();
    готДата = "";
    Для СчСтрок = 1 По СтрКоличествоСтрок(ТекстДата) Цикл
        ТекСтрока = СтрПолучитьСтроку(ТекстДата,СчСтрок);
        Если Лев(ТекСтрока,4) = "----" Тогда
            Продолжить;
        КонецЕсли;
        ТекСтрока = СтрЗаменить(ТекСтрока,РазделительСтрок,"");
        готДата = готДата + ТекСтрока;
    КонецЦикла;
2 oskarsan
 
17.06.21
17:14
Почему ответ возвращается пустым?

КИТ = "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="+КИТ;
    
    WinHttp = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
    //WinHttp.Option(2,"utf-8");
    WinHttp.SetTimeouts(0, 0, 0, 0);    
    WinHttp.Open("GET", Url, 0);
    //WinHttp.Open("POST", Url, 0);
    WinHttp.SetRequestHeader("Authorization","Bearer "+Токен);
    WinHttp.SetRequestHeader("Content-type", "application/json");
    WinHttp.SetRequestHeader("childrenPaging", "true");
    //WinHttp.Send(ЗапросJSON);
    WinHttp.Send();
    RequestTimeout = 40;
    Попытка
        Рез = WinHttp.WaitForResponse(RequestTimeout);
    Исключение
        //ошибка
        Рез = 0;
        Ответ = ОписаниеОшибки();
    КонецПопытки;

    Если Рез = -1 Тогда
        Статус = WinHttp.status();
        СтатусТекст = WinHttp.statusText();
        Ответ = СокрЛП(WinHttp.ResponseText());
    КонецЕсли;
[\1C]
Дело в экранировании? Пробовал через JSON - не работает.