Получение суммы среднемесячных платежей в режиме "Одного окна" для расчета показателя долговой нагрузки

04.06.24

Интеграция - WEB-интеграция

C 1 июля 2024 г. для расчета ПДН (Показателя долговой нагрузки) в целях расчета суммы величин ССП (суммы среднемесячных платежей) к использованию возможен только подход, установленный пунктом 2.3 Указания № 6579-У ЦБ РФ, а именно - необходимо получать данные из всех четырех КБКИ, а не только из одного.

В данной статье представлен код, который позволяет получать данные ССП для расчета ПДН в режиме "одного окна" из любого БКИ (НБКИ, ОКБ, Эквифакс и прочие).

На этом этапе у вас уже должен быть заключен договор с БКИ, на руках имеется сертификат, полученный от ЦБ, и вы зарегистрировали его в БКИ для отправки запросов и шифрования соединения (согласно требованиям ЦБ - все запросы должны осуществляться по защищенному соединению + запрос должен быть подписан присоединенной ЭП).

Все запросы в случае НБКИ необходимо направлять по адресу https://reports.nbki.ru/qbch/

Ссылка на описание API ЦБ https://www.cbr.ru/ckki/transfer_inform/

По сути, данная разработка применима к любому из четырех БКИ, ведь API у всех одинаковое и теперь ЦБ регулирует, чтобы не нужно было под каждое конкретное БКИ подстраиваться.

Так что - заключить договор можно с любом БКИ, код будет рабочим всегда, меняется только корневой адрес, куда слать запросы.

Первый этап - для упрощения текст шаблона можно поместить в макет, или в процедуру, как строку с символами переноса. Я выбрал для себя первый вариант. 

Чтобы не выкладывать готовую обработку, привожу тексты процедур и текст шаблона ниже:

Шаблон запроса (можете вставить в макет или использовать прямо в процедуре):

<ЗапросСведенийОПлатежах ТипЗапроса="2" ИдентификаторЗапроса="[ИдентификаторЗапроса]" Версия="1.2">
<Абонент>
<ЮридическоеЛицо>
<ИНН>[ИННОрганизации]</ИНН>
<ОГРН>[ОГРНОрганизации]</ОГРН>
</ЮридическоеЛицо>
</Абонент>
<Запрос Дата="[ДатаЗапроса]">
<Источник>
<ЮридическоеЛицо ПризнакРегистрацииРФ="1" КодВидаПользователя="3">
<ИНН>[ИННОрганизации]</ИНН>
<ОГРН>[ОГРНОрганизации]</ОГРН>
<ПолноеНаименование>[НаименованиеПолное]</ПолноеНаименование>
<СокращенноеНаименование>[НаименованиеСокращенное]</СокращенноеНаименование>
</ЮридическоеЛицо>
</Источник>   
<Субъект>
<ФИО>
<Фамилия>[Фамилия]</Фамилия>
<Имя>[Имя]</Имя>
[Отчество]
</ФИО>
[ПредыдущиеФИО]
<ДатаРождения>[ДатаРождения]</ДатаРождения> 
<ДокументЛичности КодДУЛ="21">
<Серия>[СерияПаспорта]</Серия>
<Номер>[НомерПаспорта]</Номер>
<ДатаВыдачи>[ДатаВыдачиПаспорта]</ДатаВыдачи> 
<Гражданство>643</Гражданство>
</ДокументЛичности>
[ПредыдущиеДУЛ]
</Субъект>
<Согласие ОбОтветственностиПредупрежден="1" СрокДействия="1" ДатаВыдачи="[ДатаНачалаСогласия]">
<Выдано>
<ЮридическоеЛицо>
<ИНН>[ИННОрганизации]</ИНН>
<ОГРН>[ОГРНОрганизации]</ОГРН>
<ПолноеНаименование>[НаименованиеПолное]</ПолноеНаименование>
</ЮридическоеЛицо>
</Выдано>
<Цель КодЦели="2"/>
</Согласие>
<Цель КодЦели="2"/>
<СуммаОбязательства Валюта="RUB">[СуммаЗайма]</СуммаОбязательства>
</Запрос>
</ЗапросСведенийОПлатежах>

 

Основная процедура, которая на входе получает заявку на займ (с примитивным набором реквизитов), также можете передавать в виде структуры набор реквизитов, на основании которых формируется тело для POST-запроса.
Для отправки данного запроса соединение необходимо шифровать пользовательским сертификатом ЦБ, который зарегистрирован в БКИ для шифрования соединения.

Я использую stunnel (cryptopro.ru/products/other/stunnel-msspi), подробнее можно узнать из других статей.

Далее на основании тела запроса генерируется отсоединенная подпись средствами 1С, и присоединяется к основному запросу.


