В современной практике автоматизации ритейла часто возникает задача получения данных напрямую из личного кабинета ОФД (Оператора Фискальных Данных). Это может быть необходимо для сверки выручки, автоматического заполнения отчетов о розничных продажах или контроля работы кассиров. В данной статье мы подробно разберем, как реализовать механизм взаимодействия 1С с API ОФД (на примере сервиса «ОФД-Я» / Ярус) с использованием объектной модели HTTPСоединение.
Многие разработчики при попытке первого подключения совершают стандартную ошибку: пытаются передать API-ключ (токен) в качестве пароля в конструкторе HTTPСоединение. Рассмотрим, почему это не работает. Стандартная авторизация в 1С через параметры соединения чаще всего подразумевает Basic Authentication, в то время как большинство современных веб-сервисов (включая ОФД) используют специализированные заголовки в самом HTTP-запросе.
Проанализируем ситуацию: если при отправке запроса вы получаете ответ со статусом 500 (Internal Server Error) или ошибку десериализации (например, null cannot be cast to non-null type kotlin.Long), это часто сигнализирует о том, что сервер не получил ожидаемый параметр авторизации или тело запроса пустое там, где оно требуется.
Так как работа с финансовыми данными всегда ведется через защищенный протокол HTTPS, первым делом нам необходимо создать объект ЗащищенноеСоединениеOpenSSL. В большинстве случаев достаточно использовать стандартные системные сертификаты.
Рассмотрим код создания соединения:
// Инициализируем защищенное соединение
SSL = Новый ЗащищенноеСоединениеOpenSSL();
// Указываем адрес сервера ОФД (без протокола https://)
АдресСервераОФД = "api.ofd-ya.ru";
// Создаем HTTPСоединение
// Обратите внимание: параметры логина и пароля оставляем пустыми
Соединение = Новый HTTPСоединение(АдресСервераОФД, , , , , 30, SSL);
Важный момент: Если вы работаете на устаревших версиях Windows Server, убедитесь, что операционная система поддерживает протокол TLS 1.2, иначе соединение будет разорвано на этапе рукопожатия (Handshake).
Выясним причину, по которой обычная передача ключа не срабатывает. Согласно документации API ОФД, ключ доступа (токен) должен передаваться в специфическом заголовке. Для сервиса «ОФД-Я» этот заголовок называется Ofdapitoken. Разберем, как правильно сформировать коллекцию заголовков в 1С.
Посмотрим на пример формирования соответствия:
КлючАПИ = "ВАШ_ДЛИННЫЙ_API_КЛЮЧ_ИЗ_ЛИЧНОГО_КАБИНЕТА";
ЗаголовкиHTTP = Новый Соответствие;
ЗаголовкиHTTP.Вставить("Ofdapitoken", КлючАПИ);
// Указываем серверу, что мы передаем данные в формате JSON
ЗаголовкиHTTP.Вставить("Content-Type", "application/json");
Иногда требуется стандартная Basic-авторизация (если это предусмотрено методом API). В этом случае ключ кодируется в Base64. Разберем этот пример для общего понимания, хотя для ОФД-Я он используется реже:
// Пример формирования заголовка Authorization (если требуется Basic Auth)
СтрокаАвторизации = КлючАПИ + ":";
ДвоичныеДанныеАут = ПолучитьДвоичныеДанныеИзСтроки(СтрокаАвторизации);
Base64Строка = ПолучитьBase64СтрокуИзДвоичныхДанных(ДвоичныеДанныеАут);
ЗаголовкиHTTP.Вставить("Authorization", "Basic " + Base64Строка);
Многие методы API требуют передачи параметров (даты, номера ФН) не в строке адреса (URL), а в теле POST-запроса в формате JSON. Рассмотрим типичную ошибку bad input. Она возникает, когда сервер ожидает структуру данных, а получает пустую строку или неверный формат даты.
Проанализируем метод получения смен по кассе /ofdapi/v2/KKTShift. Для него необходимо передать номер фискального накопителя и период. Посмотрим на правильную реализацию с использованием объекта ЗаписьJSON, что гораздо надежнее ручной склейки строк.
// Путь к ресурсу
Ресурс = "/ofdapi/v2/KKTShift";
// Подготовим структуру параметров
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("fiscalDriveNumber", "9999078900001234");
ПараметрыЗапроса.Вставить("startDate", "2023-10-01"); // Строгий формат ГГГГ-ММ-ДД
ПараметрыЗапроса.Вставить("endDate", "2023-10-31");
// Преобразуем структуру в JSON-строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);
СтрокаТела = ЗаписьJSON.Закрыть();
// Формируем запрос
ЗапросHTTP = Новый HTTPЗапрос(Ресурс, ЗаголовкиHTTP);
ЗапросHTTP.УстановитьТелоИзСтроки(СтрокаТела, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
// Отправляем запрос методом POST (в 1С это ОтправитьДляОбработки)
Попытка
ОтветСервера = Соединение.ОтправитьДляОбработки(ЗапросHTTP);
Если ОтветСервера.КодСостояния = 200 Тогда
ТекстОтвета = ОтветСервера.ПолучитьТелоКакСтроку();
// Разберем результат ниже
Иначе
Сообщить("Ошибка сервера: " + ОтветСервера.КодСостояния);
КонецЕсли;
Исключение
Сообщить("Ошибка подключения: " + ИнформацияОбОшибке().Описание);
КонецПопытки;
После получения ответа в виде строки JSON, нам необходимо преобразовать его в удобный для 1С формат (Структура или Массив). Выясним, как это сделать максимально эффективно.
Рассмотрим пример десериализации:
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
// Теперь мы можем обращаться к данным через точку
Если ТипЗнч(Данные) = Тип("Структура") И Данные.Свойство("shifts") Тогда
Для Каждого ТекущаяСмена Из Данные.shifts Цикл
Сообщить("Смена № " + ТекущаяСмена.shiftNumber + " от " + ТекущаяСмена.openDateTime);
КонецЦикла;
КонецЕсли;
При работе с API ОФД следует учитывать несколько важных нюансов, которые помогут сделать вашу интеграцию стабильной:
{ } в теле запроса. Если вы получаете ошибку, попробуйте добавить ЗапросHTTP.УстановитьТелоИзСтроки("{ }");.Приостановить(1); (или аналоги в фоновых заданиях) для создания небольших пауз.testapi.ofd-ya.ru. Это позволит отладить логику без нагрузки на основной сервер.Формат(Дата, "ДФ=гггг-ММ-дд") для преобразования дат 1С в строковый формат запроса.Разбирая данные примеры, мы видим, что основная сложность заключается не в самом протоколе HTTP, а в строгом соблюдении требований API конкретного вендора к заголовкам и формату JSON-пакета. Использование объектов HTTPЗапрос и ЗаписьJSON позволяет сделать код чистым и устойчивым к ошибкам.