Как подключить 1С к внешнему веб-сервису: REST, SOAP, JSON и фоновый обмен

· 10 мин

Содержание

Для работы с внешним веб-сервисом в 1С 8.3 есть два механизма. REST-сервисы вызывают объектами HTTPСоединение и HTTPЗапрос, а SOAP-сервисы подключают через объект конфигурации WS-ссылка или через WSОпределения и WSПрокси прямо в коде. Ответ в JSON разбирают функцией ПрочитатьJSON, ответ в XML — через ЧтениеXML и ФабрикаXDTO.

Интеграция 1С с внешним сервисом почти всегда строится одинаково. Код запроса пишут в серверном общем модуле, адрес и пароль хранят вне кода, ошибки пишут в журнал регистрации, а регулярный обмен отдают регламентному заданию. Всё, что ниже, относится к платформе 8.3 и к любой конфигурации, где разрешено дорабатывать код или подключать расширения.

Подготовка: какой механизм интеграции выбрать в 1С

Сначала посмотрите документацию сервиса. От неё зависит, какой объект платформы понадобится.

Что даёт сервисЧем работать в 1СГде пишется код
REST API: адреса вида /api/v1/orders, ответы в JSONHTTPСоединение + HTTPЗапросСерверный общий модуль
SOAP: есть ссылка на WSDL (...?wsdl)WS-ссылка или WSОпределения + WSПроксиСерверный общий модуль
Внешняя система сама шлёт данные в 1СHTTP-сервис или Web-сервис в самой конфигурации + публикация базыМодуль HTTP-сервиса

Что подготовить до первой строки кода:

  • 🔑 тестовый адрес сервиса и учётные данные (логин и пароль, токен или клиентский сертификат);
  • 📄 пример запроса и ответа из документации — лучше проверенный в Postman или curl;
  • 🖥️ доступ с сервера 1С к адресу сервиса: в клиент-серверном варианте запрос уходит с машины, где работает рабочий процесс, а не с компьютера пользователя;
  • 🧩 расширение конфигурации , если база типовая и на поддержке. Так доработка переживёт обновления.

Проверьте доступность сервиса с сервера 1С заранее: curl -v https://api.example.ru/ping или Test-NetConnection api.example.ru -Port 443 в PowerShell. Частая причина «ошибок 1С» на старте — закрытый на сервере исходящий порт или неучтённый прокси.

Как отправить HTTP-запрос к REST-сервису из 1С

Схема одна для любого REST API. Создаёте соединение с сервером, формируете запрос с адресом ресурса и заголовками, вызываете метод и проверяете код ответа.

Соединение и защищённый канал

Конструктор HTTPСоединение принимает сервер без https://, порт, логин, пароль, прокси, таймаут в секундах и объект защищённого соединения. Для HTTPS нужен ЗащищенноеСоединениеOpenSSL, иначе запрос уйдёт по обычному HTTP или упадёт.

Функция ПолучитьЗаказ(НомерЗаказа) Экспорт

    SSL = Новый ЗащищенноеСоединениеOpenSSL(, Новый СертификатыУдостоверяющихЦентровОС);
    Соединение = Новый HTTPСоединение("api.example.ru", 443, , , , 30, SSL);

    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Accept", "application/json");
    Заголовки.Вставить("Authorization", "Bearer " + ПолучитьТокенСервиса());

    Адрес = "/api/v1/orders/" + Формат(НомерЗаказа, "ЧГ=0");
    Запрос = Новый HTTPЗапрос(Адрес, Заголовки);

    Ответ = Соединение.Получить(Запрос);
    Если Ответ.КодСостояния <> 200 Тогда
        ВызватьИсключение СтрШаблон("Сервис вернул код %1: %2",
            Ответ.КодСостояния, Ответ.ПолучитьТелоКакСтроку());
    КонецЕсли;

    Возврат Ответ.ПолучитьТелоКакСтроку();

КонецФункции