Функция ПолучитьДанныеПодсистемы_RUTDF_ССП(ЗаявкаНаЗайм, ТекстОтвета) Экспорт
	
	ИдентификаторЗапроса = Новый УникальныйИдентификатор;
	
	РеквизитыЗаявки = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ЗаявкаНаЗайм, "Контрагент, Дата, Организация, Организация.ИНН, Организация.ОГРН, Организация.НаименованиеПолное, 
	|Организация.НаименованиеСокращенное, ЗаявленоСумма, УтвержденоСумма");
	
	ДанныеКонтрагента = ОбщегоНазначенияМФС.СведенияОЮрФизЛице(РеквизитыЗаявки.Контрагент, РеквизитыЗаявки.Дата);
	ДанныеПаспортаКонтрагента = ОбщегоНазначенияМФС.ПолучитьУдостоверениеЛичностиКонтрагента(РеквизитыЗаявки.Контрагент, РеквизитыЗаявки.Дата);
	
	РеквизитыКонтрагента = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(РеквизитыЗаявки.Контрагент, "Фамилия, Имя, Отчество, ДатаРождения");
	
	ПараметрыЗапроса = Новый Структура;
	ПараметрыЗапроса.Вставить("ИдентификаторЗапроса", СокрЛП(ИдентификаторЗапроса));
	ПараметрыЗапроса.Вставить("ИННОрганизации",  РеквизитыЗаявки.ОрганизацияИНН);
	ПараметрыЗапроса.Вставить("ОГРНОрганизации", РеквизитыЗаявки.ОрганизацияОГРН);
	ПараметрыЗапроса.Вставить("ДатаЗапроса",     ТекущаяДата() - 2 * 3600); // текущая дата минус 2 часа, потому что работа по московскому времени
	ПараметрыЗапроса.Вставить("НаименованиеПолное",  ВРег(РеквизитыЗаявки.ОрганизацияНаименованиеПолное));
	ПараметрыЗапроса.Вставить("НаименованиеСокращенное",  ВРег(РеквизитыЗаявки.ОрганизацияНаименованиеСокращенное));
	
	ПараметрыЗапроса.Вставить("Фамилия", ДанныеКонтрагента.Фамилия);
	ПараметрыЗапроса.Вставить("Имя", ДанныеКонтрагента.Имя);
    Если ЗначениеЗаполнено(СокрЛП(ДанныеКонтрагента.Отчество)) Тогда
		ПараметрыЗапроса.Вставить("Отчество", "<Отчество>" + ДанныеКонтрагента.Отчество + "</Отчество>");
	Иначе
		ПараметрыЗапроса.Вставить("Отчество", "");
    КонецЕсли;
	ПараметрыЗапроса.Вставить("ДатаРождения", ДанныеКонтрагента.ДатаРождения);	
	ПараметрыЗапроса.Вставить("ПредыдущиеФИО", ПредыдущиеФИО(РеквизитыЗаявки.Контрагент, РеквизитыЗаявки.Дата));
	
	ПараметрыЗапроса.Вставить("СерияПаспорта", СтроковыеФункцииКлиентСервер.ОставитьТолькоЦифрыВСтроке(ДанныеПаспортаКонтрагента.Серия));
	ПараметрыЗапроса.Вставить("НомерПаспорта", СтроковыеФункцииКлиентСервер.ОставитьТолькоЦифрыВСтроке(ДанныеПаспортаКонтрагента.Номер));
	ПараметрыЗапроса.Вставить("ДатаВыдачиПаспорта",  ДанныеПаспортаКонтрагента.ДатаВыдачи);	
	ПараметрыЗапроса.Вставить("ПредыдущиеДУЛ", ПредыдущиеДУЛ(РеквизитыЗаявки.Контрагент, РеквизитыЗаявки.Дата)); 
	
	ПараметрыЗапроса.Вставить("ДатаНачалаСогласия", РеквизитыЗаявки.Дата - 2 * 3600);
	ПараметрыЗапроса.Вставить("СуммаЗайма", Формат(?(РеквизитыЗаявки.УтвержденоСумма <> 0, РеквизитыЗаявки.УтвержденоСумма, РеквизитыЗаявки.ЗаявленоСумма), "ЧДЦ=0; ЧРД=,; ЧГ=0"));	
	
	ПараметрыПодсистемы = ПроверкаКлиентов.ПолучитьЗначенияПараметровСпособаПроверки(Справочники.СпособыПроверкиКлиентов.НайтиПоНаименованию("Запрос ССП"), РеквизитыЗаявки.Организация);
	
	ИдентификаторОтвета = Неопределено;
	СтатусОбработки = Неопределено;
	//1 - ответ получен сразу, гет запрос не требуется
	//2 - ответ получен, нужно получить расчет по идентификатору путем гет запроса
	//3 - получена ошибка
	
	HTTPПодключитьсяОтправитьЗапросКредитнаяИстория_RUTDF_ССП(ЗаявкаНаЗайм, ПараметрыЗапроса, ПараметрыПодсистемы, ТекстОтвета, ИдентификаторОтвета, СтатусОбработки); 
	Если СтатусОбработки = 1 Тогда
		//Запишем сразу в историю проверок
		СтруктураРезультата = ПроверкаКлиентов.ПолучитьСтруктуруЗаписиРезультатаПроверки();
		СтруктураРезультата.Вставить("СпособПроверки", Справочники.СпособыПроверкиКлиентов.НайтиПоНаименованию("Запрос ССП"));
		СтруктураРезультата.Вставить("Контрагент", РеквизитыЗаявки.Контрагент);
		СтруктураРезультата.Вставить("Заявка", ЗаявкаНаЗайм);
		СтруктураРезультата.Вставить("ПараметрыЗапроса", ПараметрыЗапроса);
		СтруктураРезультата.Вставить("ТекстОтвета", ТекстОтвета);
		СтруктураРезультата.Вставить("ПроверкаПодписиПройдена", Истина);
		
		ПроверкаКлиентов.ЗаписьИсторииПроверок(СтруктураРезультата);
	ИначеЕсли СтатусОбработки = 2 Тогда
		СтатусОбработки = Неопределено;
		ЧислоПопыток = 0;
		ТекстОтвета = "";
		//нужно отправить еще один запрос, чтобы получить конечный результат, не более 5 попыток
		Пока СтатусОбработки <> 1 Цикл
			ЧислоПопыток = ЧислоПопыток + 1;
			HTTPПодключитьсяОтправитьЗапросКредитнаяИстория_RUTDF_ССП_ПоИдентификатору(ПараметрыПодсистемы, ТекстОтвета, ИдентификаторОтвета, СтатусОбработки); 
			Если СтатусОбработки = 1 Тогда
				СтруктураРезультата = ПроверкаКлиентов.ПолучитьСтруктуруЗаписиРезультатаПроверки();
				СтруктураРезультата.Вставить("СпособПроверки", Справочники.СпособыПроверкиКлиентов.НайтиПоНаименованию("Запрос ССП"));
				СтруктураРезультата.Вставить("Контрагент", РеквизитыЗаявки.Контрагент);
				СтруктураРезультата.Вставить("Заявка", ЗаявкаНаЗайм);
				СтруктураРезультата.Вставить("ПараметрыЗапроса", ПараметрыЗапроса);
				СтруктураРезультата.Вставить("ТекстОтвета", ТекстОтвета);
				СтруктураРезультата.Вставить("ПроверкаПодписиПройдена", Истина);
				
				ПроверкаКлиентов.ЗаписьИсторииПроверок(СтруктураРезультата);
				Прервать;
			ИначеЕсли СтатусОбработки = 2 Тогда
				Пауза(1);
			ИначеЕсли СтатусОбработки = 3 Тогда
				ТекстОтвета = "";
				Прервать;
			КонецЕсли;
			Если ЧислоПопыток = 5 Тогда
				Прервать;
			КонецЕсли;	
		КонецЦикла;
	КонецЕсли;	
	
	Результат = ПроверкаКлиентов.ПолучитьРезультатПроверки();
	
	Возврат Результат;
	
КонецФункции

Функция ПредыдущиеФИО(Контрагент, ДатаСреза) Экспорт	
	
	ПредыдущиеФИО = Новый Массив;
	
	ЗапросФИО = Новый Запрос;
	ЗапросФИО.Текст = "ВЫБРАТЬ
	|	ФИОКонтрагентов.Период КАК Период,
	|	ФИОКонтрагентов.Фамилия КАК Фамилия,
	|	ФИОКонтрагентов.Имя КАК Имя,
	|	ФИОКонтрагентов.Отчество КАК Отчество,
	|	ФИОКонтрагентов.Контрагент КАК Контрагент
	|ПОМЕСТИТЬ ВТ_ФИО
	|ИЗ
	|	РегистрСведений.ФИОКонтрагентов КАК ФИОКонтрагентов
	|ГДЕ
	|	ФИОКонтрагентов.Контрагент = &Контрагент
	|	И ФИОКонтрагентов.Период <= &ДатаСреза
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	МАКСИМУМ(ВТ_ФИО.Период) КАК Период,
	|	ВТ_ФИО.Контрагент КАК Контрагент
	|ПОМЕСТИТЬ ВТ_АктуальныеФИО
	|ИЗ
	|	ВТ_ФИО КАК ВТ_ФИО
	|
	|СГРУППИРОВАТЬ ПО
	|	ВТ_ФИО.Контрагент
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ВТ_ФИО.Период КАК Период,
	|	ВТ_ФИО.Фамилия КАК Фамилия,
	|	ВТ_ФИО.Имя КАК Имя,
	|	ВТ_ФИО.Отчество КАК Отчество
	|ИЗ
	|	ВТ_ФИО КАК ВТ_ФИО
	|ГДЕ
	|	НЕ ВТ_ФИО.Период В
	|				(ВЫБРАТЬ
	|					ВТ_АктуальныеФИО.Период
	|				ИЗ
	|					ВТ_АктуальныеФИО КАК ВТ_АктуальныеФИО)
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВТ_ФИО.Период";
	
	ЗапросФИО.УстановитьПараметр("Контрагент", Контрагент);
	ЗапросФИО.УстановитьПараметр("ДатаСреза",  ДатаСреза);
	
	РезультатФИО = ЗапросФИО.Выполнить();
	ВыборкаФИО = РезультатФИО.Выбрать();
	Пока ВыборкаФИО.Следующий() Цикл
		
		СтруктураДокумент = Новый Структура();				
		СтруктураДокумент.Вставить("Фамилия",  СокрЛП(ВыборкаФИО.Фамилия));
		СтруктураДокумент.Вставить("Имя",      СокрЛП(ВыборкаФИО.Имя));
		СтруктураДокумент.Вставить("Отчество", СокрЛП(ВыборкаФИО.Отчество));
		
		ПредыдущиеФИО.Добавить(СтруктураДокумент);				
	КонецЦикла;
	Возврат ?(ПредыдущиеФИО.Количество() = 0, "", ПредыдущиеФИО);			
	
КонецФункции

Функция ПредыдущиеДУЛ(Контрагент, ДатаСреза) Экспорт
	
	ПредыдущиеДУЛ = Новый Массив;
	
	ЗапросДУЛ = Новый Запрос;
	ЗапросДУЛ.Текст = "ВЫБРАТЬ
	|	ДокументыКонтрагентов.Контрагент КАК Контрагент,
	|	ДокументыКонтрагентов.Период КАК Период,
	|	ДокументыКонтрагентов.Серия КАК Серия,
	|	ДокументыКонтрагентов.Номер КАК Номер,
	|	ДокументыКонтрагентов.ДатаВыдачи КАК ДатаВыдачи,
	|	ДокументыКонтрагентов.КемВыдан КАК КемВыдан,
	|	ДокументыКонтрагентов.КодПодразделения КАК КодПодразделения
	|ПОМЕСТИТЬ ВТ_ДУЛ
	|ИЗ
	|	РегистрСведений.ДокументыКонтрагентов КАК ДокументыКонтрагентов
	|ГДЕ
	|	ДокументыКонтрагентов.ЯвляетсяДокументомУдостоверяющимЛичность
	|	И ДокументыКонтрагентов.Контрагент = &Контрагент
	|	И ДокументыКонтрагентов.Период <= &ДатаСреза
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ВТ_ДУЛ.Контрагент КАК Контрагент,
	|	МАКСИМУМ(ВТ_ДУЛ.Период) КАК Период
	|ПОМЕСТИТЬ ВТ_АктуальныйДУЛ
	|ИЗ
	|	ВТ_ДУЛ КАК ВТ_ДУЛ
	|
	|СГРУППИРОВАТЬ ПО
	|	ВТ_ДУЛ.Контрагент
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ВТ_ДУЛ.Контрагент КАК Контрагент,
	|	ВТ_ДУЛ.Период КАК Период,
	|	ВТ_ДУЛ.Серия КАК Серия,
	|	ВТ_ДУЛ.Номер КАК Номер,
	|	ВТ_ДУЛ.ДатаВыдачи КАК ДатаВыдачи,
	|	ВТ_ДУЛ.КемВыдан КАК КемВыдан,
	|	ВТ_ДУЛ.КодПодразделения КАК КодПодразделения
	|ИЗ
	|	ВТ_ДУЛ КАК ВТ_ДУЛ
	|ГДЕ
	|	НЕ ВТ_ДУЛ.Период В
	|				(ВЫБРАТЬ
	|					ВТ_АктуальныйДУЛ.Период
	|				ИЗ
	|					ВТ_АктуальныйДУЛ КАК ВТ_АктуальныйДУЛ)
	|
	|УПОРЯДОЧИТЬ ПО
	|	Период";
	
	ЗапросДУЛ.УстановитьПараметр("Контрагент", Контрагент);
	ЗапросДУЛ.УстановитьПараметр("ДатаСреза",  ДатаСреза);
	
	РезультатДУЛ = ЗапросДУЛ.Выполнить();
	ВыборкаДУЛ = РезультатДУЛ.Выбрать();
	Пока ВыборкаДУЛ.Следующий() Цикл
		
		СтруктураДокумент = Новый Структура();
		
		СтруктураДокумент.Вставить("НомерДокумента", СокрЛП(ВыборкаДУЛ.Номер));
		СтруктураДокумент.Вставить("СерияДокумента", СокрЛП(ВыборкаДУЛ.Серия));
		СтруктураДокумент.Вставить("КемВыданДокумент", СокрЛП(ВыборкаДУЛ.КемВыдан));
		СтруктураДокумент.Вставить("КодПодразделения", СокрЛП(ВыборкаДУЛ.КодПодразделения));
		СтруктураДокумент.Вставить("ДатаВыдачиДокумента", ВыборкаДУЛ.ДатаВыдачи);
		
		ПредыдущиеДУЛ.Добавить(СтруктураДокумент);
		
	КонецЦикла;
	Возврат ?(ПредыдущиеДУЛ.Количество() = 0, "", ПредыдущиеДУЛ);
	
КонецФункции

Процедура HTTPПодключитьсяОтправитьЗапросКредитнаяИстория_RUTDF_ССП(ПараметрыЗапроса, ПараметрыПодсистемы, ТекстОтвета, ИдентификаторОтвета, СтатусОбработки)
	
	ИмяПользователя = СокрЛП(ПараметрыПодсистемы.ИмяПользователя);
	Пароль = СокрЛП(ПараметрыПодсистемы.Пароль);
	URL = СокрЛП(ПараметрыПодсистемы.АдресПодключения) + "/dlrequest";
	
	URL = СтрЗаменить(URL, "https://", "");
	
	ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
	
	ПервыйСлеш = СтрНайти(URL, "/");
	Хост = Лев(URL, ПервыйСлеш - 1);
	АдресРесурса = Сред(URL, ПервыйСлеш);
	
	Если ПараметрыПодсистемы.Свойство("Таймаут") Тогда
		Таймаут = ПараметрыПодсистемы.Таймаут;
	Иначе
		Таймаут = 3;
	КонецЕсли;	
	
	Если ПараметрыПодсистемы.Свойство("Прокси_Сервер") Тогда
		Прокси = Новый ИнтернетПрокси;
		Прокси.Установить("https", ПараметрыПодсистемы.Прокси_Сервер, ПараметрыПодсистемы.Прокси_Порт, ПараметрыПодсистемы.Прокси_Пользователь, ПараметрыПодсистемы.Прокси_Пароль);
		СоединениеHTTP = Новый HTTPСоединение(Хост, Неопределено, ИмяПользователя, Пароль, Прокси, Таймаут, ЗащищенноеСоединение);
	Иначе
		СоединениеHTTP = Новый HTTPСоединение(Хост, Неопределено, ИмяПользователя, Пароль, Неопределено, Таймаут);
	КонецЕсли;	
	
	ContentType = "";
	Если ПараметрыПодсистемы.Свойство("ContentType") Тогда
		ContentType = ПараметрыПодсистемы.ContentType;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(ContentType) Тогда
		ContentType = "application/octet-stream";
	КонецЕсли;
	
	КодировкаТекстаЗапроса = "";
	Если ПараметрыПодсистемы.Свойство("КодировкаТекстаЗапроса") Тогда
		КодировкаТекстаЗапроса = ПараметрыПодсистемы.КодировкаТекстаЗапроса;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(КодировкаТекстаЗапроса) Тогда
		КодировкаТекстаЗапроса = "UTF-8";
	КонецЕсли; 
	
	Заголовки = Новый Соответствие;
	Заголовки.Вставить("Content-Type", ContentType);
	Заголовки.Вставить("User-Agent", "HTTPTool/1.0"); 
	
	ЗапросHTTP = Новый HTTPЗапрос(АдресРесурса, Заголовки); 
	
	ТекстЗапроса = ПолучитьТекстЗапросаКредитнаяИстория_RUTDF_ССП(ПараметрыЗапроса, ПараметрыПодсистемы);
	ТекстЗапроса = "<?xml version=""1.0"" encoding=""" + КодировкаТекстаЗапроса + """?>" + Символы.ПС + ТекстЗапроса;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.ПС, "");
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.Таб, "");
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, Символы.НПП, "");
	
	ТекстОбработанный = ЗаменитьНедопустимыеСимволыXML(ТекстЗапроса);
	
	МенеджерыКриптографии = Новый Массив;	
	Крипто = Новый МенеджерКриптографии("Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", "", 80);
	МенеджерыКриптографии.Добавить(Крипто);
	
	ХранилищеСертификатов = МенеджерыКриптографии[0].ПолучитьХранилищеСертификатов(, РасположениеХранилищаСертификатовКриптографии.ДанныеКомпьютера); 
	
	ОтпечатокСертификатаПодписи = НРег(СтрЗаменить(ПараметрыПодсистемы.СертификатПодписи, " ", ""));
	
	СертификатыХранилища = ХранилищеСертификатов.ПолучитьВсе();
	
	Для каждого Сертификат Из СертификатыХранилища Цикл
		Если НРег(СтрЗаменить(Строка(Сертификат.Отпечаток), " ", "")) = ОтпечатокСертификатаПодписи Тогда
			СертификатПодписи = Сертификат;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	
	ДвоичныеДанныеДляПодписания = ПолучитьДвоичныеДанныеИзСтроки(ТекстЗапроса, КодировкаТекстаЗапроса);
	
	Для каждого Крипто Из МенеджерыКриптографии Цикл
		Крипто.ПарольДоступаКЗакрытомуКлючу = ПараметрыПодсистемы.СертификатПодписиПароль;
		ОтсоединеннаяПодпись = Крипто.Подписать(ДвоичныеДанныеДляПодписания, СертификатПодписи);
		Прервать;
	КонецЦикла;

	Отказ = Ложь;
	ОписаниеОшибки = "";
	ПрисоединеннаяПодпись = Присоединить(ОтсоединеннаяПодпись,ДвоичныеДанныеДляПодписания,Отказ,ОписаниеОшибки);

	ЗапросHTTP.УстановитьТелоИзДвоичныхДанных(ПрисоединеннаяПодпись);

	ПроверкаПодписиПройдена = Ложь;
	Попытка		
		ФайлОтчета = ПолучитьИмяВременногоФайла(".xml");
		ФайлЗашифрованный = ФайлОтчета + ".p7s";
		ОтветHTTP = СоединениеHTTP.ОтправитьДляОбработки(ЗапросHTTP, ФайлЗашифрованный);			
		КодВозврата = Неопределено;
		ПутьКCryptcp = Константы.ПутьДоCryptcp.Получить();
		ПутьКCryptcp = СтрЗаменить(ПутьКCryptcp, "cryptcp.exe", "csptest.exe");
		СтрокаВызова = """" + ПутьКCryptcp + """ -sfsign -verify -in """ + ФайлЗашифрованный + """ -out """ + ФайлОтчета + """";  	
		ЗапуститьПриложение(СтрокаВызова, , Истина, КодВозврата);			
		Если КодВозврата = Неопределено Или КодВозврата > 0 Тогда
			ТекстОтвета = НСтр("ru = '%1. Не удалось проверить подпись ответа. Код ошибки: %2.'");
			ТекстОтвета = СтрШаблон(ТекстОтвета, "Запрос ССП из НБКИ в режиме одного окна", КодВозврата);
			СтатусОбработки = 3;
		Иначе
			ТекстДок = Новый ТекстовыйДокумент;
			ТекстДок.Прочитать(ФайлОтчета, КодировкаТекстаЗапроса);
			ТекстОтвета = ТекстДок.ПолучитьТекст();
			ПроверкаПодписиПройдена = Истина;
			Если ОтветHTTP.КодСостояния = 200 Тогда //200 – результат запроса содержит сведения о среднемесячных платежах Субъекта; 
				СтатусОбработки = 1;	
			ИначеЕсли ОтветHTTP.КодСостояния = 202 Тогда //202 – результат запроса содержит квитанцию с идентификатором ответа;
				СтатусОбработки = 2;	
				ИдентификаторОтвета = Сред(ТекстОтвета, СтрНайти(ТекстОтвета, "<ИдентификаторОтвета") + 81, СтрНайти(ТекстОтвета, "</ИдентификаторОтвета") - СтрНайти(ТекстОтвета, "<ИдентификаторОтвета") - 81);
			Иначе
				СтатусОбработки = 3;
			КонецЕсли;	
		КонецЕсли;			
		УдалитьФайлы(ФайлЗашифрованный);
		УдалитьФайлы(ФайлОтчета);					
	Исключение		
		ТекстСообщения = НСтр("ru = '%1. Не удалось отправить отчет, попробуйте еще раз. %2.'");
		ТекстСообщения = СтрШаблон(ТекстСообщения, "Запрос ССП из НБКИ в режиме одного окна", ИнформацияОбОшибке().Описание); 	
		Ош = ОписаниеОшибки(); 
		СтатусОбработки = 3;
		ТекстОтвета = ТекстСообщения;
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Ош);
	КонецПопытки;
	
КонецПроцедуры


Функция ПолучитьТекстЗапросаКредитнаяИстория_ССП(ПараметрыЗапросов, ПараметрыПодсистемы)
	
	Перем Макет, ШаблонЗапроса;
	
	Макет = Обработки.ПроверкаКлиента.ПолучитьМакет("Шаблон_НБКИ_ЗапросСведенийОПлатежах");
	ШаблонЗапроса = Макет.ПолучитьТекст(); 	
	ТекстЗапроса = ШаблонЗапроса;
	
	Для каждого Параметр Из ПараметрыЗапросов Цикл
		
		ЗначениеПараметра = Параметр.Значение;
		
		Если Параметр.Ключ = "ПредыдущиеДУЛ" Тогда
			Если ЗначениеЗаполнено(ЗначениеПараметра) Тогда
				БлокДУЛШаблон = "<ДокументЛичности КодДУЛ=""21"">" +
				"<Серия>[СерияПаспорта]</Серия>" + 
				"<Номер>[НомерПаспорта]</Номер>" +
				"<ДатаВыдачи>[ДатаВыдачиПаспорта]</ДатаВыдачи>" +
				"<Гражданство>643</Гражданство>" + 
				"</ДокументЛичности>";
				БлокПредыдущихДУЛ = "";
				Для Каждого ДУЛ Из ЗначениеПараметра Цикл
					БлокДУЛ = БлокДУЛШаблон;
					БлокДУЛ = СтрЗаменить(БлокДУЛ, "[НомерПаспорта]", ДУЛ.НомерДокумента);
					БлокДУЛ = СтрЗаменить(БлокДУЛ, "[СерияПаспорта]", СтрЗаменить(ДУЛ.СерияДокумента, " ", ""));
					БлокДУЛ = СтрЗаменить(БлокДУЛ, "[ДатаВыдачиПаспорта]", Формат(ДУЛ.ДатаВыдачиДокумента, "ДФ=yyyy-MM-dd"));
					БлокПредыдущихДУЛ = БлокПредыдущихДУЛ + БлокДУЛ;
				КонецЦикла; 
				ЗначениеПараметра = БлокПредыдущихДУЛ;
			Иначе
				ЗначениеПараметра = "";
			КонецЕсли;
		КонецЕсли;
		
		Если Параметр.Ключ = "ПредыдущиеФИО" Тогда
			Если ЗначениеЗаполнено(ЗначениеПараметра) Тогда
				БлокФИОШаблон = "<ФИО>" +
				"<Фамилия>[Фамилия]</Фамилия>" + 
				"<Имя>[Имя]</Имя>" + 
				"[Отчество]" +
				"</ФИО>";
				БлокПредыдущихФИО = "";
				Для Каждого ФИО Из ЗначениеПараметра Цикл
					БлокФИО = БлокФИОШаблон;
					БлокФИО = СтрЗаменить(БлокФИО, "[Фамилия]",  ФИО.Фамилия);
					БлокФИО = СтрЗаменить(БлокФИО, "[Имя]",      ФИО.Имя);
					Если ЗначениеЗаполнено(СокрЛП(ФИО.Отчество)) Тогда
						БлокФИО = СтрЗаменить(БлокФИО, "[Отчество]", "<Отчество>" + ФИО.Отчество + "</Отчество>");
					Иначе
						БлокФИО = СтрЗаменить(БлокФИО, "[Отчество]", "");
					КонецЕсли;
					БлокПредыдущихФИО = БлокПредыдущихФИО + БлокФИО;
				КонецЦикла; 
				ЗначениеПараметра = БлокПредыдущихФИО;
			Иначе
				ЗначениеПараметра = "";	
			КонецЕсли;
		КонецЕсли;
		
		Если ТипЗнч(ЗначениеПараметра) = Тип("Дата") Тогда
			ЗначениеПараметра = Формат(ЗначениеПараметра, "ДФ=yyyy-MM-dd");
		КонецЕсли;
		
		ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[" + Параметр.Ключ + "]", ЗначениеПараметра);	
		
	КонецЦикла;	
	
	Возврат ТекстЗапроса;
	
КонецФункции

 

Данная процедура вернет результат обработки, подписанный сертификатом. Необходимо снять эту подпись, чтобы затем сохранить результат в файл.

Применяется бесплатная утилита csptest.exe, входящая в комплект установки Крипто Про.

На первом этапе будет либо сразу получен результат, либо вернется идентификатор запроса, по которому GET-запросом необходимо получить конечный результат:

Процедура HTTPПодключитьсяОтправитьЗапросКредитнаяИстория_ССП_ПоИдентификатору(ПараметрыПодсистемы, ТекстОтвета, ИдентификаторОтвета, СтатусОбработки)
	
	ИмяПользователя = СокрЛП(ПараметрыПодсистемы.ИмяПользователя);
	Пароль = СокрЛП(ПараметрыПодсистемы.Пароль);
	URL = СокрЛП(ПараметрыПодсистемы.АдресПодключения) + "/dlanswer";
	
	URL = СтрЗаменить(URL, "https://", "");
	
	ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
	
	ПервыйСлеш = СтрНайти(URL, "/");
	Хост = Лев(URL, ПервыйСлеш - 1);
	АдресРесурса = Сред(URL, ПервыйСлеш);
	
	Если ПараметрыПодсистемы.Свойство("Таймаут") Тогда
		Таймаут = ПараметрыПодсистемы.Таймаут;
	Иначе
		Таймаут = 3;
	КонецЕсли;	
	
	Если ПараметрыПодсистемы.Свойство("Прокси_Сервер") Тогда
		Прокси = Новый ИнтернетПрокси;
		Прокси.Установить("https", ПараметрыПодсистемы.Прокси_Сервер, ПараметрыПодсистемы.Прокси_Порт, ПараметрыПодсистемы.Прокси_Пользователь, ПараметрыПодсистемы.Прокси_Пароль);
		СоединениеHTTP = Новый HTTPСоединение(Хост, Неопределено, ИмяПользователя, Пароль, Прокси, Таймаут, ЗащищенноеСоединение);
	Иначе
		СоединениеHTTP = Новый HTTPСоединение(Хост, Неопределено, ИмяПользователя, Пароль, Неопределено, Таймаут);
	КонецЕсли;	
	
	ContentType = "";
	Если ПараметрыПодсистемы.Свойство("ContentType") Тогда
		ContentType = ПараметрыПодсистемы.ContentType;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(ContentType) Тогда
		ContentType = "application/octet-stream";
	КонецЕсли;
	
	КодировкаТекстаЗапроса = "";
	Если ПараметрыПодсистемы.Свойство("КодировкаТекстаЗапроса") Тогда
		КодировкаТекстаЗапроса = ПараметрыПодсистемы.КодировкаТекстаЗапроса;
	КонецЕсли;
	Если Не ЗначениеЗаполнено(КодировкаТекстаЗапроса) Тогда
		КодировкаТекстаЗапроса = "UTF-8";
	КонецЕсли; 
	
	Заголовки = Новый Соответствие;	
	ЗапросHTTP = Новый HTTPЗапрос(АдресРесурса + "?id=" + ИдентификаторОтвета, Заголовки); 
	
	ПроверкаПодписиПройдена = Ложь;
	Попытка		
		ФайлОтчета = ПолучитьИмяВременногоФайла(".xml");
		ФайлЗашифрованный = ФайлОтчета + ".p7s";
		ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP, ФайлЗашифрованный);			
		КодВозврата = Неопределено;
		ПутьКCryptcp = Константы.ПутьДоCryptcp.Получить();
		ПутьКCryptcp = СтрЗаменить(ПутьКCryptcp, "cryptcp.exe", "csptest.exe");
		СтрокаВызова = """" + ПутьКCryptcp + """ -sfsign -verify -in """ + ФайлЗашифрованный + """ -out """ + ФайлОтчета + """";  	
		ЗапуститьПриложение(СтрокаВызова, , Истина, КодВозврата);			
		Если КодВозврата = Неопределено Или КодВозврата > 0 Тогда
			ТекстОтвета = НСтр("ru = '%1. Не удалось проверить подпись ответа. Код ошибки: %2.'");
			ТекстОтвета = СтрШаблон(ТекстОтвета, "Запрос ССП из НБКИ в режиме одного окна", КодВозврата);
			СтатусОбработки = 3;
		Иначе
			ТекстДок = Новый ТекстовыйДокумент;
			ТекстДок.Прочитать(ФайлОтчета, КодировкаТекстаЗапроса);
			ТекстОтвета = ТекстДок.ПолучитьТекст();
			ПроверкаПодписиПройдена = Истина;
			Если ОтветHTTP.КодСостояния = 200 Тогда //результат запроса содержит сведения о среднемесячных платежах Субъекта; 
				СтатусОбработки = 1;	
			ИначеЕсли ОтветHTTP.КодСостояния = 202 Тогда //результат запроса содержит квитанцию с информацией об ошибке «Ответ не готов»;
				СтатусОбработки = 2;	
			Иначе
				СтатусОбработки = 3;
			КонецЕсли;	
		КонецЕсли;			
		УдалитьФайлы(ФайлЗашифрованный);
		УдалитьФайлы(ФайлОтчета);					
	Исключение		
		ТекстСообщения = НСтр("ru = '%1. Не удалось отправить отчет, попробуйте еще раз. %2.'");
		ТекстСообщения = СтрШаблон(ТекстСообщения, "Запрос ССП из НБКИ в режиме одного окна", ИнформацияОбОшибке().Описание); 	
		Ош = ОписаниеОшибки(); 
		СтатусОбработки = 3;
		ТекстОтвета = ТекстСообщения;
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
		ОбщегоНазначенияКлиентСервер.СообщитьПользователю(Ош);
	КонецПопытки;
	
КонецПроцедуры


Конечный результат получаете в формате XML, который содержит данные о всех среднемесячных платежах контрагента во всех БКИ. Структура его довольно простая, по ссылке на API ЦБ есть примеры с текстом запроса и ответа.

Свои вопросы можете писать в комментариях к этой статье, надеюсь, она поможет вам сэкономить время. Ведь НБКИ в скором времени перестанет предоставлять даже кредитные отчеты своим клиентам, если не шифровать соединение сертификатом при запросе и не пользоваться двусторонней аутентификацией (то есть, требуют подписывать текст запроса и снимать подпись с ответа, проверяя подпись).

ЦБ ССП ПДН Показатель долговой нагрузки 6579-У сумма среднемесячных платежей Банк России СМП НБКИ Национальное бюро кредитных историй КБКИ БКИ Одно окно

См. также

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс 24. Разработка имеет двухстороннюю синхронизацию 1С и Bitrix24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (платформа начиная с 8.3.23). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    18777    10    15    

16

Сайты и интернет-магазины WEB-интеграция Системный администратор Программист Пользователь Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    16559    15    19    

15

WEB-интеграция 8.3.8 Конфигурации 1cv8 Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение предназначено для конфигурации "1С:Предприятие 8. Управление Автотранспортом. ПРОФ". Функционал модуля: 1. Заполнение регистров сведений по подсистеме "Мониторинг", а именно: события по мониторингу, координаты по мониторингу, пробег и расход по мониторингу, текущее местоположение ТС по мониторингу 2. Заполнение путевого листа: пробег по мониторингу, время выезда/заезда, табличная часть ГСМ, места стоянок по геозонам. 3. Отчеты по данным загруженным в регистры сведений. 4. Предусмотрена автоматическая загрузка данных в фоновом режиме (условия работы данной загрузке читайте в описании товара) Модуль работает без включенной константы по настройкам мониторинга. Модуль формы предоставляется с открытым кодом, общий модуль защищен. Любой заинтересованный пользователь, имеет возможность скачать демо-версию расширения.

22656 руб.

25.05.2021    13248    35    8    

14

Прайсы WEB-интеграция Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Системный администратор Программист Автомобили, автосервисы Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Программа с заданным интервалом времени (или по ручной команде) скачивает файлы (например, прайс-листы поставщиков) из различных источников: письма электронной почты, FTP или HTTP-адреса, и сохраняет их в каталог упорядоченной структуры. При этом извлекает файлы из архивов, может переименовывать файлы и менять их формат (csv, xls, txt). Можно настроить выгрузку обработанных файлов на сайт (через FTP-подключение). Программа будет полезна компаниям, у которых есть большое количество поставщиков и/или прайс-листы поставщиков обновляются часто (необязательно прайс-листы, файлы могут быть любого назначения). Собранные таким образом актуальные версии прайс-листов можно выгрузить с помощью программы себе на сайт (или на любой FTP-сервер) или выполнить другие необходимые задачи.

25200 руб.

28.05.2015    86748    26    51    

50
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Snoppp 31.05.24 09:07 Сейчас в теме
Спасибо вам за статью и приложенное решение! Как раз сейчас работаю над такой задачей.
Подскажите пожалуйста, не сталкивались ли вы со следующим моментом:

Я пытаюсь настроить stunnel для подключение к reports.nbki.ru. но при попытке подключения на этапе handshake возникает обрыв соединения.


Лог Stunnel:
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 2636 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 7300 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 1460 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG5[19296:45532]: 349 bytes of handshake(in handshake loop) data received.
2024.05.31 12:59:53 LOG3[19296:45532]: **** Server unexpectedly disconnected
2024.05.31 12:59:53 LOG3[19296:45532]: Error performing handshake
2. itserve 37 04.06.24 11:02 Сейчас в теме
(1) Добрый день, есть некоторые тонкости.
Стуннел должен быть скачан с сайта крипто про, скачанный с другого источника не запускался:
cryptopro.ru/products/other/stunnel-msspi
А вообще - все ошибки гуглились, на cryptopro.ru/forum2/
3. Snoppp 04.06.24 12:13 Сейчас в теме
Спасибо за ответ. Да, stunnel скачан с сайта крипто про. Похожую проблему находил на форуме, но она без ответа.

