HTTP-сервис 1С: создание с нуля, пример GET и POST

Дата: 21.09.2026 09:33:33
HTTP-сервис
Интеграция
API
Обмен данными
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Управляемые

HTTP-сервис 1С — объект конфигурации, который принимает запросы по адресу вида https://сервер/база/hs/api/... и возвращает ответ, собранный кодом его модуля: JSON, текст или файл. Через него сайт забирает остатки, CRM передаёт заказы, мобильное приложение читает справочники — без COM-соединения и файловых выгрузок. Ниже пример HTTP-сервиса 1С 8.3 от объекта метаданных до проверки из другой базы: методы GET и POST, разбор JSON, коды ответа, авторизация.

Листинги складываются в один модуль. Справочник Номенклатура и его реквизиты названы как в УТ 11, БП 3.0 и ERP — в своей конфигурации подставьте свои имена.

Как устроен сервис: корневой URL, шаблоны, методы

У сервиса есть корневой URL и шаблоны URL с параметрами в фигурных скобках. У каждого шаблона — методы: HTTP-глагол и имя функции-обработчика. Адрес вызова: http://сервер/публикация/hs/корневой-URL/шаблон. Префикс hs постоянный, он отличает HTTP-сервисы от веб-сервисов (ws).

Шаблон URLШаблонМетодОбработчикНазначение
Пинг/v1/pingGETПингGETпроверка публикации
Товары/v1/productsGETТоварыGETсписок по страницам
Товар/v1/products/{code}GETТоварGETтовар по коду
Заказы/v1/ordersPOSTЗаказыPOSTприём заказа

Как создать HTTP-сервис 1С в конфигураторе

  1. В дереве конфигурации: Общие → HTTP-сервисы → Добавить. Имя API, корневой URL api.
  2. Добавьте шаблон URL: имя Товар, шаблон /v1/products/{code}. Остальные — по таблице.
  3. У шаблона добавьте метод: имя GET, HTTP-метод GET. В свойстве «Обработчик» нажмите кнопку с лупой — в модуле сервиса появится функция-заготовка.
  4. Добавьте константу КлючAPIСайта (Строка, 64) и непериодический регистр сведений ЗаказыССайта: измерение ВнешнийИД (Строка, 50), ресурс Обработан (Булево), реквизиты ДатаПолучения (Дата и время) и ТелоЗаказа (Строка неограниченной длины).
  5. Создайте роль ИспользованиеAPI: чтение справочника и константы, чтение и изменение регистра.
  6. Заведите пользователя api_site с этой ролью, флагом «Аутентификация 1С:Предприятия» и длинным случайным паролем.

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

Функция ПингGET(Запрос)

	Строки = Новый Массив;
	Строки.Добавить("Сервис работает");
	Строки.Добавить("Метод: " + Запрос.HTTPМетод);
	Строки.Добавить("Базовый URL: " + Запрос.БазовыйURL);
	Строки.Добавить("Относительный URL: " + Запрос.ОтносительныйURL);
	Строки.Добавить("Пользователь: " + ИмяПользователя());

	Ответ = Новый HTTPСервисОтвет(200);
	Ответ.Заголовки.Вставить("Content-Type", "text/plain; charset=utf-8");
	Ответ.УстановитьТелоИзСтроки(СтрСоединить(Строки, Символы.ПС), КодировкаТекста.UTF8,
		ИспользованиеByteOrderMark.НеИспользовать);
	Возврат Ответ;

КонецФункции
  • Обработчик получает HTTPСервисЗапрос и обязан вернуть HTTPСервисОтвет. Модуль сервиса выполняется только на сервере, директивы компиляции в нём не пишут.
  • БазовыйURL и ОтносительныйURL показывают, какую часть адреса платформа сопоставляет с шаблонами.
  • Третий параметр УстановитьТелоИзСтроки отключает BOM — служебные байты в начале тела, на которых спотыкаются JSON-парсеры сайтов.

