Как отправить POST-запрос с JSON-телом из 1С и исправить ошибку Unrecognized token

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интеграционных решений между «1С:Предприятием» и сторонними веб-сервисами (например, платежными шлюзами, CRM-системами или API служб доставки) программисты часто сталкиваются с необходимостью отправки POST-запросов с телом в формате JSON. Одной из наиболее распространенных ошибок на этапе отладки является некорректная передача параметров, из-за которой удаленный сервер возвращает ошибку синтаксического анализа (парсинга), например: com.fasterxml.jackson.core.JsonParseException: Unrecognized token.

В данной статье мы подробно разберем, почему возникает эта ошибка на примере интеграции с белорусской платежной системой Webpay, как правильно упаковать параметры в JSON штатными средствами платформы 1С, а также рассмотрим важные технические нюансы работы с API Webpay, которые не были упомянуты в обсуждении на форуме, но критически важны для успешного запуска системы в промышленную эксплуатацию.

Выясняем причину ошибки Unrecognized token

Давайте проанализируем ситуацию, описанную в исходном обращении. Разработчик пытается отправить запрос к API Webpay на адрес получения отчетов /reports/get. При этом в заголовках запроса явно указывается тип содержимого JSON:


Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");

Однако само тело запроса формируется в виде обычной строки параметров, характерной для метода GET или для POST-запросов с типом содержимого application/x-www-form-urlencoded:


СтрокаПар2 = "login=test&password=test&startDate=2020-09-01&endDate=2020-10-06&reportType=ERIP_TRANSACTION_LOG&reportFormat=JSON";