Вы используете в работе именно stunnel - msspi, по ссылке которую вы приложили, или stunnel https://cryptopro.ru/products/other/stunnel?
5. itserve 37 04.06.24 12:47 Сейчас в теме
4. itserve 37 04.06.24 12:46 Сейчас в теме
stunnel - msspi
Прикрепленные файлы:
6. Snoppp 04.06.24 12:53 Сейчас в теме
Да, действительно, получилось, спасибо за помощь! После того, как установил stunnel - msspi авторизация reports.nbki.ru прошла успешно
7. pavlo 19.06.24 14:29 Сейчас в теме
Здравствуйте ,
Так и не понял, а без stunnel из 1с не реально сделать запрос в нбки?
8. itserve 37 19.06.24 21:48 Сейчас в теме
(7)Добрый вечер, вариантов на самом деле несколько, в данной статье представлен самый простой и бесплатный - через стуннел. 1С даже на самом последнем релизе платформы не может шифровать исходящее соединение при отправке запроса.
Как вариант - можно набросать простенькую dll, которая получала бы на входе заданные параметры и возвращала результат итоговый.
10. pavlo 20.06.24 06:35 Сейчас в теме
(8)
А как настроить этот тунель?
11. itserve 37 20.06.24 07:09 Сейчас в теме
(10) Порядок действий:
1) Скачиваете cryptopro.ru/products/other/stunnel-msspi и устанавливаете на сервере, где сервер 1С крутится
2) На этом же сервере устанавливаете сертификат от ЦБ (или от аналогичного органа, выданный на Вашу организацию), регистрируете его в личном кабинете НБКИ, что именно им будете шифровать соединение и подписывать запросы (во вложении скрин из лк НБКИ, где указано что этот сертификат используется для Подпись запросов и Запросы ССП от КБКИ, это можно сделать через техпод НБКИ по sd@nbki.ru)
3) В файле stunnel.conf прописываете настройки, как на скрине ниже, где
192.168.0.47:1606 - внутренний ай-пи вашего сервера, где крутится 1С, 1606 - любой свободный порт, чтобы привязать сертификат и исходящие запросы по конкретному порту.
connect = reports.nbki.ru:443
client = yes
verify = 2 - тут ничего не меняете,
cert = D:\NBKI\cert_cb.cer - путь к сертификату в каталоге.
Теперь при исходящем запросе через порт 1606 трафик будет шифроваться указанным сертификатом из каталога.
4) В 1С, соответственно, адрес, куда слать запросы, указываете не https://reports.nbki.ru/qbch/, а 192.168.0.47:1606/qbch - в тексте статьи это АдресПодключения.
Прикрепленные файлы:
15. pavlo 20.06.24 10:28 Сейчас в теме
(11)
Спасибо буду пробовать, а winhttp не пробовали использовать?
16. itserve 37 20.06.24 11:08 Сейчас в теме
(15)Нет, а какой метод winhttp подойдет?
17. pavlo 20.06.24 11:31 Сейчас в теме
(16)
Я не говорил что подойдет, просто пробую но пока сложно сертификат передать

WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");// winhttp.winhttprequest.5.1
WinHttp.SetClientCertificate("LOCAL_MACHINE\Personal\My");

//WinHttp.Option(2,"utf-8");
//WinHttp.Option(2,"Windows-1251");
//WinHttp.Option(4,"13056");
//WinHttp.Option(6, Истина);
//WinHttp.Option(12,Истина);

//************************** Начало блока по отключению защищенного соединения **********
Скрипт= Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.language="javascript";
Скрипт.AddObject("WinHttp", WinHttp);
Скрипт.Eval("WinHttp.Option(2)=65001"); // установка кодировки страницы
Скрипт.Eval("WinHttp.Option(4)=13056");//intSslErrorIgnoreFlags Игноировать ошбибки при SSL соединении
Скрипт.Eval("WinHttp.Option(6)=true");//blnEnableRedirects Разрешить перенаправления
Скрипт.Eval("WinHttp.Option(12)=true");//blnEnableHttpsToHttpRedirects Разрешить перенаправления с защищенного на не защиещенное соединение
//Скрипт.Eval("WinHttp.Option(9)=0");//blnEnableHttpsToHttpRedirects Разрешить перенаправления с защищенного на не защиещенное соединение
//************************** Конец блока по отключению защищенного соединения **********

WinHttp.Open("POST", "https://reports.demo.nbki.ru/qbch/dlrequest", Ложь);


//Агент="Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
WinHttp.SetRequestHeader("Accept-Language", "ru");
WinHttp.SetRequestHeader("Accept-Charset", "Windows-1251");
WinHttp.setRequestHeader("Content-Language", "ru");
WinHttp.setRequestHeader("Content-Charset", "Windows-1251");
WinHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=Windows-1251");
WinHttp.SetRequestHeader("Accept-Encoding","text");
//WinHttp.setRequestHeader("User-Agent", Агент);

WinHttp.Send("");
Ответ = WinHttp.ResponseText();
Показать


Но пишет так
Для проверки подлинности клиента требуется сертификат, хотя ЦБ сертификат указан из реестра
Прикрепленные файлы:
20. itserve 37 20.06.24 11:55 Сейчас в теме
(17)В этом-то и сложность. судя по синтаксис-помощнику - передать пользовательский серт можно при ссл соединении, но это работает только на клиенте, а не на сервере, и только при выборе сертификата из диалогового окна.
21. pavlo 20.06.24 12:48 Сейчас в теме
(20)
вроде читал и его и скачал, сейчас снова поставил норм
НО ошибку выдает запрос 1С
делаю так

имяФайла = "C:\tmp\1\1.xml.sig";
ДвоичныеДанные = Новый ДвоичныеДанные(имяФайла);
ДвоичныеДанные.Записать(имяФайла);

Соединение = Новый HTTPСоединение("localhost:4444", 443,,,,,ЗащищенноеСоединение, Ложь);

Запрос = Новый HTTPЗапрос("qbch/dlrequest");
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанные);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);


В итоге уже пишет "Ошибка работы с Интернет: URL using bad/illegal format or missing URL"

А если
Соединение = Новый HTTPСоединение("localhost", 4444,,,,,ЗащищенноеСоединение, Ложь);
то возвращает
Ошибка работы с Интернет: Couldn't resolve host name
22. itserve 37 20.06.24 12:54 Сейчас в теме
(21)
URL using bad/illegal format or missing URL

тут только по отладке смотреть, и в журнале стуннел
24. pavlo 20.06.24 17:31 Сейчас в теме
(22)
да особо не вижу ничего, сейчас конфиг такое

[nbki_demo]
accept = 192.168.150.10:20000
connect = reports.demo.nbki.ru:443
client = yes
verify = 2
cert = C:\Stunnel\cert.cer
pincode = ******

