В данной статье постараюсь собрать большую часть примеров для взаимодействия с "Честным знаком". На Инфостарте есть не мало обработок и готовых решений, но не всегда есть возможность купить или разобраться в чужом коде. Статья в основном для тех кто начал прикручивать маркировку в свою нетиповую конфигурацию.
Итак, начнем.
1. Сертификаты.
На компьютере должен быть установлен криптопровайдеров (В примере будет рассмотрен Crypto Pro), для работы с сертификатами из 1С.
&НаКлиенте
Функция ПолучитьСертификаты()
Попытка
comStore = Новый COMОбъект("CAdESCOM.Store");
comCPSigner = Новый COMОбъект("CAdESCOM.CPSigner"); // Аналог "CAPICOM.Signer".
comSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
Исключение
Сообщить("Не установлен КриптоПро!");
Возврат Неопределено;
КонецПопытки;
comStore.Open(
2, // StoreLocation - CAPICOM_CURRENT_USER_STORE (Хранилище текущего пользователя). CAPICOM_LOCAL_MACHINE_STORE = 1; (Локальное хранилище компьютера).
"MY", // StoreName CAPICOM_MY_STORE = "My" (Хранилище персональных сертификатов пользователя).
0); // 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;
// Оставить "только сертификаты, действительные в настоящее время".
// comCertificates = comCertificates.Find(9, ); // (CAPICOM_CERTIFICATE_FIND_TIME_VALID, "the current time is assumed")
// КоличествоСертификатов = comCertificates.Count;
// Поиск по отпечатку
// Отпечаток = СтрЗаменить(Строка(Base64Значение(Base64СтрокаОтпечатка)), " ", "");
// comCertificates = comCertificates.Find(0, Отпечаток); // (CAPICOM_CERTIFICATE_FIND_SHA1_HASH( Возвращает сертификаты соответствующие указанному хэшу SHA1) , отпечаток)
// КоличествоСертификатов = comCertificates.Count;
///Основные отборы: список других параметров можно посмотреть ниже. ДополнительныеПараметрыcomStore()
Если КоличествоСертификатов = 0 Тогда
comCertificates = Неопределено;
comCPSigner = Неопределено;
comSignedData = Неопределено;
Сообщить("Не найдены актуальные ключи ЭЦП для подписи данных!");
Возврат Неопределено;
ИначеЕсли КоличествоСертификатов = 1 Тогда
Возврат comCertificates.Item(1); //Возврат сертификата
Иначе
СписокСертификатов = Новый СписокЗначений;
Для i = 1 По КоличествоСертификатов Цикл
СписокСертификатов.Добавить(i, comCertificates.Item(i).SubjectName);
КонецЦикла;
КонецЕсли;
//Возврат списка сертификатов
Возврат СписокСертификатов;
КонецФункции
&НаКлиенте
Функция ПодписатьСертификатомСтроку(ВыбранныйСертификат, СтрокаДляПодписи, Открепл)
Попытка
comStore = Новый COMОбъект("CAdESCOM.Store");
comCPSigner = Новый COMОбъект("CAdESCOM.CPSigner"); // Аналог "CAPICOM.Signer".
comSignedData = Новый COMОбъект("CAdESCOM.CadesSignedData");
Исключение
Сообщить("Не установлен КриптоПро!");
Возврат Неопределено;
КонецПопытки;
СтрокаВBase64 = Истина;
comStore.Open(
2, // StoreLocation - CAPICOM_CURRENT_USER_STORE.
"MY", // StoreName
0); // OpenMode - CAPICOM_STORE_OPEN_READ_ONLY.
comCertificates = comStore.Certificates;
comStore.Close();
comStore = Неопределено;
comCPSigner.Certificate = ВыбранныйСертификат;
// + Что-то из этого может быть нужным.
// 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.
Если СтрокаВ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(ПодписанныеДанные);
КонецФункции
&НаКлиенте
Функция УбратьСимволы1013(Строка)
Возврат СтрЗаменить(СтрЗаменить(Строка, Символы.ПС, ""), Символы.ВК, ""); // Ещё бывают символы "77u/", при необходимости удалять и их.
КонецФункции
Функция ДополнительныеПараметрыcomStore()
_ = "Название свойства Описание
|CADESCOM_STRING_TO_UCS2LE = 0x00 Данные будут перекодированы в UCS-2 little endian.
|CADESCOM_BASE64_TO_BINARY = 0x01 Данные будут перекодированы из Base64 в бинарный массив.
|CAPICOM_LOCAL_MACHINE_STORE = 1 Локальное хранилище компьютера.
|CAPICOM_CURRENT_USER_STORE = 2 Хранилище текущего пользователя.
|CADESCOM_LOCAL_MACHINE_STORE = 1 Локальное хранилище компьютера.
|CADESCOM_CURRENT_USER_STORE = 2 Хранилище текущего пользователя.
|CADESCOM_CONTAINER_STORE = 100 Хранилище сертификатов в контейнерах закрытых ключей. В данный Store попадут все сертификаты из контейнеров закрытых ключей которые доступны в системе в момент открытия.
//|CAPICOM_MY_STORE = "My" Хранилище персональных сертификатов пользователя.
|CAPICOM_STORE_OPEN_MAXIMUM_ALLOWED = 2 Открывает хранилище на чтение/запись, если пользователь имеет права на чтение/запись. Если прав на запись нет, то хранилище открывается за чтение.
|CADESCOM_XML_SIGNATURE_TYPE_ENVELOPED = 0 Вложенная подпись.
|CADESCOM_XML_SIGNATURE_TYPE_ENVELOPING = 1 Оборачивающая подпись.
|CADESCOM_XML_SIGNATURE_TYPE_TEMPLATE = 2 Подпись по шаблону.
|CADESCOM_CADES_DEFAULT = 0 Тип подписи по умолчанию (CAdES-X Long Type 1).
|CADESCOM_CADES_BES = 1 Тип подписи CAdES-BES.
|CADESCOM_CADES_T = 0x5 Тип подписи CAdES-T.
|CADESCOM_CADES_X_LONG_TYPE_1 = 0x5d Тип подписи CAdES-X Long Type 1.
|CADESCOM_PKCS7_TYPE = 0xffff Тип подписи PKCS7.
|CADESCOM_ENCODE_BASE64 = 0 Кодировка BASE64.
|CADESCOM_ENCODE_BINARY = 1 Бинарные данные.
|CADESCOM_XADES_DEFAULT = 0x00000010 Тип подписи по умолчанию (XAdES-X Long Type 1).
|CADESCOM_XADES_BES = 0x00000020 Тип подписи XAdES-BES.
|CADESCOM_XADES_T = 0x00000050 Тип подписи XAdES-T.
|CADESCOM_XADES_X_LONG_TYPE_1 = 0x000005d0 Тип подписи XAdES-X Long Type 1.
|CADESCOM_XADES_A = 0x000007d0 Тип подписи XAdES-A.
|CADESCOM_XMLDSIG_TYPE = 0 Тип подписи XMLDSIG.
|CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT = 0 Сохраняет все сертификаты цепочки за исключением корневого.
|CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN = 1 Сохраняет полную цепочку.
|CAPICOM_CERT_INFO_SUBJECT_SIMPLE_NAME = 0 Возвращает имя наименования сертификата.
|CAPICOM_CERT_INFO_ISSUER_SIMPLE_NAME = 1 Возвращает имя издателя сертификата.
|CAPICOM_CERTIFICATE_FIND_SHA1_HASH = 0 Возвращает сертификаты соответствующие указанному хэшу SHA1.
|CAPICOM_CERTIFICATE_FIND_SUBJECT_NAME = 1 Возвращает сертификаты, наименование которого точно или частично совпадает с указанным.
|CAPICOM_CERTIFICATE_FIND_ISSUER_NAME = 2 Возвращает сертификаты, наименование издателя которого точно или частично совпадает с указанным.
|CAPICOM_CERTIFICATE_FIND_ROOT_NAME = 3 Возвращает сертификаты, у которых наименование корневого точно или частично совпадает с указанным.
|CAPICOM_CERTIFICATE_FIND_TEMPLATE_NAME = 4 Возвращает сертификаты, у которых шаблонное имя точно или частично совпадает с указанным.
|CAPICOM_CERTIFICATE_FIND_EXTENSION = 5 Возвращает сертификаты, у которых имеется раcширение, совпадающее с указанным.
|CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY = 6 Возвращает сертификаты, у которых идентификатор раcширенного свойства совпадает с указанным.
|CAPICOM_CERTIFICATE_FIND_CERTIFICATE_POLICY = 8 Возвращает сертификаты, содержащие указанный OID политики.
|CAPICOM_CERTIFICATE_FIND_TIME_VALID = 9 Возвращает действующие на текущее время сертификаты.
|CAPICOM_CERTIFICATE_FIND_TIME_NOT_YET_VALID = 10 Возвращает сертификаты, время которых невалидно.
|CAPICOM_CERTIFICATE_FIND_TIME_EXPIRED = 11 Возвращает просроченные сертификаты.
|CAPICOM_CERTIFICATE_FIND_KEY_USAGE = 12 Возвращает сертификаты, содержащие ключи, которые могут быть использованны указанным способом.
|CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE = 128 Ключ может быть использован для создания цифровой подписи.
|CAPICOM_PROPID_ENHKEY_USAGE = 9 EKU.
|CAPICOM_OID_OTHER = 0 Объект не соответствует ни одному из предуставленных типов.
|CAPICOM_OID_KEY_USAGE_EXTENSION = 10 Расширение сертификата, содержащее информацию о назначении открытого ключа.
|CAPICOM_EKU_OTHER = 0 Сертификат может быть использован для чего-то, что не предустановлено.
|CAPICOM_EKU_SERVER_AUTH = 1 Сертификат может быть использован для аутентификации сервера.
|CAPICOM_EKU_CLIENT_AUTH = 2 Сертификат может быть использован для аутентификации клиента.
|CAPICOM_EKU_CODE_SIGNING = 3 Сертификат может быть использован для создания цифровой подписи.
|CAPICOM_EKU_EMAIL_PROTECTION = 4 Сертификат может быть использован для защиты электронной подписи.
|CAPICOM_EKU_SMARTCARD_LOGON = 5 Сертификат может быть использован для входа со смарт карты.
|CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0 Время подписи. Совпадает с CADESCOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME
|CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME = 1 Название документа. Совпадает с CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME
|CAPICOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION = 2 Описание документа. Совпадает с CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION
|CADESCOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0 Время подписи.
|CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_NAME = 1 Название документа.
|CADESCOM_AUTHENTICATED_ATTRIBUTE_DOCUMENT_DESCRIPTION = 2 Описание документа.
|CADESCOM_ATTRIBUTE_OTHER = -1 Прочие атрибуты.
|CADESCOM_DISPLAY_DATA_NONE = 0 Данные не будут пересылаться в устройство.
|CADESCOM_DISPLAY_DATA_CONTENT = 1 Отображаемые данные лежат в теле сообщения.
|CADESCOM_DISPLAY_DATA_ATTRIBUTE = 2 Отображаемые данные лежат в подписанном атрибуте сообщения.
|CADESCOM_ENCRYPTION_ALGORITHM_RC2 = 0 Алгоритм RSA RC2.
|CADESCOM_ENCRYPTION_ALGORITHM_RC4 = 1 Алгоритм RSA RC4.
|CADESCOM_ENCRYPTION_ALGORITHM_DES = 2 Алгоритм DES.
|CADESCOM_ENCRYPTION_ALGORITHM_3DES = 3 Алгоритм 3DES.
|CADESCOM_ENCRYPTION_ALGORITHM_AES = 4 Алгоритм AES.
|CADESCOM_ENCRYPTION_ALGORITHM_GOST_28147_89 = 25 Алгоритм ГОСТ 28147-89.
|CADESCOM_HASH_ALGORITHM_SHA1 = 0 Алгоритм SHA1.
|CADESCOM_HASH_ALGORITHM_MD2 = 1 Алгоритм MD2.
|CADESCOM_HASH_ALGORITHM_MD4 = 2 Алгоритм MD4.
|CADESCOM_HASH_ALGORITHM_MD5 = 3 Алгоритм MD5.
|CADESCOM_HASH_ALGORITHM_SHA_256 = 4 Алгоритм SHA1 с длиной ключа 256 бит.
|CADESCOM_HASH_ALGORITHM_SHA_384 = 5 Алгоритм SHA1 с длиной ключа 384 бита.
|CADESCOM_HASH_ALGORITHM_SHA_512 = 6 Алгоритм SHA1 с длиной ключа 512 бит.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411 = 100 Алгоритм ГОСТ Р 34.11-94.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256 = 101 Алгоритм ГОСТ Р 34.11-2012.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512 = 102 Алгоритм ГОСТ Р 34.11-2012.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411_HMAC = 110 Алгоритм ГОСТ Р 34.11-94 HMAC.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256_HMAC = 111 Алгоритм ГОСТ Р 34.11-2012 HMAC.
|CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_512_HMAC = 112 Алгоритм ГОСТ Р 34.11-2012 HMAC.
|LOG_LEVEL_DEBUG = 4 Уровень ведения логов DEBUG.
|LOG_LEVEL_INFO = 2 Уровень ведения логов INFO.
|LOG_LEVEL_ERROR = 1 Уровень ведения логов ERROR.
|CADESCOM_AllowNone = 0x00 Флаг запрета установки недоверенных сертификатов или сертификатов, для которых нет соответствующего запроса.
|CADESCOM_AllowNoOutstandingRequest = 0x01 Флаг создания закрытого ключа из ответа на запрос.
|CADESCOM_AllowUntrustedCertificate = 0x02 Флаг установки недоверенных сертификатов конечного пользователя и центров сертификации.
|CADESCOM_AllowUntrustedRoot = 0x04 Флаг установки сертификата, даже если корневой центр сертификации для него не является доверенным.
|CADESCOM_SkipInstallToStore = 0x10000000 Флаг пропуска установки сертификата в хранилище сертификатов.
|ENABLE_CARRIER_TYPE_CSP = 0x01 Обычный криптоконтейнер (HDIMAGE, REGISTRY).
|ENABLE_CARRIER_TYPE_FKC_NO_SM = 0x02 ФКН без SM.
|ENABLE_CARRIER_TYPE_FKC_SM = 0x04 ФКН с SM.
|ENABLE_ANY_CARRIER_TYPE = 0x07 ENABLE_CARRIER_TYPE_CSP | ENABLE_CARRIER_TYPE_FKC_NO_SM | ENABLE_CARRIER_TYPE_FKC_SM.
|DISABLE_EVERY_CARRIER_OPERATION = 0x00 Запрещенные виды носителей полностью запрещены.
|ENABLE_CARRIER_OPEN_ENUM = 0x01 На запрещенных видах носителей можно открывать и перечислять контейнеры.
|ENABLE_CARRIER_CREATE = 0x02 На запрещенных видах носителей можно создавать контейнеры.
|ENABLE_ANY_OPERATION = 0x03 ENABLE_CARRIER_OPEN_ENUM | ENABLE_CARRIER_CREATE.
|MEDIA_TYPE_REGISTRY = 0x00000001 Реестр.
|MEDIA_TYPE_HDIMAGE = 0x00000002 Жесткий диск.
|MEDIA_TYPE_CLOUD = 0x00000004 Облачный носитель.
|MEDIA_TYPE_SCARD = 0x00000008 Смарт-карта или любое другое устройство с интерфейсом смарт-карты.
|XCN_CRYPT_STRING_BASE64HEADER = 0 Кодировка base64 с использованием открывающего и закрывающего заголовков сертификата.
|AT_KEYEXCHANGE = 1 Использование ключа для подписывания и шифрования.
|AT_SIGNATURE = 2 Использование ключа только для подписывания.
|
|https://cpdn.cryptopro.ru/content/cades/plugin-methods.html";
КонецФункции
В новых конфигурациях, для подписания документов используется компонента XMLDSig. Ниже пример взаимодействия.
&НаКлиенте
Функция ПодписатьДанные(Данные,Откреп = Ложь)
///Получим внешнюю компоненту из общих макетов (КомпонентаXMLDSig)
ВнешняяКомпонента = КомпонентаПодписи();
Если ВнешняяКомпонента = Неопределено Тогда
возврат Неопределено;
КонецЕсли;
///Получим отфарматированный сертификат (Двоичные данные, преобразованные в base64)
СертификатКриптографииBase64 = ПолучитьСертификатBase64Строку();
Если СертификатКриптографииBase64 = Неопределено Тогда
возврат Неопределено;
КонецЕсли;
Попытка
АтрибутSignatureValue = ВнешняяКомпонента.CMSSign(Данные, ///Подписываемые данные
СертификатКриптографииBase64, ///Сертификат в Base64
"", ///Параоль сертификата
0, //тип подписи "CAdES-BES"
Откреп, //открепленная
17); //РежимВключенияСертификатовКриптографии.ВключатьПолнуюЦепочку
Исключение
ВызватьИсключение НСтр("ru = 'Ошибка вызова метода CMSSign компоненты XMLDSig.'") + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
///Преобразуем подпись в Base64Строку
Подпись = Base64Строка(АтрибутSignatureValue);
Подпись = СтрЗаменить(Подпись, Символы.ПС, "");
Подпись = СтрЗаменить(Подпись, Символы.ВК, "");
Возврат Подпись; ///Подписанные данные
КонецФункции
&НаКлиенте
Функция КомпонентаПодписи()
КомпонентаДвоичныеДанные = ПолучитьКомпонентуПодписи();
АдресМакета = ПоместитьВоВременноеХранилище(КомпонентаДвоичныеДанные);
Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
Иначе
УстановитьВнешнююКомпоненту(АдресМакета);
Если ПодключитьВнешнююКомпоненту(АдресМакета, "XMLDSignAddInSymbolicName", ТипВнешнейКомпоненты.Native) Тогда
ВнешняяКомпонента = Новый("AddIn.XMLDSignAddInSymbolicName.XMLDSignAddIn");
Иначе
Сообщить(ОписаниеОшибки());
ВнешняяКомпонента = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат ВнешняяКомпонента;
КонецФункции
&НаСервере
Функция ПолучитьКомпонентуПодписи() Экспорт
Возврат ПолучитьОбщийМакет("КомпонентаXMLDSig");
КонецФункции
&НаСервере
Функция ПолучитьСертификатBase64Строку() Экспорт
///Получим двоичные данные сертификата
ДанныеСертификата = Справочники.СертификатыЭЦП.НайтиПоКоду("01").ФайлСертификата.Получить();
///Зашифруем в Base64
СтрокаBase64 = Base64Строка(ДанныеСертификата);
Значение = СтрЗаменить(СтрокаBase64, Символы.ВК, "");
Значение = СтрЗаменить(Значение, Символы.ПС, "");
Возврат Значение;
КонецФункции
P.S. В новых версиях 1С имеется возможность взаимодействия с сертификатами с помощью "Менеджера Криптографии" и "Сертификата Криптографии". Но информацию по их применению я так и не нашел... (Как подписывать, как прикреплять подпись, как прикрепить Открепленную подпись и т.д.). У кого получилось взаимодействовать с типовым механизмом - просьба отписаться в коммментах.
2. Api "Честный знак"
Для получения новых кодов маркировки и для подачи отчета о нанесении, необходимо подключение к СУЗ (Станция управления заказами). Для подключения к СУЗ необходимо получить Токен. (Статический токен больше не поддерживается с 1.10.2021, динамический имеет ограниченное время действия -10 часов).
Для получения необходимо зайти в СУЗ - Устройства - Создать устройства.
Создаем новое устройство.
Копируем строки "OMS ID" и "Идентификатор соединения".
Подключаемся из 1С.
#Если ТонкийКлиент Тогда
Функция ПроверитьДоступностьСУЗ_V2()
OMSID = "Ваш oms id;
ИдентификаторСоединения = "Ваш ИД";
Сервер = "markirovka.crpt.ru";
СертификатCOM = ПолучитьСертификаты(); ///Необходимо выбрать сертификат из списка
//Сформируем новый динамический Токен
Токен = СформироватьНовыйТокен(OMSID, СертификатCOM, ИдентификаторСоединения, Сервер);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("clientToken", Токен);
URLЗапроса = СтрШаблон("api/v2/milk/ping?omsId=%1",OMSID); ///Молочная продукция
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
Соединение = Новый HTTPСоединение(
"suzgrid.crpt.ru", ///Адрес подключения СУЗ
443,,, ///Порт
Неопределено, ///Прокси
60, ///Таймер
Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС()));
HTTPОтвет = Соединение.Получить(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда ///Успешно получен ответ
ДанныеОбработки = ТекстJSONВОбъект(HTTPОтвет.ПолучитьТелоКакСтроку());
Если ДанныеОбработки = Неопределено Тогда
//ошибка
Иначе
// Структура - Ожидаемое результат запроса:
// * omsId - GUID - Идентификатор СУЗ
Сообщить("Успешно!: " + ДанныеОбработки.omsId);
КонецЕсли;
КонецЕсли;
КонецФункции
Функция СформироватьНовыйТокен(OMSID, СертификатCOM, ИдентификаторСоединения, Сервер)
// Получение данных для получения токена
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;
// Подписание данных для получения токена
ПодписанныеДанные = ПодписатьСертификатомСтроку(
СертификатCOM,
Зашифровать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;
Возврат Токен;
КонецФункции
Функция ЗашифроватьBase64(Строка, Кодировка) Экспорт
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ЗаписьТекста = Новый ЗаписьТекста(ИмяВременногоФайла, Кодировка);
ЗаписьТекста.Записать(Строка);
ЗаписьТекста.Закрыть();
Двоичные = Новый ДвоичныеДанные(ИмяВременногоФайла);
Результат = Base64Строка(Двоичные);
Если Лев(Результат, 4) = "77u/" Тогда
Результат = Сред(Результат, 5);
КонецЕсли;
Результат = СтрЗаменить(Результат, Символы.ПС, "");
УдалитьФайлы(ИмяВременногоФайла);
Возврат Результат;
КонецФункции
#КонецЕсли
&НаКлиенте
Функция ОтправитьОтчетОНанесении(СрокГодности,ТаблицаКодовМаркировок,Номенклатура)
Перем OmsId; //Заменить на ваши данные
Перем ТокенДоступа;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
Соединение = Новый HTTPСоединение("suzgrid.crpt.ru",443,,,Неопределено,60,ЗащищенноеСоединение);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
ЗаголовокHTTP.Вставить("clientToken", ТокенДоступа);
ПараметрыURL = Новый Массив;
ПараметрыURL.Добавить(OmsId);
URLЗапроса = СтрШаблон("api/v2/milk/utilisation?omsId=%1",СтрСоединить(ПараметрыURL, "&"));
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("usageType", "PRINTED"); ///Тип использования: VERIFIED (Нанесение КМ подтверждено) , PRINTED - КМ Напечатано
ТелоЗапроса.Вставить("expDate", формат(СрокГодности,"ДФ=ггММдд")); ///Дата окончания срока годности
ТелоЗапроса.Вставить("capacity", Число(Формат(ТаблицаКодовМаркировок.Количество(),"ЧДЦ=3"))); ///Объем продукции
ТелоЗапроса.Вставить("usedInProduction", 0); ///Признак использованияКМ на производстве:0 – значение по умолчанию;
ТелоЗапроса.Вставить("cisType", "UNIT"); ///Единичный товар
ТелоЗапроса.Вставить("sntins", Новый Массив); ///Массив кодов маркировок
Для каждого ТекСтрока из ТаблицаКодовМаркировок Цикл
ПолныйКодМаркировки = ТекСтрока.ПолныйКодМаркировки; ///Полный код маркировки с символикой GS1 DataMatrix FNC1
Если ПустаяСтрока(ПолныйКодМаркировки) Тогда
ВызватьИсключение("Не найден полный код маркировки у номенклатуры:" + Номенклатура);
КонецЕсли;
//Стр.Добавить(ПолныйКодМаркировки); ///Полный код
ТелоЗапроса.sntins.Добавить(ПолныйКодМаркировки);
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON();
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса);
ТекстJSON = ЗаписьJSON.Закрыть();
///Отчет о нанесении можно не подписывать. Но если надо:
//Если Сертификат <> Неопределено Тогда
// ПодписанныйДокумент = ПодписатьСертификатомДокумент(
// ПолучитьСертификаты(Истина,Истина,Сертификат),
// ЗашифроватьBase64(ТекстJSON, КодировкаТекста.UTF8),Ложь);
//
// ЗаголовокHTTP.Вставить("X-Signature", ПодписанныйДокумент);
//КонецЕсли;
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
ИДДок = Ответ.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ИДДок);
РезультатРазбора = ПрочитатьJSON(Чтение, ложь);
ИдентификаторОтчетаОНанесении = РезультатРазбора.reportId; ///ИД созданного документа в Честном знаке "СУЗ" - Отчет о нанесении
Возврат ИдентификаторОтчетаОНанесении;
///P.S. Обычно таблицу с кодом маркировки хранят на сервере, для передачи таблицы лучше использовать ЗаписьJSON и ЧтениеJSON
///так как код маркировки содержит спец символ GS1, который будет выдавать ошибку при передаче.
///Функция НаСервере()
/// ЗаписьJSON = Новый ЗаписьJSON;
/// ЗаписьJSON.УстановитьСтроку();
/// ЗаписатьJSON(ЗаписьJSON, МассивТаблицыВыгрузки);
/// ТаблицаКодовМаркировок = ЗаписьJSON.Закрыть();
///Функция НаКлиенте()
/// ЧтениеJSON = Новый ЧтениеJSON;
/// ЧтениеJSON.УстановитьСтроку(НаСервере());
/// ТаблицаКодовМаркировок = ПрочитатьJSON(ЧтениеJSON, ложь);
КонецФункции
Отчет об агрегации можно формировать в самой системе "Честного знака", и в системе СУЗ. Разницы нет. Документы появятся и там и там. Ниже идет пример отправки в СУЗ:
&НаКлиенте
Функция Агрегирование()
Перем ИННОрганизации; ///Заменить на свои данные
Перем OmsId;
Перем ТокенДоступа;
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
Соединение = Новый HTTPСоединение("suzgrid.crpt.ru",443,,,Неопределено,60,ЗащищенноеСоединение);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
ЗаголовокHTTP.Вставить("clientToken", ТокенДоступа);
ПараметрыURL = Новый Массив;
ПараметрыURL.Добавить(OmsId);
URLЗапроса = СтрШаблон("api/v2/milk/aggregation?omsId=%1",СтрСоединить(ПараметрыURL, "&"));
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("participantId", ИННОрганизации); ///ИНН Организации
ТелоЗапроса.Вставить("aggregationUnits", Новый Массив); ///Массив агрегации КоличествоВУпаковке
Для каждого стр из ТаблицаАгрегации цикл ///Дерево значений
ТелоМассива = новый Структура;
ТелоМассива.Вставить("aggregatedItemsCount" , ТаблицаКодовМаркировок.Строки.Количество()); ///Количество штук в 1 агрегации (По факту сколько содержится, к примеру получилось 30шт в 32 упаковке)
ТелоМассива.Вставить("aggregationType", "AGGREGATION");
ТелоМассива.Вставить("aggregationUnitCapacity", 32); ///Количество штук в одной упаковке
ТелоМассива.Вставить("sntins", Новый Массив);
Для каждого ТекСтрока из ТаблицаКодовМаркировок.Строки Цикл
//ПолныйКодМаркировки = ТекСтрока.ПолныйКодМаркировки;
КодМаркировки = ТекСтрока.КодМаркировки; //При агрегировании (И вводе в оборот) необходимо использовать сокращенный код маркировки (первые 2 группы Полного кода, до спец символа)
Если ПустаяСтрока(КодМаркировки) Тогда
ВызватьИсключение("Не найден код маркировки");
КонецЕсли;
ТелоМассива.sntins.Добавить(КодМаркировки);
КонецЦикла;
ТелоМассива.Вставить("unitSerialNumber", стр.КодАгрегации);
ТелоЗапроса.aggregationUnits.Добавить(ТелоМассива);
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON();
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса);
ТекстJSON = ЗаписьJSON.Закрыть();
///Отчет об агрегации можно не подписывать. Но если надо:
//Если Сертификат <> Неопределено Тогда
// ПодписанныйДокумент = ПодписатьСертификатомДокумент(
// ПолучитьСертификаты(Истина,Истина,Сертификат),
// ЗашифроватьBase64(ТекстJSON, КодировкаТекста.UTF8),Ложь);
//
// ЗаголовокHTTP.Вставить("X-Signature", ПодписанныйДокумент);
//КонецЕсли;
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
ИДДок = Ответ.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ИДДок);
РезультатРазбора = ПрочитатьJSON(Чтение, ложь);
Возврат РезультатРазбора.reportId; /// ИД созденного документа Агрегации в "Честном знаке"
/// Возвращает структуру:
// omsId
// reportId
КонецФункции
Получение Токена системы "Честный знак", немножко отличается (Не добавляется идентификатор соединения)
&НаКлиенте
Функция ПолучитьТокенЧестныйЗнак()
ИдентификаторСоединения = "Ваш ИД";
Сервер = "markirovka.crpt.ru";
СертификатCOM = ПолучитьСертификаты(); ///Необходимо выбрать сертификат из списка
// Получение данных для получения токена
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;
// Подписание данных для получения токена
ПодписанныеДанные = ПодписатьСертификатомСтроку(
СертификатCOM,
Зашифровать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;
///Токен имеет ограниченное время 10 часов. Можно хранить токен в системе и проверять его срок действия, по истечению - формировать новый
/// Если СрокДействияТокенаИстек(СтарыйТокен) Тогда Токен = СформироватьНовыйТокен() Иначе Токен = СтарыйТокен КонецЕсли;
Возврат Токен;
КонецФункции
#Область РасшифровкаТокена
Функция СрокДействияТокенаИстек(ТокенДоступа)
РезультатРазбораТокена = РасшифроватьТокенJWT(ТокенДоступа);
Если РезультатРазбораТокена = Неопределено Тогда
Возврат Истина;
Иначе
ДействуетДо = ДатаИзСтрокиUNIX(РезультатРазбораТокена.exp, 1);
Если ДействуетДо < (ТекущаяДата() - 600) Тогда /// Истекает через 10 мин
Возврат Истина;
Иначе
возврат Ложь;
КонецЕсли;
КонецЕсли;
КонецФункции
Функция РасшифроватьТокен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;
КонецФункции
Функция ДатаИзСтрокиUNIX(Значение, Делитель = 1000) Экспорт
Возврат МестноеВремя('19700101' + Цел(Значение / Делитель));
КонецФункции
#КонецОбласти
Ввод в оборот.
Документ "Ввод в оборот" создается в системе "Честный знак".
Новый документ сформируется в системе и вернет уникальный идентификатор , даже если документ содержит ошибки, при этом он может не отображаться в списке документов "Честного знака"!
Информацию о созданном документе так же можно проверить с помощью api, где будет все подробно описано.
&НаКлиенте
Функция ВводВОборот()
Перем ИННОрганизации;
Перем ТокенДоступа;
Перем Категория; ///2105009100 — Мороженое и прочие виды пищевого льда
СертификатCOM = ПолучитьСертификаты(); ///Необходимо выбрать сертификат из списка
///Формирование основного текста
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("participant_inn", ИННОрганизации); ///ИНН участника оборота товаров
ТелоЗапроса.Вставить("production_date", Формат(ДатаВыпуска,"ДФ=yyyy-MM-dd")); ///Дата производства товара
ТелоЗапроса.Вставить("producer_inn", ИННОрганизации); ///ИНН производителя товара
ТелоЗапроса.Вставить("owner_inn", ИННОрганизации); ///ИНН собственника товара
ТелоЗапроса.Вставить("production_type", "OWN_PRODUCTION"); ///Тип производство - Собственное
ТелоЗапроса.Вставить("products", Новый Массив);
Для каждого стр из ТаблицаАгрегации Цикл //Дерево значений по Коду агрегации ///Если используются агрегации - заполняем код агрегации, В "Честном знаке" проставятся упаковки с содержащеми КМ
СтрокаКодАгрегации = стр.КодАгрегации;
ТаблицаКодовМаркировок = стр.КодыМаркировок;
Если ПустаяСтрока(СтрокаКодАгрегации) Тогда
Для каждого мм из ТаблицаКодовМаркировок цикл
СтрокаТЧ = Новый Структура;
СтрокаТЧ.Вставить("production_date", Формат(ДатаВыпуска,"ДФ=yyyy-MM-dd")); ///Дата выпуска
СтрокаТЧ.Вставить("uit_code", мм.КодМаркировки); ///Код маркировки(В сокращенном виде - первые 2 группы полного кода, до спец символики)
СтрокаТЧ.Вставить("tnved_code", Категория); ///Код ТН ВЭД (10 знаков)
//Подтверждающий документ заполнять не обязательно, но если нужно:
///СтрокаТЧ.Вставить("certificate_document", "CONFORMITY_DECLARATION"); ///Вид подтверждающего документа (Декларация)
///СтрокаТЧ.Вставить("certificate_document_number", ДанныеСертификата.Сертификат);
///СтрокаТЧ.Вставить("certificate_document_date", Формат(ДанныеСертификата.ДатаНачала,"ДФ=yyyy-MM-dd"));
ТелоЗапроса.products.Добавить(СтрокаТЧ);
КонецЦикла;
Иначе
СтрокаТЧ = Новый Структура;
СтрокаТЧ.Вставить("production_date", Формат(ДатаВыпуска,"ДФ=yyyy-MM-dd")); ///Дата выпуска
СтрокаТЧ.Вставить("uitu_code", СтрокаКодАгрегации); ///Код агрегации
СтрокаТЧ.Вставить("tnved_code", Категория); ///Код ТН ВЭД (10 знаков)
///СтрокаТЧ.Вставить("certificate_document", "CONFORMITY_DECLARATION"); ///Вид подтверждающего документа (Декларация)
///СтрокаТЧ.Вставить("certificate_document_number", ДанныеСертификата.Сертификат);
///СтрокаТЧ.Вставить("certificate_document_date", Формат(ДанныеСертификата.ДатаНачала,"ДФ=yyyy-MM-dd"));
ТелоЗапроса.products.Добавить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
ЗаписьJSON = Новый ЗаписьJSON();
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса);
ТекстJSON = ЗаписьJSON.Закрыть();
ТекстXML64 = ЗашифроватьBase64(ТекстJSON, КодировкаТекста.UTF8);
///Подпись текста
ОткрепленнаяПодпись = Истина;
ПодписанныйДокумент = ПодписатьСертификатомДокумент( ///Необходимо открепить подпись!
ПолучитьСертификаты(2,СертификатCOM),ТекстXML64,ОткрепленнаяПодпись);
///Отправка текста
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
HTTPСоединение = Новый HTTPСоединение("markirovka.crpt.ru",443,,,,60,ЗащищенноеСоединение);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=UTF-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
ЗаголовокHTTP.Вставить("Authorization", "Bearer " + ТокенДоступа);
URLЗапроса = "/api/v3/true-api/lk/documents/create?pg=milk";
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
ТелоЗапроса = Новый Структура;
ТелоЗапроса.Вставить("document_format", "MANUAL"); //Тип документа (для json указать MANUAL)
ТелоЗапроса.Вставить("product_document",ТекстXML64); //Документ без подписи
ТелоЗапроса.Вставить("signature", ПодписанныйДокумент); //Документ с подписью
ТелоЗапроса.Вставить("type", "LP_INTRODUCE_GOODS"); // – Ввод в оборот. Производство РФ. json;
ТелоЗапроса.Вставить("product_group", "milk"); //Товарная группа - Молочная продукция
ЗаписьJSON = Новый ЗаписьJSON();
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, "");
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON);
ЗаписатьJSON(ЗаписьJSON, ТелоЗапроса);
ТекстJSON = ЗаписьJSON.Закрыть();
HTTPЗапрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
ИдентификаторДокументаЧестныйЗнак = Ответ.ПолучитьТелоКакСтроку();
Возврат ИдентификаторДокументаЧестныйЗнак; //Вернет просто Идентификатор (Строкой)
КонецФункции
&НаКлиенте
Функция СвойствоДокументаПоИД(ИдентификаторНовогоДокумента) Экспорт
Перем ТокенДоступа;
URLЗапроса = "/api/v3/true-api/doc/"+ИдентификаторНовогоДокумента+"/info";
Сервер = "markirovka.crpt.ru";
HTTPСоединение = Новый HTTPСоединение(Сервер,443,,,,,Новый ЗащищенноеСоединениеOpenSSL);
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=UTF-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
ЗаголовокHTTP.Вставить("Authorization", "Bearer " + ТокенДоступа);
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
Соединение = Новый HTTPСоединение(Сервер,443,,,Неопределено,60,ЗащищенноеСоединение);
HTTPОтвет = Соединение.Получить(HTTPЗапрос);
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
РезультатРазбора = ПрочитатьJSON(Чтение, ложь);
ВОЗВРАТ РезультатРазбора;
//Если РезультатРазбора.status = "CHECKED_OK" Тогда
// Всё успешно!;
//ИначеЕсли "IN_PROGRESS" Тогда
// Документ всё еще в процессе - ошибок нет, нужно ждать
//Иначе
// Сообщить(РезультатРазбора.downloadDesc); ///Сообщения об ошибке
//КонецЕсли;
КонецФункции
Можно узнать информацию любого вида документа системы "Честный знак" (Ввод в оборот, списание, агрегирование и т.д.) За исключением информации об "Отчете о нанесении".
&НаКлиенте
Функция УЗНАТЬ_БАЛАНС() Экспорт ///Проверить баланс лицевого счета Честный знак
Перем ТокенДоступа;
Сервер = "markirovka.crpt.ru";
HTTPСоединение = Новый HTTPСоединение(Сервер,443,,,,,Новый ЗащищенноеСоединениеOpenSSL);
URLЗапроса = "/api/v3/true-api/elk/product-groups/balance?productGroupId=8";
ЗаголовокHTTP = Новый Соответствие();
ЗаголовокHTTP.Вставить("Content-Type", "application/json; charset=UTF-8");
ЗаголовокHTTP.Вставить("Accept", "application/json");
ЗаголовокHTTP.Вставить("Accept-Charset", "utf-8");
ЗаголовокHTTP.Вставить("Authorization", "Bearer " + ТокенДоступа);
HTTPЗапрос = Новый HTTPЗапрос(URLЗапроса, ЗаголовокHTTP);
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС());
Соединение = Новый HTTPСоединение(Сервер,443,,,Неопределено,60,ЗащищенноеСоединение);
HTTPОтвет = Соединение.Получить(HTTPЗапрос);
ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Попытка
РезультатРазбора = ПрочитатьJSON(Чтение, ложь);
///Получится струтура с результатом:
///balance 1 200 120 Число // Сумма в копейках
///contractId 1 000 002 Число // ИДентификатор договора (Номер счета)
///organisationId 13 567 555 226 Число // ИДентификатор лицевого счета организации
///productGroupId 8 Число // ИДентификатор группы маркировки ( 8 - Для молочной продукции)
Возврат РезультатРазбора;
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции