HTTP API 1С для Tec.Delivery
Практическая реализация репрезентатива данных 1С
Данная инструкция предназначена для разработчиков 1С и описывает практическую реализацию HTTP API, через которое Tec.Delivery получает категории, товары, цены, остатки и данные изображений из 1С.
1.1. Создание HTTP-сервиса в 1С
В конфигурации необходимо создать объект метаданных HTTP-сервис, который будет использоваться Tec.Delivery как репрезентатив данных 1С. Через этот HTTP-сервис Tec.Delivery будет получать данные из информационной базы: категории, товары, цены, остатки и сведения об изображениях.
HTTP-сервис реализуется на стороне 1С и должен содержать шаблоны URL, обработчики запросов и программный код, который получает данные из объектов конфигурации, формирует JSON и возвращает его в HTTP-ответе.
TecDeliveryAPI
Практический порядок создания HTTP-сервиса:
- Открыть конфигурацию в режиме Конфигуратор.
- В дереве конфигурации открыть раздел Общие → HTTP-сервисы.
- Создать новый HTTP-сервис.
- Задать имя сервиса, например TecDeliveryAPI.
- Добавить шаблоны URL для методов API.
- Для каждого шаблона создать обработчик запроса.
- В обработчике реализовать получение параметров запроса, выборку данных из 1С и возврат JSON-ответа.
| Шаблон URL | HTTP-метод | Обработчик | Назначение |
|---|---|---|---|
| /api/v1/get | GET | Get | Выгрузка категорий и товаров |
| /api/v1/balance | GET | Balance | Выгрузка актуальных остатков |
HTTP-сервис: TecDeliveryAPI
Шаблон URL: /api/v1/get → обработчик Get
Шаблон URL: /api/v1/balance → обработчик Balance
После создания HTTP-сервиса конфигурацию необходимо обновить и опубликовать информационную базу на веб-сервере. Без публикации на веб-сервере HTTP-сервис будет существовать только в конфигурации 1С и не будет доступен для внешних HTTP-запросов.
1.2. Публикация HTTP-сервиса на веб-сервере
Для доступа к HTTP-сервису информационная база 1С должна быть опубликована на веб-сервере. Обычно для публикации используется веб-сервер Apache или IIS, установленный на сервере 1С или на отдельном сервере, имеющем доступ к кластеру 1С.
Публикация выполняется средствами 1С. В результате создается веб-публикация информационной базы, через которую становятся доступны HTTP-сервисы конфигурации.
Практический порядок публикации:
- Открыть информационную базу в режиме Конфигуратор.
- Перейти в меню Администрирование → Публикация на веб-сервере.
- Выбрать веб-сервер, например Apache или IIS.
- Указать имя публикации, например tec1c.
- Указать каталог публикации на сервере.
- Включить публикацию HTTP-сервисов.
- Сохранить публикацию и перезапустить веб-сервер при необходимости.
| Параметр публикации | Описание | Пример |
|---|---|---|
| Веб-сервер | Сервер, через который будут доступны HTTP-запросы к 1С | Apache или IIS |
| Имя публикации | Путь, по которому будет доступна информационная база | tec1c |
| Каталог публикации | Папка, в которую 1С создаст файлы веб-публикации | C:\inetpub\wwwroot\tec1c |
| HTTP-сервисы | Должны быть включены для доступа к API Tec.Delivery | Включено |
https://example.com/tec1c/hs/TecDeliveryAPI/api/v1/get?type=product&limit=100&offset=0
В URL публикации часть /tec1c соответствует имени веб-публикации информационной базы, часть /hs используется платформой 1С для обращения к HTTP-сервисам, а TecDeliveryAPI соответствует имени HTTP-сервиса в конфигурации.
1.3. Проверка доступности HTTP-сервиса
После публикации необходимо проверить, что HTTP-сервис доступен по URL и возвращает корректный HTTP-ответ. Проверку можно выполнить из браузера, Postman, curl или другого HTTP-клиента.
GET https://example.com/tec1c/hs/TecDeliveryAPI/api/v1/get?type=category&limit=10&offset=0
curl -X GET "https://example.com/tec1c/hs/TecDeliveryAPI/api/v1/get?type=category&limit=10&offset=0"
Если HTTP-сервис опубликован корректно, сервер должен вернуть HTTP-статус 200 и JSON-ответ в формате Tec.Delivery.
{
"data": [],
"total": 0
}
2.1. Обработчик метода /api/v1/get
Метод /api/v1/get должен принимать параметр type и в зависимости от его значения возвращать категории или товары.
Функция Get(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
Попытка
ТипДанных = Запрос.ПараметрыЗапроса.Получить("type");
Лимит = Число(Запрос.ПараметрыЗапроса.Получить("limit"));
Смещение = Число(Запрос.ПараметрыЗапроса.Получить("offset"));
ДатаИзменения = Запрос.ПараметрыЗапроса.Получить("modified_since");
Если Лимит = 0 Тогда
Лимит = 100;
КонецЕсли;
Если ТипДанных = "category" Тогда
Результат = ПолучитьКатегории(Лимит, Смещение, ДатаИзменения);
ИначеЕсли ТипДанных = "product" Тогда
Результат = ПолучитьТовары(Лимит, Смещение, ДатаИзменения);
Иначе
Ответ.КодСостояния = 400;
Ответ.УстановитьТелоИзСтроки("{""error"":""Invalid type""}", КодировкаТекста.UTF8);
Возврат Ответ;
КонецЕсли;
Ответ.УстановитьТелоИзСтроки(Результат, КодировкаТекста.UTF8);
Исключение
Ответ.КодСостояния = 500;
Ответ.УстановитьТелоИзСтроки("{""error"":""Internal server error""}", КодировкаТекста.UTF8);
КонецПопытки;
Возврат Ответ;
КонецФункции
Функция ПолучитьКатегории(Лимит, Смещение, ДатаИзменения) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.ДатаИзменения КАК ДатаИзменения
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа = ИСТИНА
| И Номенклатура.ПометкаУдаления = ЛОЖЬ";
Если ЗначениеЗаполнено(ДатаИзменения) Тогда
ТекстЗапроса = ТекстЗапроса + "
| И Номенклатура.ДатаИзменения >= &ДатаИзменения";
Запрос.УстановитьПараметр("ДатаИзменения", ПреобразоватьДатуISO(ДатаИзменения));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|УПОРЯДОЧИТЬ ПО
| Номенклатура.Наименование";
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
МассивДанных = Новый Массив;
Всего = 0;
Индекс = 0;
Пока Выборка.Следующий() Цикл
Если Индекс >= Смещение И МассивДанных.Количество() < Лимит Тогда
Объект = Новый Структура;
Объект.Вставить("id", Строка(Выборка.Ссылка.УникальныйИдентификатор()));
Объект.Вставить("type", "category");
Если Выборка.Родитель.Пустая() Тогда
Объект.Вставить("parent", "0");
Иначе
Объект.Вставить("parent", Строка(Выборка.Родитель.УникальныйИдентификатор()));
КонецЕсли;
Объект.Вставить("name", Выборка.Наименование);
Объект.Вставить("modified_at", ФорматДатыISO(Выборка.ДатаИзменения));
МассивДанных.Добавить(Объект);
КонецЕсли;
Индекс = Индекс + 1;
Всего = Всего + 1;
КонецЦикла;
Возврат СформироватьJSONОтвет(МассивДанных, Всего);
КонецФункции
Функция ПолучитьТовары(Лимит, Смещение, ДатаИзменения) Экспорт
Запрос = Новый Запрос;
ТекстЗапроса =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Родитель КАК Родитель,
| Номенклатура.Наименование КАК Наименование,
| Номенклатура.Описание КАК Описание,
| Номенклатура.ДатаИзменения КАК ДатаИзменения,
| Номенклатура.Артикул КАК Артикул
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ЭтоГруппа = ЛОЖЬ
| И Номенклатура.ПометкаУдаления = ЛОЖЬ";
Если ЗначениеЗаполнено(ДатаИзменения) Тогда
ТекстЗапроса = ТекстЗапроса + "
| И Номенклатура.ДатаИзменения >= &ДатаИзменения";
Запрос.УстановитьПараметр("ДатаИзменения", ПреобразоватьДатуISO(ДатаИзменения));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + "
|УПОРЯДОЧИТЬ ПО
| Номенклатура.Наименование";
Запрос.Текст = ТекстЗапроса;
Выборка = Запрос.Выполнить().Выбрать();
МассивДанных = Новый Массив;
Всего = 0;
Индекс = 0;
Пока Выборка.Следующий() Цикл
Если Индекс >= Смещение И МассивДанных.Количество() < Лимит Тогда
Цена = ПолучитьЦенуТовара(Выборка.Ссылка);
Остаток = ПолучитьОстатокТовара(Выборка.Ссылка);
СсылкаКартинки = ПолучитьСсылкуКартинки(Выборка.Ссылка);
ХешКартинки = ПолучитьХешКартинки(Выборка.Ссылка);
Объект = Новый Структура;
Объект.Вставить("id", Строка(Выборка.Ссылка.УникальныйИдентификатор()));
Объект.Вставить("type", "product");
Объект.Вставить("parent", Строка(Выборка.Родитель.УникальныйИдентификатор()));
Объект.Вставить("name", Выборка.Наименование);
Объект.Вставить("description", Выборка.Описание);
Объект.Вставить("modified_at", ФорматДатыISO(Выборка.ДатаИзменения));
Объект.Вставить("price", Цена);
Объект.Вставить("discount", 0);
Объект.Вставить("store_balance", Остаток);
Объект.Вставить("bulk", Ложь);
Объект.Вставить("image_url", СсылкаКартинки);
Объект.Вставить("image_hash", ХешКартинки);
МассивДанных.Добавить(Объект);
КонецЕсли;
Индекс = Индекс + 1;
Всего = Всего + 1;
КонецЦикла;
Возврат СформироватьJSONОтвет(МассивДанных, Всего);
КонецФункции
2.2. Выгрузка категорий
Категории обычно соответствуют группам справочника номенклатуры. Для Tec.Delivery каждая категория должна иметь идентификатор, родительскую категорию, название и дату изменения.
| Поле JSON | Источник в 1С | Описание |
|---|---|---|
| id | УникальныйИдентификатор() | Уникальный ID категории |
| type | category | Тип объекта |
| parent | Родитель | ID родительской категории или 0 |
| name | Наименование | Название категории |
| modified_at | ДатаИзменения | Дата последнего изменения |
{
"id": "b92195a4-1c10-11ef-9a1b-00155d01aa01",
"type": "category",
"parent": "0",
"name": "Крупы",
"modified_at": "2026-02-13T13:24:04"
}
2.3. Выгрузка товаров
Товары обычно соответствуют элементам справочника номенклатуры. Для каждого товара необходимо передать основные данные, цену, остаток, признак весового товара и данные изображения.
| Поле JSON | Описание | Пример |
|---|---|---|
| id | Уникальный ID товара | 6f2d5b3a-1c11-11ef-9a1b-00155d01aa01 |
| type | Тип объекта | product |
| parent | ID категории | b92195a4-1c10-11ef-9a1b-00155d01aa01 |
| name | Название товара | Рис длиннозерный 800 г |
| description | Описание товара | Рис длиннозерный пропаренный |
| price | Цена товара | 145 |
| discount | Скидка | 0 |
| store_balance | Остаток товара | 16 |
| bulk | Признак весового товара | false |
| image_url | Ссылка на изображение | https://example.com/1c-images/product.jpg |
| image_hash | Версия изображения | 2026-02-13T13:24:04 |
{
"id": "6f2d5b3a-1c11-11ef-9a1b-00155d01aa01",
"type": "product",
"parent": "b92195a4-1c10-11ef-9a1b-00155d01aa01",
"name": "Рис длиннозерный 800 г",
"description": "Рис длиннозерный пропаренный",
"modified_at": "2026-02-13T13:24:04",
"price": 145,
"discount": 0,
"store_balance": 16,
"bulk": false,
"image_url": "https://example.com/1c-images/6f2d5b3a.jpg",
"image_hash": "2026-02-13T13:24:04"
}
2.4. Получение цены товара
Функция получения цены должна быть адаптирована под фактический регистр цен конкретной конфигурации 1С.
Функция ПолучитьЦенуТовара(Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Цены.Цена КАК Цена
|ИЗ
| РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата) КАК Цены
|ГДЕ
| Цены.Номенклатура = &Номенклатура";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Цена;
КонецЕсли;
Возврат 0;
КонецФункции
2.5. Получение остатков товара
Остатки можно получать из регистра накопления. Если используется несколько складов, необходимо суммировать остаток по всем складам, которые должны участвовать в онлайн-продажах.
Функция ПолучитьОстатокТовара(Номенклатура)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(Остатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &Дата,
| Номенклатура = &Номенклатура
| ) КАК Остатки";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Выборка = Запрос.Выполнить().Выбрать();
Остаток = 0;
Пока Выборка.Следующий() Цикл
Остаток = Остаток + Выборка.Остаток;
КонецЦикла;
Возврат Остаток;
КонецФункции
2.6. Отдельный метод /api/v1/balance
Метод /api/v1/balance используется для быстрой синхронизации остатков без полной выгрузки карточек товаров.
| Поле JSON | Описание | Пример |
|---|---|---|
| id | ID товара | 6f2d5b3a-1c11-11ef-9a1b-00155d01aa01 |
| store_balance | Актуальный остаток | 16 |
{
"data": [
{
"id": "6f2d5b3a-1c11-11ef-9a1b-00155d01aa01",
"store_balance": 16
}
],
"total": 1
}
2.7. Формирование JSON-ответа
Все методы должны возвращать единый формат ответа с массивом data и общим количеством элементов total.
Функция СформироватьJSONОтвет(МассивДанных, Всего)
Ответ = Новый Структура;
Ответ.Вставить("data", МассивДанных);
Ответ.Вставить("total", Всего);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Ответ);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
2.8. Форматирование даты
Даты изменения должны передаваться в формате ISO-подобной строки. Это позволяет Tec.Delivery выполнять инкрементальную синхронизацию.
2026-02-13T13:24:04
Функция ФорматДатыISO(Дата)
Возврат Формат(Дата, "ДФ=yyyy-MM-dd'T'HH:mm:ss");
КонецФункции
Функция ПреобразоватьДатуISO(СтрокаДаты)
СтрокаДаты = СтрЗаменить(СтрокаДаты, "T", " ");
Возврат Дата(СтрокаДаты);
КонецФункции
2.9. Изображения товаров
Если изображения товаров доступны на отдельном веб-сервере, в поле image_url необходимо передавать прямую ссылку на изображение.
Функция ПолучитьСсылкуКартинки(Номенклатура)
GUID = Строка(Номенклатура.УникальныйИдентификатор());
Возврат "https://example.com/1c-images/" + GUID + ".jpg";
КонецФункции
Функция ПолучитьСсылкуКартинки(Номенклатура)
Возврат "";
КонецФункции
Поле image_hash используется для определения изменения изображения. Если изображение изменилось, значение image_hash также должно измениться.
Функция ПолучитьХешКартинки(Номенклатура)
Объект = Номенклатура.ПолучитьОбъект();
Возврат Строка(Объект.ДатаИзменения);
КонецФункции
3.1. Проверка метода категорий
После публикации HTTP-сервиса необходимо проверить, что метод возвращает корректный JSON и HTTP-статус 200.
GET /api/v1/get?type=category&limit=10&offset=0
3.2. Проверка метода товаров
Проверьте, что товары возвращаются с корректными значениями id, parent, name, price и store_balance.
GET /api/v1/get?type=product&limit=10&offset=0
3.3. Проверка инкрементальной выгрузки
Для проверки инкрементальной синхронизации измените один товар в 1С и выполните запрос с параметром modified_since.
GET /api/v1/get?type=product&limit=100&offset=0&modified_since=2026-02-13T13:24:04
3.4. Проверка остатков
Метод /api/v1/balance должен возвращать только ID товаров и актуальные остатки.
GET /api/v1/balance?limit=100&offset=0
4.1. Адаптация под конкретную конфигурацию 1С
Примеры в документе используют типовые имена справочников и регистров. В реальном проекте разработчик 1С должен заменить их на фактические объекты конфигурации.
| Пример из инструкции | Что нужно проверить |
|---|---|
| Справочник.Номенклатура | Фактический справочник товаров |
| РегистрСведений.ЦеныНоменклатуры | Фактический регистр цен |
| РегистрНакопления.ТоварыНаСкладах | Фактический регистр остатков |
ПолучитьЦенуТовара()
ПолучитьОстатокТовара()
ПолучитьСсылкуКартинки()
ПолучитьХешКартинки()
4.2. Ошибки и HTTP-статусы
| HTTP-статус | Когда использовать | Пример ответа |
|---|---|---|
| 200 | Запрос успешно обработан | {"data":[],"total":0} |
| 400 | Передан некорректный параметр | {"error":"Invalid type"} |
| 500 | Внутренняя ошибка обработки | {"error":"Internal server error"} |
4.3. Публикация и доступность сервиса
Если Tec.Delivery обращается к репрезентативу напрямую, HTTP-сервис должен быть доступен из интернета по HTTPS. Если прямой доступ невозможен, можно использовать локальную утилиту синхронизации Tec.Delivery.
Итоговый чек-лист
- Создан HTTP-сервис 1С для Tec.Delivery.
- Добавлен метод /api/v1/get для выгрузки категорий и товаров.
- Добавлен метод /api/v1/balance для выгрузки остатков.
- Реализована постраничная загрузка через limit и offset.
- Реализована инкрементальная выгрузка через modified_since.
- Категории возвращают id, type, parent, name и modified_at.
- Товары возвращают id, parent, name, price, store_balance, image_url и image_hash.
- Функции получения цены и остатков адаптированы под фактическую конфигурацию 1С.
- JSON-ответы возвращаются в едином формате data и total.
- Методы протестированы вручную перед подключением синхронизации Tec.Delivery.