Как правильно настроить HTTP POST запрос в 1С и исправить ошибки авторизации и перенаправления (на примере API express-pay.by)?

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

При интеграции 1С с внешними API и платежными шлюзами разработчики часто сталкиваются с ситуацией, когда отправленный HTTP-запрос не приносит желаемого результата. Вроде бы код написан по шаблону, но сервер возвращает пустой ответ, ошибку авторизации Authorization has been denied for this request или странное сообщение о перенаправлении 302 Object Moved.

В этой статье мы подробно разберем типичные ошибки, которые совершают программисты 1С при работе с объектами HTTPСоединение и HTTPЗапрос. Мы пошагово проанализируем каждую проблему на примере реального кейса интеграции с платежным сервисом «Экспресс Платежи» (api.express-pay.by) и соберем идеальный рабочий шаблон кода для отправки POST-запросов.

---

Выясняем причины: почему POST-запрос возвращает ошибки?

Для начала проанализируем исходный код, который часто приводит к сбоям, и выделим в нем критические уязвимости. Обычно разработчики пытаются уместить весь URL-адрес в одно место или забывают про особенности работы протокола HTTPS в 1С. Рассмотрим основные проблемы по очереди.

Ошибка №1. Неправильное разделение хоста и пути ресурса

Взглянем на частую ошибку инициализации объектов работы с сетью:


// Ошибочный вариант
HTTPСоединение = Новый HTTPСоединение("https://api.express-pay.by/v1/invoices?token={Token}");
запросPOST = Новый HTTPЗапрос("api.express-pay.by");

При создании HTTPСоединение в качестве первого параметра должен передаваться исключительно адрес сервера (хост) без указания протокола (http/https), портов и путей. Все, что идет после имени домена (включая параметры запроса), должно передаваться в объекте HTTPЗапрос.

Если написать так, как в примере выше, то 1С попытается обратиться к несуществующему хосту. Правильное разделение выглядит следующим образом:

Ошибка №2. Игнорирование защищенного соединения SSL (HTTPS)

Если мы создаем объект HTTPСоединение простым конструктором:

HTTPСоединение = Новый HTTPСоединение("api.express-pay.by");

то 1С по умолчанию пытается установить связь по незащищенному протоколу HTTP (порт 80). Современные веб-серверы и платежные шлюзы в целях безопасности запрещают незащищенные соединения. В ответ на такой запрос сервер присылает HTTP-статус 302 Found (или Object Moved) и перенаправляет клиентское приложение на защищенную версию адреса с HTTPS.

В файле ответа при этом можно увидеть HTML-код с текстом: This document may be found here. Чтобы избежать нежелательного перенаправления, необходимо сразу инициализировать защищенное соединение SSL, передав в конструктор порт 443 и объект ЗащищенноеСоединениеOpenSSL.

Ошибка №3. Буквальное использование фигурных скобок в параметрах URL

В документации к различным API параметры часто обозначают в фигурных скобках, например: /v1/invoices?token={token}. Это лишь плейсхолдер, указывающий на то, что вместо {token} нужно подставить реальное строковое значение ключа безопасности.

Если разработчик буквально переносит фигурные скобки в код 1С:

запросPOST = Новый HTTPЗапрос("/v1/invoices?token={" + Token + "}");

то сервер принимает эти скобки как часть токена (в закодированном виде они превращаются в символы %7B и %7D). Естественно, валидация ключа на стороне сервера проваливается, и система возвращает ошибку авторизации: {"Message":"Authorization has been denied for this request."}. Фигурные скобки необходимо убирать.

Ошибка №4. Отсутствие кодирования параметров (URL-encoding)

При отправке данных формы методом POST с типом контента application/x-www-form-urlencoded все передаваемые параметры склеиваются в одну строку. Параметры должны разделяться строго символом амперсанда &, а не системными разделителями строк 1С (такими как Символы.ПС).

Более того, любые спецсимволы, кириллица или пробелы в значениях параметров (например, в назначении платежа или имени клиента) должны быть корректно закодированы. В противном случае веб-сервер не сможет корректно распарсить тело запроса.

---

Пошаговое руководство: как правильно составить и отправить POST-запрос

Теперь, когда мы проанализировали причины основных ошибок, разработаем надежный и гибкий алгоритм отправки POST-запроса в 1С. Мы откажемся от записи ответов во временные файлы на диске (чтобы не зависеть от прав доступа в операционной системе) и научимся обрабатывать ответы сервера прямо в оперативной памяти.

Шаг 1. Формируем тело запроса и кодируем параметры

Для начала подготовим строку параметров для передачи в теле POST-запроса. Все параметры должны быть приведены к формату URL-строки. Для этого мы напишем вспомогательную функцию кодирования параметров, чтобы гарантировать корректность отправляемых данных.


// Функция для безопасного кодирования параметров запроса
Функция КодироватьПараметр(ЗначениеПараметра)
    Возврат КодироватьСтроку(Строка(ЗначениеПараметра), СпособКодированияСтроки.КодировкаURL);
КонецФункции