Когда удаленный веб-сервер принимает этот запрос, он считывает заголовок Content-Type: application/json и передает входящий поток данных своему внутреннему парсеру JSON (в данном случае библиотеке Jackson на базе Java). Парсер ожидает увидеть валидный JSON-документ, который должен начинаться с открывающей фигурной скобки { или квадратной скобки [, либо содержать литералы типа true, false или null.

Вместо этого парсер натыкается на первый символ «l» слова «login» и незамедлительно аварийно завершает работу, выдавая ошибку: Unrecognized token 'login': was expecting ('true', 'false' or 'null'). Сервер буквально сообщает нам: «Я не понимаю, что это за токен, так как ожидал начало JSON-объекта».

Решение проблемы: Правильное формирование JSON в 1С

Для того чтобы исправить данную ошибку, нам необходимо передать в тело HTTP-запроса текстовую строку, которая представляет собой валидную структуру JSON. Некоторые разработчики пытаются собирать JSON-строки вручную, используя конкатенацию строк и экранирование кавычек, например:

СтрокаПар2 = "{ ""login"" : ""test"", ""password"" : ""test"" }";

Рассмотрим, почему такой подход крайне нежелателен. Ручная сборка строк подвержена ошибкам: очень легко пропустить запятую, кавычку или некорректно обработать спецсимволы в строковых значениях параметров (например, переносы строк, символы табуляции или кавычки внутри самих данных). Если в параметрах передаются произвольные пользовательские данные, ручной метод сборки практически гарантированно приведет к сбоям.

Правильным и безопасным способом формирования JSON в платформе 1С является использование специализированных объектов: Структура, ЗаписьJSON и функции ЗаписатьJSON(). Разберем этот процесс по шагам на практическом примере.


// Шаг 1. Создаем структуру для хранения параметров запроса
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("login", "test");
ПараметрыЗапроса.Вставить("password", "test"); // Внимание! См. раздел об авторизации ниже
ПараметрыЗапроса.Вставить("startDate", "2020-09-01"); // Даты передаются в формате Строки (ГГГГ-ММ-ДД)
ПараметрыЗапроса.Вставить("endDate", "2020-10-06");
ПараметрыЗапроса.Вставить("reportType", "ERIP_TRANSACTION_LOG");
ПараметрыЗапроса.Вставить("reportFormat", "JSON");

// Шаг 2. Инициализируем объект ЗаписьJSON для сериализации структуры в строку
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();

// Шаг 3. Записываем структуру в формате JSON
ЗаписатьJSON(ЗаписьJSON, ПараметрыЗапроса);

// Шаг 4. Получаем готовую JSON-строку и закрываем объект записи
СтрокаПараметровJSON = ЗаписьJSON.Закрыть();

Использование этого механизма гарантирует, что платформа 1С автоматически преобразует все типы данных в соответствующие типы JSON (строки, числа, булевы значения), правильно экранирует все служебные символы и сформирует синтаксически безупречный документ.

Полный листинг отправки POST-запроса из 1С

Теперь объединим подготовку тела запроса с кодом инициализации HTTP-соединения и отправки данных. Посмотрим на итоговый рабочий вариант кода:


// Настройки подключения к серверу Webpay
СерверИсточника = "merchant.webpay.by";
ПортПодключения = 443;
РесурсЗапроса = "/reports/get";

// Включаем поддержку безопасного соединения SSL
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL;

Попытка
    Соединение = Новый HTTPСоединение(СерверИсточника, ПортПодключения, , , , , ЗащищенноеСоединение);
Исключение
    ЗаписьЖурналаРегистрации("Интеграция.Webpay", УровеньЖурналаРегистрации.Ошибка, , , 
        "Ошибка инициализации HTTP-соединения: " + ОписаниеОшибки());
    ВызватьИсключение "Не удалось установить соединение с сервером платежной системы.";
КонецПопытки;

// Формируем заголовки HTTP-запроса
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8");

// Создаем HTTP-запрос
Запрос = Новый HTTPЗапрос(РесурсЗапроса, Заголовки);

// Заполняем тело запроса подготовленной JSON-строкой
Запрос.УстановитьТелоИзСтроки(СтрокаПараметровJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Отправляем запрос методом POST
Попытка
    Ответ = Соединение.ОтправитьДляОбработки(Запрос); // Метод ОтправитьДляОбработки отправляет POST-запрос
Исключение
    ЗаписьЖурналаРегистрации("Интеграция.Webpay", УровеньЖурналаРегистрации.Ошибка, , , 
        "Ошибка при отправке запроса: " + ОписаниеОшибки());
    ВызватьИсключение "Сервер не ответил на запрос отчета.";
КонецПопытки;

// Анализируем полученный ответ
Если Ответ.КодСостояния = 200 Тогда
    // Читаем полученное тело ответа в формате JSON
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8));
    
    ДанныеОтчета = ПрочитатьJSON(ЧтениеJSON, Ложь);
    ЧтениеJSON.Закрыть();
    
    // Здесь выполняем обработку полученных данных отчета (ДанныеОтчета)
Иначе
    ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
        "Ошибка сервера Webpay. Код состояния: %1. Ответ сервера: %2",
        Ответ.КодСостояния,
        Ответ.ПолучитьТелоКакСтроку()
    );
КонецЕсли;

Важнейшие технические детали интеграции с Webpay

Решение синтаксической проблемы с JSON — это лишь первый шаг к стабильной работе интеграции. При реальном внедрении обмена с API Webpay в базах 1С вам обязательно потребуется учесть особенности работы самого платежного шлюза. Проанализируем ключевые моменты, которые часто упускаются из виду на этапе проектирования.

1. Безопасность и авторизация: Хеширование пароля (MD5)

В демонстрационных примерах разработчики часто передают пароль в открытом текстовом виде: "password" : "test". Однако реальное API Webpay в целях безопасности категорически запрещает передачу паролей в открытом виде. В поле password необходимо отправлять MD5-хеш вашего пароля от личного кабинета мерчанта.

Если вы передадите пароль обычным текстом, сервер вернет ошибку авторизации (HTTP статус 401 Unauthorized), даже если структура JSON составлена идеально верно. Чтобы вычислить MD5-хеш строки в 1С, мы можем воспользоваться встроенным объектом ХешированиеДанных. Разберем пример вспомогательной функции:


Функция ПолучитьMD5ХешСтроки(ВходнаяСтрока) Экспорт
    Хеширование = Новый ХешированиеДанных(ХешФункция.MD5);
    Хеширование.Добавить(ВходнаяСтрока);
    
    // Получаем шестнадцатеричное строковое представление хеша
    ХешСтрока = НРег(СтрЗаменить(Строка(Хеширование.ХешСумма), " ", ""));
    Возврат ХешСтрока;
КонецФункции

Перед добавлением пароля в структуру параметров обязательно обработайте его этой функцией: ПараметрыЗапроса.Вставить("password", ПолучитьMD5ХешСтроки(ПарольОтКабинета));.

2. Лимиты и ограничения на объемы запрашиваемых данных

При попытке выгрузить отчет за длительный период вы можете столкнуться с неявными ошибками со стороны сервера. На стороне Webpay установлены жесткие ограничения:

Для обхода этих лимитов в коде 1С рекомендуется реализовывать пакетную загрузку данных. Например, если бухгалтеру требуется отчет за год, алгоритм 1С должен автоматически разбить этот период на ежемесячные или декадные интервалы, последовательно отправить несколько запросов к API и объединить полученные результаты в одну таблицу значений.

3. Альтернативный метод получения отчетов (GET-запросы)

Помимо отправки ресурсоемких POST-запросов, API Webpay предлагает альтернативный и зачастую более удобный сценарий работы через GET-запросы. В этом случае адрес обращения выглядит как: https://merchant.webpay.by/reports/merchants/{reportType}, где вместо {reportType} подставляется нужный тип отчета.

У данного подхода есть важные отличия:

  1. Авторизация: Авторизационные данные передаются через стандартный заголовок HTTP Authorization: login:password (в формате Basic auth).
  2. Передача параметров: Все параметры фильтрации (даты, форматы) указываются непосредственно в URL-строке запроса (Query parameters). Например: /reports/merchants/ERIP_TRANSACTION_LOG?startDate=2020-09-01&endDate=2020-10-06.
  3. Асинхронная отправка на Email: Если в GET-запросе передать дополнительный параметр email со значением адреса электронной почты, система Webpay сформирует отчет в фоновом режиме на своей стороне и отправит его на указанный ящик (обычно в течение 5–10 минут). Это крайне удобно для тяжелых отчетов, обработка которых в режиме реального времени может приводить к таймаутам соединения в 1С.

4. Доступные типы отчетов и форматы файлов

В обсуждении на форуме рассматривается только лог транзакций ЕРИП (ERIP_TRANSACTION_LOG) в формате JSON. Но возможности интеграции гораздо шире. Вы можете автоматизировать получение следующих отчетов:

Кроме того, если разбор сложных иерархических JSON-структур в 1С вызывает затруднения, вы можете изменить параметр reportFormat на значение EXCEL. Веб-сервис сформирует готовый файл .xlsx. В коде 1С этот файл можно сохранить на локальный диск или во временное хранилище с помощью метода Ответ.ПолучитьТелоКакДвоичныеДанные() и затем легко прочитать встроенными средствами платформы (например, через объект ТабличныйДокумент).

Инструменты для отладки HTTP-запросов в 1С

При разработке любых интеграционных механизмов мы настоятельно рекомендуем использовать внешние обработки для тестирования API непосредственно из среды выполнения «1С:Предприятия». Например, специализированные консоли HTTP-запросов. В отличие от внешних программ тестирования (таких как Postman или Insomnia), консоль в 1С позволяет:

Применяя данные рекомендации и используя встроенные механизмы сериализации JSON, вы сможете создавать надежные, стабильные и безопасные механизмы обмена данными между вашей информационной базой 1С и внешними платежными сервисами.

← На главную