Публикация на веб-сервере

  1. При установке платформы отметьте компонент «Модули расширения веб-сервера». Установите Apache 2.4 или включите IIS.
  2. Запустите конфигуратор от имени администратора Windows, иначе он не запишет настройки веб-сервера.
  3. Откройте Администрирование → Публикация на веб-сервере. Имя — trade (станет частью адреса), веб-сервер — Apache 2.4, каталог — например, C:\www\trade.
  4. На закладке «HTTP сервисы» снимите публикацию всех сервисов по умолчанию и отметьте только API.
  5. Нажмите «Опубликовать» и перезапустите службу Apache.

В каталоге публикации появится default.vrd. Фрагмент для серверной базы:

<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
		xmlns:xs="http://www.w3.org/2001/XMLSchema"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		base="/trade"
		ib="Srvr=&quot;srv1c&quot;;Ref=&quot;trade&quot;;">
	<httpServices publishByDefault="false">
		<service name="API"
				rootUrl="api"
				enable="true"
				reuseSessions="dontuse"
				sessionMaxAge="20"
				poolSize="10"
				poolTimeout="5"/>
	</httpServices>
</point>

base — имя публикации в адресе, ib — строка соединения; для файловой базы в ней File=&quot;D:\Bases\Trade&quot;;. При publishByDefault="false" доступны только сервисы из элементов service с enable="true". После ручной правки файла перезапустите веб-сервер.

Откройте в браузере http://localhost/trade/hs/api/v1/ping. Браузер спросит логин и пароль — это Basic-аутентификация, введите данные api_site. Пришёл текст «Сервис работает» — публикация в порядке.

Модуль HTTP-сервиса: ответ в JSON

Чтобы обработчики не собирали ответ заново, сериализацию выносят в две функции модуля. Подробнее о записи и чтении JSON — в статье о JSON в 1С.

// Ответ с телом JSON и заданным кодом состояния
Функция ОтветJSON(КодСостояния, Данные)

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

	Ответ = Новый HTTPСервисОтвет(КодСостояния);
	Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
	Ответ.УстановитьТелоИзСтроки(ТекстJSON, КодировкаТекста.UTF8,
		ИспользованиеByteOrderMark.НеИспользовать);
	Возврат Ответ;

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

// Ошибка в едином формате: {"error": "текст"}
Функция ОтветОшибка(КодСостояния, ТекстОшибки)

	Возврат ОтветJSON(КодСостояния, Новый Структура("error", ТекстОшибки));

КонецФункции
  • ЗаписатьJSON принимает структуры, соответствия со строковыми ключами, массивы, строки, числа, даты и булево; Неопределено становится null. Ссылку на объект он не примет — передавайте код или УникальныйИдентификатор() строкой.
  • ПереносСтрокJSON.Нет убирает переносы и отступы — ответ компактнее.
  • Ошибки уходят в едином формате {"error": "текст"} — сайту хватает одной ветки разбора.

Доступ: пользователь, роль и ключ

Платформа пускает в обработчик только пользователя информационной базы: логин и пароль приходят в заголовке Authorization: Basic. Поверх этого код проверяет роль и ключ интеграции. Утёкший пароль без ключа бесполезен, а сотрудник, который вызовет API со своим логином, получит 403.

// Значение заголовка без учёта регистра имени; пустая строка, если заголовка нет
Функция ЗначениеЗаголовка(Запрос, ИмяЗаголовка)

	Для Каждого Заголовок Из Запрос.Заголовки Цикл
		Если НРег(Заголовок.Ключ) = НРег(ИмяЗаголовка) Тогда
			Возврат Заголовок.Значение;
		КонецЕсли;
	КонецЦикла;

	Возврат "";

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