Теперь соберем саму строку параметров, разделяя их знаком &:


// Формируем параметры тела запроса (токен в теле дублировать не нужно, если он передается в URL)
ПараметрыТела = "AccountNo=" + КодироватьПараметр("123456")
              + "&Amount=" + КодироватьПараметр("150.00")
              + "&Currency=" + КодироватьПараметр("933") // 933 - код белорусского рубля BYN
              + "&Info=" + КодироватьПараметр("Оплата за ИТ-услуги")
              + "&ReturnInvoiceUrl=1";

Шаг 2. Создаем защищенное соединение по протоколу HTTPS

Для отправки запроса на защищенный хост нам обязательно потребуется объект ЗащищенноеСоединениеOpenSSL. Создадим его с дефолтными системными настройками сертификатов. Это гарантирует беспрепятственную работу с протоколом HTTPS.


// Определяем параметры подключения к серверу
СерверИсточник = "api.express-pay.by";
ПортПодключения = 443; // Стандартный порт для HTTPS

// Инициализируем защищенное SSL-соединение
Защита = Новый ЗащищенноеСоединениеOpenSSL();
HTTPСоединение = Новый HTTPСоединение(СерверИсточник, ПортПодключения, , , , , Защита);

Шаг 3. Инициализируем объект HTTP-запроса и заполняем заголовки

Создаем объект HTTPЗапрос. В качестве параметра конструктора передаем только путь к ресурсу на сервере и параметры строки запроса (в нашем случае — токен авторизации). Также обязательно устанавливаем заголовок Content-Type, сообщающий серверу, в каком формате передаются данные в теле POST-запроса.


// Путь к ресурсу API с корректным подставлением токена авторизации (БЕЗ фигурных скобок!)
ТокенАвторизации = "ваш_секретный_токен_из_личного_кабинета";
ПутьКРесурсу = "/v1/invoices?token=" + ТокенАвторизации;

// Инициализируем запрос
ЗапросPOST = Новый HTTPЗапрос(ПутьКРесурсу);

// Устанавливаем обязательный заголовок для передачи параметров формы
ЗапросPOST.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

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

Шаг 4. Отправляем запрос и обрабатываем результат в памяти

Вместо того чтобы записывать результаты во внешние файлы (например, на диск C:\, к которому у сервера 1С может просто не быть прав доступа), мы отправим запрос и получим объект HTTPОтвет. Это позволит нам проанализировать код состояния ответа (например, 200 или 201 для успешных запросов) и прочитать тело ответа напрямую.


Попытка
    // Отправляем POST-запрос на обработку
    HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(ЗапросPOST);
    
    // Получаем код состояния HTTP-ответа
    КодСостояния = HTTPОтвет.КодСостояния;
    
    // Считываем тело ответа сервера как текстовую строку
    ТекстОтвета = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
    
    // Анализируем результат работы
    Если КодСостояния = 200 Или КодСостояния = 201 Тогда
        // Запрос успешно обработан сервером
        Сообщить("Счет успешно выставлен!");
        Сообщить("Ответ сервера: " + ТекстОтвета);
        
        // Здесь можно распарсить полученный JSON ответ, используя объект "ЧтениеJSON"
    Иначе
        // Сервер вернул ошибку (например, 400, 401, 403, 500)
        Сообщить("Ошибка при выставлении счета! Код состояния сервера: " + КодСостояния);
        Сообщить("Детали ошибки: " + ТекстОтвета);
    КонецЕсли;

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

---

Дополнительные настройки интеграции: на что обратить внимание?

Если даже при абсолютно верном и корректном коде 1С вы продолжаете получать ошибку авторизации Authorization has been denied, обязательно проверьте административные настройки на стороне самого сервиса интеграции:

  1. Включение API в личном кабинете. Убедитесь, что для вашей учетной записи или конкретной услуги активирована возможность удаленного взаимодействия. Перейдите в настройки личного кабинета мерчанта и проверьте статус флажка «Разрешить использование API для услуги».
  2. Цифровая подпись запросов (Signature). В зависимости от требований безопасности сервиса, запросы могут требовать обязательного подписания. Цифровая подпись формируется путем склеивания значений всех параметров в алфавитном порядке и их последующего хеширования (обычно алгоритмом MD5 или SHA1) с использованием секретного ключа (соли), задаваемого в личном кабинете. Если данная опция включена в ЛК, запросы без параметра signature будут отклоняться сервером.
  3. Коды валют. При формировании параметров платежей (особенно для РБ) всегда передавайте актуальные международные цифровые коды валют. Например, для белорусского рубля (BYN) используйте код 933. Использование устаревших кодов (например, 974 для старого белорусского рубля) приведет к ошибке валидации формы на стороне платежного шлюза.

Применяя предложенный нами структурированный подход к разделению адресного пространства, обязательному включению SSL/HTTPS, URL-кодированию параметров и чтению ответов в оперативную память, вы навсегда избавитесь от неожиданных ошибок обмена данными по HTTP протоколу в среде 1С:Предприятие.

← На главную