пинкод само собой пароль
localhost поменяли и в коде и в конфиге на 192.168.150.10, теперь выдает Ошибка работы с Интернет: Failure when receiving data from the peer
Блин, жесть какая то с этим НБКИ :(
25. pavlo 20.06.24 17:41 Сейчас в теме
(22)
[ ] Initializing inetd mode configuration
[ ] Running on Windows 6.2
[ ] No limit detected for the number of clients
[.] stunnel 5.71 on x86-pc-msvc-1929 platform
[.] Compiled without OPENSSL
[.] Threading:WIN32 Sockets:SELECT,IPv6 TLS:OCSP,SNI
[ ] errno: (*_errno())
[ ] Initializing inetd mode configuration
[ ] Running on Windows 6.2
[.] Reading configuration from file C:\Stunnel\stunnel.conf
[.] UTF-8 byte order mark not detected
[ ] Initializing service [nbki_demo]
[.] Configuration successful
[ ] Deallocating deployed section defaults
[ ] Binding service [nbki_demo]
[ ] Listening file descriptor created (FD=892)
[ ] Setting accept socket options (FD=892)
[ ] Option SO_EXCLUSIVEADDRUSE set on accept socket
[.] Binding service [nbki_demo] to 192.168.150.10:20000: Can't assign requested address (WSAEADDRNOTAVAIL) (10049)
[!] Binding service [nbki_demo] failed
[ ] Unbinding service [nbki_demo]
[ ] Service [nbki_demo] closed
[ ] Deallocating deployed section defaults
[ ] Deallocating section [nbki_demo]
[ ] Initializing inetd mode configuration
[ ] Running on Windows 6.2

Server is down
27. itserve 37 20.06.24 17:49 Сейчас в теме
(24)
(25)
Тут только подключаться и смотреть.
В статье представлен полностью работоспособный код, получаем ССП уже месяц, заранее перешли на новую систему.
С 01.08.2024 все кредитные отчёты от НБКИ можно будет получать только через шифрование соединения и с двусторонней аутентификацией.
Если не получится решить проблему - могу оказать посильную помощь, за 4 000 в час.
29. pavlo 20.06.24 18:21 Сейчас в теме
(27)
я так понял с 01.07.2024
нам главное чтобы он ответил, остальное вроде как подписать и т.п. сможем и так, но не можем понять почему вот такое и не поднимается
Пробовали 24 платформу она тоже штатно не умеет
30. пользователь 20.06.24 18:25
Сообщение было скрыто модератором.
...
28. Snoppp 20.06.24 18:11 Сейчас в теме
(25)Тоже на днях мучался с подключением. Перепробовал много вариантов. Вроде получилось, были такие же ошибки. У вас сам сертификат ЭЦП установлен в папку личное у пользователя? И попробуйте службу stunnel запустите от пользователя у которого этот сертификат установлен
31. pavlo 20.06.24 18:27 Сейчас в теме
(28)
сертификат же файлом лежит в папке stunnel, разве нет?
32. itserve 37 20.06.24 18:33 Сейчас в теме
(29)
(31)помимо файла его обязательно нужно установить на сервере 1С, в папку личное, я устанавливал не в папку пользователя, а в общую папку компьютера
33. pavlo 20.06.24 18:39 Сейчас в теме
(32)
Локальный компьютер - Личное?
35. itserve 37 20.06.24 18:46 Сейчас в теме
(33)да, сертификат установлен здесь. Далее в коде процедуры ищу его по отпечатку и через менеджер криптографии подписываю запрос и снимаю подпись с ответа.
Стуннел шифрует само соединение - трафик.
37. pavlo 20.06.24 18:57 Сейчас в теме
(35)
главная тема в том, что пока ничего не подписываем, просто хотим получить ответ хоть какой то от нбки
берем подпись в двоичные данные и отправляем туда как тело, но ладно бы нбки послал нас, но туда даже не доходит, особенно через тунель

с тунелем поддержка говорит и не приходило запросов,
а без тунеля поддержка нбки пишет что приходит такое

но это без тунеля и тут вроде с виду понятно что не уходит сертификат


Добрый день.

Указанный сертификат прописан на тестовом контуре.
Вот такие записи видим в логе при попытке установить соединение:
[Wed Jun 19 15:05:24.313766 2024] [ssl:info] [pid 15865:tid 140545972164352] [client 185.171.100.252:54167] AH02008: SSL library error 1 in handshake (server reports.demo.nbki.ru:443)
[Wed Jun 19 15:05:24.313785 2024] [ssl:info] [pid 15865:tid 140545972164352] [client -] SSL Library Error: error:140890C7:SSL routines:ssl3_get_client_certificate:peer did not return a certificate -- No CAs k
nown to server for verification?
[Wed Jun 19 15:05:24.313806 2024] [ssl:info] [pid 15865:tid 140545972164352] [client 185.171.100.252:54167] AH01998: Connection closed to child 470 with abortive shutdown (server reports.demo.nbki.ru:443)

Обычно это указывает на проблему с корневыми сертификатам.
Попробуйте прописать корневые и промежуточные сертификаты УЦ ЦБ РФ и Минцифры в хранилище, которое использует Ваше ПО.
Показать
38. itserve 37 20.06.24 19:01 Сейчас в теме
(37)да, ещё нужно установить корневой сертификат удостоверяющего центра.
34. пользователь 20.06.24 18:45
Сообщение было скрыто модератором.
...
36. пользователь 20.06.24 18:49
Сообщение было скрыто модератором.
...
39. пользователь 20.06.24 19:03
Сообщение было скрыто модератором.
...
40. пользователь 20.06.24 19:12
Сообщение было скрыто модератором.
...
41. пользователь 20.06.24 19:26
Сообщение было скрыто модератором.
...
18. pavlo 20.06.24 11:32 Сейчас в теме
(11)
Что то не запускается stunnel пишет
Прикрепленные файлы:
19. itserve 37 20.06.24 11:50 Сейчас в теме
(18) скачать и установить нужно именно stunnel - msspi, по ссылке cryptopro.ru/products/other/stunnel-msspi
настройте stunnel.conf и запустите от имени админа
9. user708174_iia25 20.06.24 06:09 Сейчас в теме
Добрый день, Иван. А можно увидеть скрины данной разработки, я только начинаю кодить. опыта мало, а задача стоит найти решение.
12. itserve 37 20.06.24 08:02 Сейчас в теме
(9)Добрый день, в статье представлен полностью открытый код, встраиваете его в свою конфигурацию.
Вызываете Функция ПолучитьДанныеПодсистемы_RUTDF_ССП(ЗаявкаНаЗайм, ТекстОтвета)
где в ЗаявкаНаЗайм - структура с указанными параметрами (ФИО клиента, паспортные данные, данные организации, запрашиваемая сумма), после выполнения в ТекстОтвета запишется полученный результат ССП в формате XML.
13. user2093362 20.06.24 09:27 Сейчас в теме
(12)
Может я ошибаюсь, но по-моему нет процедуры или у меня нет в описании,
Присоединить(ОтсоединеннаяПодпись,ДвоичныеДанныеДляПодписания,Отказ,ОписаниеОшибки);
14. itserve 37 20.06.24 10:01 Сейчас в теме
(13)Можно использовать эту публикацию - https://infostart.ru/1c/tools/1493281/
26. itserve 37 20.06.24 17:44 Сейчас в теме
(23) не могу выложить код этой процедуры, так как ее написал не я.
Оставьте свое сообщение