// Неопределено - доступ разрешён, иначе готовый ответ с ошибкой
Функция ПроверитьДоступ(Запрос)

	Если Не РольДоступна("ИспользованиеAPI") Тогда
		Возврат ОтветОшибка(403, "Нет прав на использование API");
	КонецЕсли;

	КлючИзЗапроса = ЗначениеЗаголовка(Запрос, "X-Api-Key");
	КлючВБазе = Константы.КлючAPIСайта.Получить();

	Если ПустаяСтрока(КлючВБазе) Или КлючИзЗапроса <> КлючВБазе Тогда
		ЗаписьЖурналаРегистрации("API.Доступ", УровеньЖурналаРегистрации.Предупреждение, , ,
			"Неверный X-Api-Key, пользователь " + ИмяПользователя());
		Возврат ОтветОшибка(401, "Не передан или неверен заголовок X-Api-Key");
	КонецЕсли;

	Возврат Неопределено;

КонецФункции
  • ЗначениеЗаголовка не зависит от регистра: по HTTP/2 и через часть прокси имена заголовков приходят строчными буквами.
  • 403 — пользователь известен, но роли нет; 401 — ключ не передан или не совпал. Неудачные попытки видны в журнале регистрации по событию API.Доступ.
  • Пустая константа закрывает доступ всем: забытая настройка не откроет API.
  • Если доступ разрешён, функция возвращает Неопределено. Первые четыре строки каждого рабочего обработчика ниже проверяют именно это.

Если внешняя система не умеет Basic, логин и пароль технического пользователя прописывают в строку ib файла default.vrd параметрами Usr и Pwd. Платформа входит под этим пользователем без заголовка Authorization, а доступ держится на ключе; каталог публикации тогда закройте от посторонних.

Методы HTTP-сервиса: GET с параметрами

Значение из {code} лежит в Запрос.ПараметрыURL, параметры после знака вопроса — в Запрос.ПараметрыЗапроса. Оба свойства — фиксированные соответствия со строковыми значениями. Товар по коду:

Функция ТоварGET(Запрос)

	ОтказВДоступе = ПроверитьДоступ(Запрос);
	Если ОтказВДоступе <> Неопределено Тогда
		Возврат ОтказВДоступе;
	КонецЕсли;

	КодТовара = Запрос.ПараметрыURL.Получить("code");
	Если Не ЗначениеЗаполнено(КодТовара) Тогда
		Возврат ОтветОшибка(400, "Не указан код товара");
	КонецЕсли;

	ЗапросКБазе = Новый Запрос;
	ЗапросКБазе.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	Номенклатура.Ссылка КАК Ссылка,
	|	Номенклатура.Код КАК Код,
	|	Номенклатура.Наименование КАК Наименование,
	|	Номенклатура.Артикул КАК Артикул
	|ИЗ
	|	Справочник.Номенклатура КАК Номенклатура
	|ГДЕ
	|	Номенклатура.Код = &Код
	|	И НЕ Номенклатура.ЭтоГруппа
	|	И НЕ Номенклатура.ПометкаУдаления";
	ЗапросКБазе.УстановитьПараметр("Код", КодТовара);
	Выборка = ЗапросКБазе.Выполнить().Выбрать();

	Если Не Выборка.Следующий() Тогда
		Возврат ОтветОшибка(404, "Товар с кодом " + КодТовара + " не найден");
	КонецЕсли;

	Товар = Новый Структура;
	Товар.Вставить("id", Строка(Выборка.Ссылка.УникальныйИдентификатор()));
	Товар.Вставить("code", СокрЛП(Выборка.Код));
	Товар.Вставить("name", Выборка.Наименование);
	Товар.Вставить("sku", Выборка.Артикул);

	Возврат ОтветJSON(200, Товар);

КонецФункции
  • Ключ в ПараметрыURL совпадает с именем в фигурных скобках шаблона: {code} → "code".
  • Нет товара — ответ 404 с текстом, а не пустой объект: сайт отличит удалённый товар от сбоя.
  • Наружу уходит УникальныйИдентификатор(): он не меняется при перенумерации кодов.

Список товаров по страницам, адрес /v1/products?limit=100&after=00-00000123:

Функция ТоварыGET(Запрос)

	ОтказВДоступе = ПроверитьДоступ(Запрос);
	Если ОтказВДоступе <> Неопределено Тогда
		Возврат ОтказВДоступе;
	КонецЕсли;

	Лимит = 50;
	ЛимитСтрокой = Запрос.ПараметрыЗапроса.Получить("limit");
	Если ЛимитСтрокой <> Неопределено Тогда
		Попытка
			Лимит = Число(ЛимитСтрокой);
		Исключение
			Возврат ОтветОшибка(400, "Параметр limit должен быть числом");
		КонецПопытки;
	КонецЕсли;
	Если Лимит < 1 Или Лимит > 500 Или Лимит <> Цел(Лимит) Тогда
		Возврат ОтветОшибка(400, "Параметр limit: целое число от 1 до 500");
	КонецЕсли;

	ПослеКода = Запрос.ПараметрыЗапроса.Получить("after");
	Если ПослеКода = Неопределено Тогда
		ПослеКода = "";
	КонецЕсли;

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

	Товары = Новый Массив;
	ПоследнийКод = Неопределено;
	Пока Выборка.Следующий() Цикл
		ПоследнийКод = СокрЛП(Выборка.Код);
		Товары.Добавить(Новый Структура("code, name", ПоследнийКод, Выборка.Наименование));
	КонецЦикла;

	Результат = Новый Структура;
	Результат.Вставить("items", Товары);
	Результат.Вставить("next", ?(Товары.Количество() = Лимит, ПоследнийКод, Неопределено));

	Возврат ОтветJSON(200, Результат);

КонецФункции
  • Строку из параметра переводите в число внутри Попытка: Число("abc") вызывает исключение, а клиент должен получить 400, а не 500.
  • Число после ПЕРВЫЕ нельзя передать параметром, поэтому проверенный лимит подставляется в текст через СтрЗаменить.
  • OFFSET в языке запросов нет, поэтому страницы листаются по ключу: next содержит последний код страницы, следующий запрос передаёт его в after. Дальние страницы не замедляются.
  • Если справочник без групп, уберите условие ЭтоГруппа в обоих запросах.

Метод POST: разбор JSON-тела

Заказ с сайта не проводят прямо в обработчике: тело сохраняют в регистр и сразу отвечают, а документ создаёт регламентное задание. Сайт не ждёт проведения, ошибка в документе не теряет заказ.