Три детали, на которых спотыкаются чаще всего:

  1. Таймаут. По умолчанию он равен нулю, то есть запрос ждёт бесконечно. Зависший сервис подвесит и сеанс пользователя. Ставьте 20–60 секунд.
  2. Номер в адресе. Число без Формат(..., "ЧГ=0") превратится в 1 234 с неразрывным пробелом, и сервис вернёт 404.
  3. СертификатыУдостоверяющихЦентровОС. Платформа проверит сертификат сервера по хранилищу Windows или Linux. Если сервис на самоподписанном сертификате, добавьте его корневой сертификат в хранилище ОС сервера, а не отключайте проверку.

Методы HTTP

Метод HTTPМетод HTTPСоединениеТипичная задача
GETПолучить(Запрос)Прочитать заказ, остатки, курс
POSTОтправитьДляОбработки(Запрос)Создать документ во внешней системе
PUTЗаписать(Запрос)Полностью заменить объект
DELETEУдалить(Запрос)Удалить объект
PATCH и любые другиеВызватьHTTPМетод("PATCH", Запрос)Частичное изменение

Тело для POST задают до вызова: Запрос.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать). Без явного отказа от BOM часть сервисов не может разобрать JSON: первые три байта метки кодировки ломают парсер.

Авторизация

  • 🔐 Basic. Проще всего передать логин и пароль в конструктор HTTPСоединение. Если заголовок собираете вручную, уберите переносы строк из результата Base64Строка(): на длинных строках платформа вставляет их, и сервер отвечает 401.
  • 🎫 Токен (Bearer). Получаете токен отдельным POST-запросом, храните вместе со сроком жизни и обновляете за пару минут до истечения, а не после ошибки.
  • 📜 Клиентский сертификат. Первый параметр ЗащищенноеСоединениеOpenSSL — объект СертификатКлиентаФайл с путём к файлу .pfx и паролем. Файл должен лежать на сервере 1С.

Подключение SOAP-сервиса через WS-ссылку

SOAP удобнее подключать объектом конфигурации. В Конфигураторе откройте ветку Общие → WS-ссылки, добавьте новый элемент и укажите адрес WSDL. Платформа скачает описание и покажет сервисы, точки подключения и операции.

Вызов из кода выглядит так:

Прокси = WSСсылки.СервисКонтрагентов.СоздатьWSПрокси(
    "http://example.ru/partners", "PartnerService", "PartnerServiceSoap");
Прокси.Пользователь = Логин;
Прокси.Пароль = Пароль;

Результат = Прокси.CheckPartner("7700000000");

Пространство имён, имя сервиса и точки подключения берите из окна WS-ссылки — они видны в её дереве.

Если адрес WSDL меняется (тестовый и боевой контур) или описание у сервиса часто обновляется, используйте динамический вариант без объекта конфигурации:

Определения = Новый WSОпределения(АдресWSDL, Логин, Пароль, , 30, SSL);
Прокси = Новый WSПрокси(Определения, "http://example.ru/partners",
    "PartnerService", "PartnerServiceSoap", , 30, SSL);

Динамическое WSОпределения при каждом создании заново скачивает WSDL. В цикле на 1000 документов это 1000 лишних запросов. Создайте прокси один раз до цикла и используйте повторно.

После изменения WSDL на стороне сервиса WS-ссылку нужно обновить: в контекстном меню объекта есть команда повторного импорта описания. Затем обновите конфигурацию базы данных.

Разбор ответа в JSON и XML

JSON: чтение и запись

Ответ REST-сервиса почти всегда JSON. Читать удобнее в Соответствие: имена полей у внешних систем бывают с дефисами или цифрами в начале, а такие свойства структура не примет.

Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТекстОтвета);
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();

Для Каждого Позиция Из Данные["items"] Цикл
    Артикул = Позиция["sku"];
    Количество = Позиция["qty"];
КонецЦикла;

Для отправки данных собираете структуру или соответствие и сериализуете:

Тело = Новый Структура;
Тело.Вставить("number", Документ.Номер);
Тело.Вставить("date", Документ.Дата);
Тело.Вставить("sum", Документ.СуммаДокумента);

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
Настройки = Новый НастройкиСериализацииJSON;
Настройки.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
ЗаписатьJSON(Запись, Тело, Настройки);
ТекстJSON = Запись.Закрыть();

Что учесть при работе с JSON в 1С:

  • 📅 Даты приходят строкой. Преобразуйте их функцией ПрочитатьДатуJSON(Строка, ФорматДатыJSON.ISO).
  • 🔢 Числа приходят типом Число, но идентификаторы вида "000123" держите строкой — иначе потеряются ведущие нули.
  • 🔗 Ссылки 1С (СправочникСсылка) напрямую в JSON не пишутся. Передавайте код, ИНН или уникальный идентификатор: Строка(Ссылка.УникальныйИдентификатор()).
  • ⛔ Пустое значение null превращается в Неопределено. Проверяйте его до присваивания реквизиту.

XML и XDTO

Для сервисов, которые отвечают XML, есть два пути. Простой разбор — ЧтениеXML с циклом по узлам. Типизированный — ФабрикаXDTO.ПрочитатьXML(Чтение), если вы загрузили XSD-схему в пакет XDTO. Второй путь даёт объекты со свойствами и проверку структуры, но требует поддерживать схему в актуальном виде.

Сопоставление полей
id заказа→Номер документа (строкой)
created_at→Дата (ПрочитатьДатуJSON)
customer.inn→Контрагент (поиск по ИНН)
items[].sku→Номенклатура (поиск по артикулу)
items[].qty→Количество
items[].price→Цена

Ошибки интеграции и повторные попытки

Любой вызов внешнего сервиса оборачивайте в Попытка ... Исключение. Обрыв сети, таймаут, ошибка SSL вызывают исключение. Коды 4xx и 5xx исключения не вызывают — их нужно проверить самому через Ответ.КодСостояния.

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

Повторы через очередь, а не через цикл

В 1С нет удобной паузы на сервере, а повтор в цикле сразу после ошибки бесполезен: сервис ещё лежит. Практичнее завести очередь исходящих сообщений — регистр сведений с полями «Объект», «Тело», «Попыток», «Следующая попытка», «Последняя ошибка».

Логика такая:

  1. При проведении документа запись ставится в очередь, а не отправляется сразу.
  2. Регламентное задание раз в 1–5 минут выбирает записи, у которых наступило время следующей попытки.
  3. Успех — запись удаляется. Ошибка — растёт счётчик, время следующей попытки сдвигается: 1, 5, 15, 60 минут.
  4. После 5–10 неудач запись остаётся с флагом ошибки, ответственный видит её в отчёте.

Если сервис поддерживает ключ идемпотентности (заголовок вроде Idempotency-Key), передавайте в нём уникальный идентификатор документа. Тогда повтор после таймаута не создаст во внешней системе дубль.

Фоновые и регламентные задания для обмена

Пользователь не должен ждать ответа сервиса. Если вызов занимает больше пары секунд или отправляется пакет документов, выносите его в фоновое задание.

Запуск из кода — ФоновыеЗадания.Выполнить(). Вызываемая процедура должна быть экспортной и лежать в серверном общем модуле:

Параметры = Новый Массив;
Параметры.Добавить(Документ.Ссылка);
ФоновыеЗадания.Выполнить("ИнтеграцияЗаказы.ОтправитьЗаказ", Параметры,
    "ОтправкаЗаказа_" + Строка(Документ.Ссылка.УникальныйИдентификатор()),
    "Отправка заказа во внешнюю систему");

Третий параметр — ключ. Два задания с одинаковым ключом одновременно не запустятся: платформа выдаст ошибку на второй вызов. Это защищает от двойной отправки по двойному клику.

Регулярный обмен настраивают регламентным заданием:

  1. В Конфигураторе или расширении добавьте объект в ветке Общие → Регламентные задания.
  2. Укажите имя метода из серверного общего модуля и включите флаг «Использование».
  3. Задайте расписание: например, каждые 300 секунд.
  4. В клиент-серверной базе проверьте, что регламентные задания не заблокированы в свойствах информационной базы в консоли кластера.