Функция ЗаказыPOST(Запрос)

	ОтказВДоступе = ПроверитьДоступ(Запрос);
	Если ОтказВДоступе <> Неопределено Тогда
		Возврат ОтказВДоступе;
	КонецЕсли;

	ТекстТела = Запрос.ПолучитьТелоКакСтроку("UTF-8");
	Если ПустаяСтрока(ТекстТела) Тогда
		Возврат ОтветОшибка(400, "Пустое тело запроса");
	КонецЕсли;

	Попытка
		Чтение = Новый ЧтениеJSON;
		Чтение.УстановитьСтроку(ТекстТела);
		Заказ = ПрочитатьJSON(Чтение, Истина);
		Чтение.Закрыть();
	Исключение
		Возврат ОтветОшибка(400, "Тело запроса не является корректным JSON");
	КонецПопытки;

	Если ТипЗнч(Заказ) <> Тип("Соответствие") Тогда
		Возврат ОтветОшибка(422, "Ожидается JSON-объект заказа");
	КонецЕсли;

	ВнешнийИД = Заказ.Получить("id");
	Если ТипЗнч(ВнешнийИД) <> Тип("Строка") Или ПустаяСтрока(ВнешнийИД) Или СтрДлина(ВнешнийИД) > 50 Тогда
		Возврат ОтветОшибка(422, "Поле id: строка от 1 до 50 символов");
	КонецЕсли;

	Позиции = Заказ.Получить("items");
	Если ТипЗнч(Позиции) <> Тип("Массив") Или Позиции.Количество() = 0 Тогда
		Возврат ОтветОшибка(422, "Поле items: непустой массив позиций");
	КонецЕсли;

	Для Каждого Позиция Из Позиции Цикл
		Если ТипЗнч(Позиция) <> Тип("Соответствие")
			Или ТипЗнч(Позиция.Получить("code")) <> Тип("Строка")
			Или ТипЗнч(Позиция.Получить("qty")) <> Тип("Число")
			Или Позиция.Получить("qty") <= 0 Тогда
			Возврат ОтветОшибка(422, "Позиция заказа: нужны code (строка) и qty (число больше нуля)");
		КонецЕсли;
	КонецЦикла;

	МенеджерЗаписи = РегистрыСведений.ЗаказыССайта.СоздатьМенеджерЗаписи();
	МенеджерЗаписи.ВнешнийИД = ВнешнийИД;
	МенеджерЗаписи.Прочитать();
	Если МенеджерЗаписи.Выбран() Тогда
		Возврат ОтветJSON(200, Новый Структура("id, status", ВнешнийИД, "duplicate"));
	КонецЕсли;

	МенеджерЗаписи.ВнешнийИД = ВнешнийИД;
	МенеджерЗаписи.ДатаПолучения = ТекущаяДатаСеанса();
	МенеджерЗаписи.ТелоЗаказа = ТекстТела;
	МенеджерЗаписи.Обработан = Ложь;

	Попытка
		МенеджерЗаписи.Записать();
	Исключение
		ЗаписьЖурналаРегистрации("API.Заказы", УровеньЖурналаРегистрации.Ошибка, , ,
			"Заказ " + ВнешнийИД + ": " + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
		Возврат ОтветОшибка(500, "Заказ не сохранён, повторите запрос позже");
	КонецПопытки;

	Возврат ОтветJSON(201, Новый Структура("id, status", ВнешнийИД, "accepted"));

КонецФункции
  • ПрочитатьJSON(Чтение, Истина) читает объекты в Соответствие. В структуру ключи вроде order-id не прочитаются — будет исключение.
  • Битый JSON — 400, корректный JSON с неверными полями — 422. По коду сайт понимает, что повтор того же запроса не поможет.
  • id заказа из внешней системы — измерение регистра: повтор после тайм-аута получит 200 и duplicate, второй заказ не появится.
  • Исключение при записи уходит в журнал регистрации с подробностями, а клиенту — нейтральный текст без имён модулей и стека.

Проверка: браузер, Postman и запрос из другой базы

GET-методы проверяют в браузере. Для POST удобен Postman: метод POST, адрес http://localhost/trade/hs/api/v1/orders, на закладке Authorization — Basic Auth с логином api_site, в Headers — X-Api-Key, в Body → raw → JSON — тело заказа:

{
    "id": "W-1001",
    "items": [
        {"code": "00-00000123", "qty": 2},
        {"code": "00-00000456", "qty": 1}
    ]
}

Первый вызов вернёт 201 и accepted, повторный — 200 и duplicate. Из другой базы 1С тот же запрос отправляет форма внешней обработки с командой ОтправитьТестовыйЗаказ:

&НаКлиенте
Процедура ОтправитьТестовыйЗаказ(Команда)

	ПоказатьПредупреждение(, ОтправитьЗаказНаСервере());

КонецПроцедуры

&НаСервереБезКонтекста
Функция ОтправитьЗаказНаСервере()

	// Параметры теста: подставьте свои
	Сервер = "localhost";
	Порт = 80;
	Логин = "api_site";
	Пароль = "пароль пользователя api_site";
	КлючAPI = "значение константы КлючAPIСайта";

	Позиции = Новый Массив;
	Позиции.Добавить(Новый Структура("code, qty", "00-00000123", 2));
	Заказ = Новый Структура("id, items", "TEST-" + Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMddHHmmss"), Позиции);

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

	// Для HTTPS: Порт = 443 и Новый ЗащищенноеСоединениеOpenSSL вместо Неопределено
	Соединение = Новый HTTPСоединение(Сервер, Порт, Логин, Пароль, , 30, Неопределено);
	ЗапросHTTP = Новый HTTPЗапрос("/trade/hs/api/v1/orders");
	ЗапросHTTP.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
	ЗапросHTTP.Заголовки.Вставить("X-Api-Key", КлючAPI);
	ЗапросHTTP.УстановитьТелоИзСтроки(ТекстЗаказа, КодировкаТекста.UTF8,
		ИспользованиеByteOrderMark.НеИспользовать);

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

	Возврат СтрШаблон("Код %1: %2", Ответ.КодСостояния, Ответ.ПолучитьТелоКакСтроку("UTF-8"));

КонецФункции
  • &НаСервереБезКонтекста: запрос выполняется на сервере без передачи данных формы, клиентская процедура только показывает результат.
  • Логин и пароль из HTTPСоединение уходят как Basic-аутентификация, заголовок Authorization собирать не нужно.
  • Для HTTPS укажите порт 443 и Новый ЗащищенноеСоединениеOpenSSL. Таймауты, прокси и разбор ответов — в статье об HTTP-запросах из 1С.

Типичные ошибки

Код или текстПричинаЧто сделать
404 Not FoundВ адресе нет /hs/, опечатка в корневом URL или шаблоне, сервис не отмечен при публикации, Apache не перезапущенВызвать /v1/ping, сверить адрес с БазовыйURL, открыть default.vrd
405 Method Not AllowedШаблон найден, но метода для этого глагола нет: POST на шаблон только с GETДобавить метод в шаблон
401 UnauthorizedНет заголовка Authorization, неверный пароль, у пользователя выключена аутентификация 1С:ПредприятияПроверить пользователя и пароль
500 и «Нарушение прав доступа!»Роли не хватает права на объект, который читает или пишет обработчикВыдать права «Чтение» и «Изменение» на нужные объекты
500 и «Передано значение недопустимого типа» из ЗаписатьJSONВ структуру ответа попала ссылка на справочник или документПередавать код или Строка(Ссылка.УникальныйИдентификатор())
500 у файловой базы на ApacheУ учётной записи службы Apache нет прав на каталог базыДать ей полный доступ к каталогу
Apache не стартует: «Cannot load …wsap24.dll into server»Разрядность Apache и модуля расширения 1С не совпадаетПоставить модули расширения той же разрядности
«Unexpected token» в JavaScript, «Syntax error» в PHP при разборе ответаВ начале тела BOMПередавать ИспользованиеByteOrderMark.НеИспользовать в УстановитьТелоИзСтроки
Кириллица в теле заказа нечитаемаТело прочитано не в той кодировкеУказывать "UTF-8" в ПолучитьТелоКакСтроку, клиенту — charset=utf-8

Частые вопросы

Чем HTTP-сервис отличается от веб-сервиса 1С?

Веб-сервис работает по SOAP: XML, WSDL-описание, типы через XDTO. HTTP-сервис — обычный REST: адреса, методы и формат ответа определяет разработчик. Для сайтов, мобильных приложений и JavaScript проще HTTP-сервис; веб-сервис выбирают, когда другая сторона требует SOAP.

Можно ли добавить сервис в типовую конфигурацию без снятия с поддержки?

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

Как отдать файл, например PDF счёта?

Вместо УстановитьТелоИзСтроки вызовите Ответ.УстановитьТелоИзДвоичныхДанных(Данные) и добавьте заголовки Content-Type: application/pdf и Content-Disposition: attachment; filename="invoice.pdf".

Когда проще заказать

Если сервис нужен под конкретный сайт, CRM или маркетплейс — с согласованным контрактом, тестовым контуром и сопровождением, — быстрее поручить его исполнителю: услуги по доработке и интеграции 1С. Опишите конфигурацию, внешнюю систему и нужные методы в форме задания, оценка бесплатная.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.