В типовых конфигурациях на БСП состояние заданий видно в Администрирование → Обслуживание → Регламентные операции → Регламентные и фоновые задания. Там же можно запустить задание вручную и посмотреть текст последней ошибки.

В файловой базе регламентные задания выполняются только пока база открыта в клиенте или опубликована на веб-сервере. Для постоянного обмена файловый вариант ненадёжен.

Безопасность интеграции: пароли, сертификаты, права

Утечка токена от внешнего API обходится дороже, чем вся доработка. Минимальные правила:

  • 🚫 Пароли и токены не пишите в код и в константы. Константу видит любой пользователь с правом чтения. В конфигурациях на БСП есть безопасное хранилище: ОбщегоНазначения.ЗаписатьДанныеВБезопасноеХранилище() и ОбщегоНазначения.ПрочитатьДанныеИзБезопасногоХранилища(). Данные из него читаются только в привилегированном режиме.
  • 🔒 Только HTTPS с проверкой сертификата сервера. Отключать проверку ради «чтобы заработало» нельзя: так открывается возможность перехвата трафика.
  • 👤 Отдельная учётная запись у сервиса с минимальными правами. Если 1С только читает остатки, у ключа не должно быть права на запись.
  • 🛡️ Профили безопасности. Если в кластере включены профили безопасности, внешний ресурс (адрес и порт) нужно разрешить. В БСП конфигурация сама запрашивает разрешения на использование внешних ресурсов — администратору остаётся их подтвердить.
  • 📝 Журнал. Пишите в журнал регистрации адрес, код ответа и длительность запроса, но не тело с персональными данными и не заголовок Authorization.

Если внешняя система сама обращается к 1С, нужна публикация базы на веб-сервере (Apache или IIS) через Администрирование → Публикация на веб-сервере в Конфигураторе. Для такой публикации заведите в 1С отдельного пользователя с ролью только на нужный HTTP-сервис и закройте публикацию от интернета, если доступ нужен только внутри сети.

Частые ошибки при интеграции 1С с веб-сервисами

ОшибкаЧем оборачиваетсяКак правильно
Запрос выполняется &НаКлиентеНужен доступ в интернет с каждого рабочего места, токен попадает на клиентВызов только в серверном модуле
Отправка прямо в ПриЗаписи документаПроведение висит, при сбое сервиса документ не записываетсяОчередь + фоновое или регламентное задание
Таймаут не заданСеанс зависает до перезапуска20–60 секунд в конструкторе соединения
Адрес сервиса вшит в кодПри переезде на боевой контур правят конфигурациюХранить адрес в настройках, а копию базы для тестов перенастраивать
Тестовая копия базы шлёт данные в боевой сервисДубли заказов и платежей у контрагентаОтключить обмен в копии сразу после развёртывания

Перед первым запуском обмена на копии рабочей базы отключите в ней регламентные задания интеграции, иначе копия начнёт отправлять реальные документы во внешнюю систему.

Можно ли вызывать веб-сервис из веб-клиента 1С?
Можно, но правильнее не делать этого с клиента. Вызывайте серверную процедуру, а она уже обращается к сервису: так запрос идёт с сервера 1С, и токен не попадает в браузер.
Нужна ли отдельная лицензия для работы с веб-сервисами?
Для исходящих запросов из 1С — нет, это часть платформы. Для входящих запросов к опубликованной базе каждый сеанс веб-сервиса использует клиентскую лицензию, как обычное подключение.
Как работать через прокси-сервер организации?
Передайте в конструктор HTTPСоединение или WSОпределения объект ИнтернетПрокси. Вариант Новый ИнтернетПрокси(Истина) берёт системные настройки прокси сервера.
Чем отладить запрос, если сервис отвечает непонятной ошибкой?
Повторите тот же запрос в Postman или curl с теми же заголовками и телом. Если там он проходит, сравните заголовки: чаще всего отличается Content-Type или метка BOM в теле.
REST или SOAP — что выбрать, если сервис поддерживает оба?
REST проще в отладке и не требует обновлять описание при изменениях сервиса. SOAP оправдан, когда нужна строгая проверка структуры по WSDL и сервис давно стабилен.