Инструкция: структура фида Обмен с сайтами
Где находится код
Основная логика формирования фида:
src/HTTPServices/RestApi/Ext/Module.bsl, обработчикfeedsGET.src/CommonModules/RestAPI_Методы/Ext/Module.bsl, областьfeeds.src/ExchangePlans/Дев_ОбменССайтомОнлайн/Templates/СхемаВыгрузкиДанных/Ext/Template.xml, макет СКДСхемаВыгрузкиДанных.src/ExchangePlans/Дев_ОбменССайтомОнлайн.xml, план обмена и табличная частьДополнительныеРеквизитыСведения.
Ключевые процедуры и функции:
ПолучитьДанные_ОбменССайтомОнлайн(Запрос)- проверяетname,token, вызывает формирование данных и возвращает HTTP-ответ.ВыполнитьФормированиеДанных_ОбменССайтомОнлайн(УзелОбмена)- собирает итоговую JSON-структуру.ПодготовитьДанныеДляВыгрузки_ОбменССайтомОнлайн(Параметры)- получает данные через СКД и дополнительные пакетные запросы.ДобавитьЗапросыВПакет(ТекстЗапроса, Параметры)- добавляет к основному СКД-запросу выборки цен, скидок, доп. свойств, файлов и итогового дерева.ПолучитьСтруктуру_Район,ПолучитьСтруктуру_Объект,ПолучитьСтруктуру_Секция,ПолучитьСтруктуру_ОН,ПолучитьСтруктуру_Балкон,ПолучитьСтруктуру_Цены,ПолучитьСтруктуру_Скидка,ПолучитьСтруктуру_Свойства- задают состав JSON-объектов.
Endpoint
HTTP-сервис: RestApi.
URL-шаблон: /feeds/{ИмяМетода}.
Метод: GET.
Для получения фида используется:
GET /feeds/feeds?name=<НаименованиеУзлаОбмена> token: <ТокенУзлаОбмена>
Параметры:
| Параметр | Где передается | Назначение |
|---|---|---|
name | query string | Наименование узла плана обмена Дев_ОбменССайтомОнлайн. По нему выполняется ПланыОбмена.Дев_ОбменССайтомОнлайн.НайтиПоНаименованию(name) |
token | HTTP-заголовок token; если заголовка нет, проверяется тело запроса | Сравнивается с реквизитом Токен найденного узла обмена |
Ответ всегда оборачивается через СтрокаОтвета:
{
"data": {},
"success": true,
"err_msg": ""
}
При ошибках:
| Условие | HTTP-код | success | err_msg |
|---|---|---|---|
Узел обмена не найден по name | 405 | false | Wrong name : "..." |
| Токен не заполнен или не совпал | 405 | false | Wrong token |
| Ошибка формирования/сериализации | 500 | false | Подробное представление ошибки 1С |
Дальше в документе описана структура внутри data.
Общая структура JSON
{
"data": {
"complexes": [
{
"id": "...",
"name": "...",
"company": "...",
"city": "...",
"images": ["..."],
"buildings": [
{
"id": "...",
"name": "...",
"address": "...",
"floor_cnt": 0,
"commissioning_period": "2026-12-31T00:00:00",
"construction_completion": "2026-09-30T00:00:00",
"sections": [
{
"id": "...",
"name": "Секция 2",
"flats": [
{
"id": "...",
"name": "...",
"section": "...",
"building": "...",
"complexe": "...",
"prices": [],
"discounts": [],
"additional_properties": []
}
]
}
]
}
]
}
]
},
"success": true,
"err_msg": ""
}
Иерархия:
complexes[]- районы строительства.complexes[].buildings[]- объекты строительства внутри района.complexes[].buildings[].sections[]- секции объекта строительства.complexes[].buildings[].sections[].flats[]- лоты / объекты недвижимости.
Как выбираются данные
Основной набор данных строится через СКД СхемаВыгрузкиДанных плана обмена Дев_ОбменССайтомОнлайн.
В начале выборки создается временная таблица Районы из табличной части узла обмена:
ПланОбмена.Дев_ОбменССайтомОнлайн.Районы
То есть в фид попадают только районы, указанные в настройке конкретного узла обмена.
Основной источник лотов:
РегистрСведений.УПДК_ПараметрыНедвижимости
Сверху к нему подтягиваются:
- статусы из
РегистрСведений.УПДК_Недвижимость.СрезПоследних; - данные аренды из
РегистрСведений.АренднаяНедвижимость.СрезПоследних; - этапы строительства из
РегистрСведений.УПДК_ЭтапыСтроительстваОбъектов.СрезПоследних; - цены из
РегистрСведений.УПДК_ФактическиеЦеныНедвижимости; - собственник из
РегистрСведений.УПДК_СобственникиОбъектовНедвижимости.СрезПоследних; - признак снятия с продаж из
РегистрСведений.СнятыеКвартирыСПродаж.СрезПоследних.
Дополнительные пакетные запросы после СКД получают:
- доп. свойства из табличной части узла обмена
ДополнительныеРеквизитыСведенияи значений объекта недвижимости; - присоединенные файлы объектов недвижимости;
- присоединенные файлы районов строительства;
- скидки/наценки;
- связанные объекты;
- все фактические цены по объекту недвижимости;
- итоговое дерево
Район -> Объект -> Секция -> ОбъектНедвижимости.
complexes[]: район строительства
Источник уровня: СтрокаРайон из итогового дерева ДеревоДанных.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
id | string | XMLСтрока(СтрокаРайон.Район) | Уникальный идентификатор района строительства |
name | string | СтрокаРайон.РайонНаименование = ВремНедвижимость.Район.Наименование | Наименование района |
company | string | СтрокаРайон.СобственникНаименование | Собственник района/объектов, подтянутый из регистра собственников |
city | string | СтрокаРайон.РайонГородНаименование = ЕСТЬNULL(ВремНедвижимость.Район.Город.Наименование, "") | Город района |
images | array[string] | РайоныСтроительстваПрисоединенныеФайлы.Описание | URL/описания файлов района. Берутся только если включена выгрузка файлов |
buildings | array[object] | Вложенные строки итогов по объектам строительства | Объекты строительства района |
buildings[]: объект строительства / корпус
Источник уровня: СтрокаОбъект из итогового дерева.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
id | string | XMLСтрока(СтрокаОбъект.Объект) | Уникальный идентификатор объекта строительства |
name | string | СтрокаОбъект.ОбъектНаименование = ВремНедвижимость.Объект.Наименование | Наименование объекта/корпуса |
address | string | СтрокаОбъект.СтроительныйАдрес = ПОДСТРОКА(ВремНедвижимость.Объект.СтроительныйАдрес, 1, 1000) | Строительный адрес |
floor_cnt | number/string | СтрокаОбъект.КоличествоЭтажей = ВремНедвижимость.Объект.КоличествоЭтажей | Количество этажей объекта строительства |
commissioning_period | ISO date string | ЗаписатьДатуJSON(СтрокаОбъект.СрокВводаВЭксплуатацию, ФорматДатыJSON.ISO) | Срок ввода в эксплуатацию |
construction_completion | ISO date string | ЗаписатьДатуJSON(СтрокаОбъект.СрокОкончанияСтроительства, ФорматДатыJSON.ISO) | Срок окончания строительства |
sections | array[object] | Вложенные строки итогов по секциям | Секции объекта строительства |
Разница commissioning_period и construction_completion
commissioning_period = реквизит объекта строительства СрокВводаВЭксплуатацию.
construction_completion = реквизит объекта строительства СрокОкончанияСтроительства.
По смыслу это разные даты:
construction_completion- когда строительство должно быть завершено;commissioning_period- когда объект должен быть введен в эксплуатацию.
Для сайта нельзя считать эти поля взаимозаменяемыми. Если сайтам нужен квартал/срок сдачи именно по окончанию строительства, нужно брать construction_completion. Если нужен ввод в эксплуатацию - commissioning_period.
Отдельно: в другом описательном API в коде встречается поле construction_completion_date, но в данном фиде используется именно construction_completion.
sections[]: секция
Источник уровня: СтрокаСекция из итогового дерева.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
id | string | XMLСтрока(СтрокаСекция.Секция) | Уникальный идентификатор секции |
name | string | СтрокаСекция.СекцияНаименование = ВремНедвижимость.Секция.Наименование | Наименование секции, например Секция 2 |
flats | array[object] | Вложенные строки объектов недвижимости | Лоты секции |
Отдельного поля с номером секции в текущей структуре нет. Сейчас сайт может получить номер только из name, например из строки Секция 2. Это хрупко: если наименование станет 2 секция, Блок А, Секция 2А, парсинг на сайте сломается.
Рекомендация: добавить в ПолучитьСтруктуру_Секция() отдельное поле, например number, и заполнять его из отдельного реквизита секции, если такой реквизит есть в справочнике секций. Если отдельного реквизита нет, лучше добавить его в 1С, а не парсить номер из наименования.
flats[]: объект недвижимости / лот
Источник уровня: СтрокаОН из итогового дерева.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
id | string | XMLСтрока(СтрокаОН.ОбъектНедвижимости.УникальныйИдентификатор()) | Уникальный идентификатор лота |
name | string | СтрокаОН.ОбъектНедвижимостиНаименование = ВремНедвижимость.ОбъектНедвижимости.Наименование | Наименование объекта недвижимости |
section | string | Структура_Секция.id | ID секции |
building | string | Структура_Объект.id | ID объекта строительства |
complexe | string | Структура_Район.id | ID района. Важно: ключ называется complexe, не complex |
description | string | СтрокаОН.ОбъектНедвижимостиОписание = ПОДСТРОКА(ВремНедвижимость.ОбъектНедвижимости.Описание, 1, 1000) | Описание лота |
tags | array[string] | РегистрСведений.ТегиОбъектовНедвижимости, поле Тег.Наименование | Теги объекта недвижимости |
object_type | string | СтрокаОН.ОбъектНедвижимостиВидНедвижимости = ЕСТЬNULL(ВидНедвижимости.Представление, "") | Вид недвижимости текстом |
type | string | XMLСтрока(СтрокаОН.ОбъектНедвижимостиТипНедвижимости) | Тип недвижимости ссылкой/идентификатором |
floor | number/string | СтрокаОН.Этаж | Этаж |
floor_number | number/string | СтрокаОН.НомерНаЭтаже | Номер на этаже |
number_of_object | string | СтрокаОН.НомерУсловный | Условный номер лота |
rooms_count | number/string | СтрокаОН.КоличествоКомнат | Количество комнат |
kitchen_area | number/string | СтрокаОН.ПлощадьКухни | Площадь кухни |
project_area | number/string | СтрокаОН.ОбщаяПлощадьПроектная | Общая проектная площадь |
bti_area | number/string | СтрокаОН.ОбщаяПлощадьБТИ | Общая площадь БТИ |
area | number/string | СтрокаОН.ПриведеннаяПлощадь | Приведенная площадь. Если БТИ-приведенная площадь не заполнена, берется проектная приведенная площадь |
azimut | number/string | СтрокаОН.Азимут | Азимут |
Balconies | array[object] | Табличная часть объекта недвижимости Балконы | Балконы/лоджии лота. Важно: ключ начинается с заглавной буквы |
decoration | string | XMLСтрока(СтрокаОН.ОтделкаНаименование) | Наименование отделки |
living_area | number/string | СтрокаОН.ЖилаяПлощадь | Жилая площадь. Если жилая БТИ не заполнена, берется проектная жилая площадь |
type_plan | string | XMLСтрока(СтрокаОН.ТипПланировки) | Тип планировки |
livingroom_area | number/string | СтрокаОН.ПлощадьГостиная | Площадь гостиной |
canteen_area | number/string | СтрокаОН.ПлощадьКухниБТИ | Площадь кухни БТИ; если БТИ = 0, берется ПлощадьКухни |
status_detail | string | XMLСтрока(СтрокаОН.СтатусНедвижимости) | Статус недвижимости |
object_planes | array[string] | ПланировкиСервер.ПолучитьВсеИзображения(...).ПланКвартиры | Изображения плана квартиры |
integr_planes | array[string] | ПланировкиСервер.ПолучитьВсеИзображения(...).ПланДляИнтеграций | Планировки для интеграций |
floor_planes | array[string] | ПланировкиСервер.ПолучитьВсеИзображения(...).ПланЭтажа | План этажа |
tour_3d | string | СтрокаОН.СсылкаНаPlanoplan = ЕСТЬNULL(ОбъектНедвижимости.Планировка.СсылкаНаPlanoplan, "") | Ссылка на 3D-тур / Planoplan |
cost | number/string | ФактическаяЦена.Стоимость, если вид цены равен основному виду цены | Итоговая стоимость по основному виду цены |
price | number/string | ФактическаяЦена.Цена, если вид цены равен основному виду цены | Цена за единицу площади/метр по основному виду цены |
prices | array[object] | РегистрСведений.УПДК_ФактическиеЦеныНедвижимости | Все не удаленные виды цен по лоту |
discounts | array[object] | РегистрСведений.УПДК_ФактическиеСкидкиНаценки.СрезПоследних | Скидки/наценки по лоту |
additional_properties | array[object] | Настроенные в узле обмена доп. реквизиты/сведения и их значения по лоту | Динамические доп. параметры |
feature_mortgage | boolean | ОбъектНедвижимости.Ипотека | Признак “Ипотека” |
feature_lift | boolean | ОбъектНедвижимости.лифт | Признак “Лифт” |
feature_parking | boolean | ОбъектНедвижимости.Парковка | Признак “Парковка” |
feature_security | boolean | ОбъектНедвижимости.Охрана | Признак “Охрана” |
feature_kids_zone | boolean | ОбъектНедвижимости.ДетскаяЗона | Признак “Детская зона” |
feature_gym | boolean | ОбъектНедвижимости.Спортзал | Признак “Спортзал” |
view_to_yard | boolean | ОбъектНедвижимости.ВидВоДвор | Вид во двор |
layout_replanning_possible | boolean | ОбъектНедвижимости.ВозможностьПерепланировки | Возможность перепланировки |
layout_free | boolean | ОбъектНедвижимости.СвободнаяПланировка | Свободная планировка |
layout_two_sides | boolean | ОбъектНедвижимости.КвартираНа2Стороны | Квартира на две стороны |
layout_big_bathroom | boolean | ОбъектНедвижимости.БольшаяВанная | Большая ванная |
layout_laundry | boolean | ОбъектНедвижимости.Постирочная | Постирочная |
layout_wardrobe_niche | boolean | ОбъектНедвижимости.НишаПодШкаф | Ниша под шкаф |
layout_cabinet | boolean | ОбъектНедвижимости.Кабинет | Кабинет |
metro_minutes | string/number | ОбъектНедвижимости.БлижайшееМетро | Ближайшее метро, мин. По названию реквизита это может быть не только число, нужно проверять тип в 1С |
bathroom_area_total | number/string | ОбъектНедвижимости.ПлощадьСанузлов | Общая площадь санузлов |
mall_minutes | string/number | ОбъектНедвижимости.СколькоДоТЦ | Сколько до ТЦ, мин |
school_minutes | string/number | ОбъектНедвижимости.СколькоДоШколы | Сколько до школы, мин |
compass | string | ОбъектНедвижимости.Компас | Компас/направление |
central_park_minutes | string/number | ОбъектНедвижимости.СколькоДоЦентральногоПарка | Сколько до Центрального парка, мин |
wardrobes | boolean/string | ОбъектНедвижимости.Кладовые | Кладовые. Добавлено в CRM4DEV-1575 |
ceiling_height | number/string | ОбъектНедвижимости.ВысотаПотолкаНедвижимости | Высота потолка. В origin/develop ключ корректный без пробела |
view_from_the_windows | string | Строка(ОбъектНедвижимости.ВидИзОкон) | Вид из окон. Добавлено в CRM4DEV-1575 |
side | string | Строка(ОбъектНедвижимости.Сторона) | Сторона света/сторона. Добавлено в CRM4DEV-1575 |
Balconies[]
Источник: табличная часть объекта недвижимости Балконы.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
type | string | XMLСтрока(Строка_Балкон.ТипБалкона) | Тип балкона/лоджии |
square_meters | string | XMLСтрока(Строка_Балкон.ПлощадьБалкона) | Площадь балкона/лоджии |
prices[]
Источник: РегистрСведений.УПДК_ФактическиеЦеныНедвижимости.
В массив попадают все цены по объекту недвижимости, где вид цены не помечен на удаление.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
price_type_id | string | XMLСтрока(ФактическаяЦена.ВидЦены) | ID вида цены |
price_name | string | ФактическаяЦена.ВидЦеныНаименование | Наименование вида цены |
price | number/string | ФактическаяЦена.Цена | Цена |
cost | number/string | ФактическаяЦена.Стоимость | Стоимость |
Важно по корневым полям price и cost лота: они заполняются не первой ценой из массива, а только той строкой, где ФактическаяЦена.ВидЦены = УПДК_ЦенообразованиеПовтИсп.ПолучитьОсновнойВидЦены(). Если такого вида цены нет среди фактических цен, корневые price и cost останутся пустыми, но массив prices[] может быть заполнен.
discounts[]
Источник: РегистрСведений.УПДК_ФактическиеСкидкиНаценки.СрезПоследних(&Дата, ).
Дополнительные условия:
- берется последний проведенный документ
УПДК_РасчетФактическихСкидокНаценок; - не выгружаются скидки/наценки с признаком
СкидкаНаценка.НеВыгружатьНаСайт; - блок работает, если включена константа
ИспользоватьУправляемыеСкидкиНаценки.
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
promotion_id | string | XMLСтрока(Скидка.МаркетинговаяКампания) | ID маркетинговой кампании |
discount_name | string | Скидка.СкидкаНаценкаНаименование | Наименование скидки/наценки |
discount_id | string | XMLСтрока(Скидка.СкидкаНаценка) | ID скидки/наценки |
amount | number/string | Скидка.Сумма | Сумма скидки/наценки |
extra_charge | boolean | Скидка.ЭтоНаценка | true, если это наценка; false, если скидка |
additional_properties[]
Это не резерв “на будущее”. Массив реально заполняется текущим кодом.
Логика такая:
- В узле плана обмена
Дев_ОбменССайтомОнлайнесть табличная частьДополнительныеРеквизитыСведенияс синонимомДополнительные свойства. - В этой табличной части выбираются свойства из плана видов характеристик
ДополнительныеРеквизитыИСведения. - При формировании фида код берет только те свойства, которые указаны в этом узле обмена.
- Значения берутся из двух источников: -
Справочник.УПДК_ОбъектыНедвижимости.ДополнительныеРеквизиты, если свойство является дополнительным реквизитом; -РегистрСведений.ДополнительныеСведения, если свойство является дополнительным сведением. - В фид попадает строковое представление значения:
Строка(ОписаниеСвойства.Значение).
Структура элемента:
| JSON-поле | Тип | Источник 1С | Значение |
|---|---|---|---|
type | string | Строка(ОписаниеСвойства.СвойствоТипЗначения) | Тип значения свойства в 1С |
id | string | XMLСтрока(ОписаниеСвойства.Свойство) | ID свойства |
name | string | ОписаниеСвойства.СвойствоЗаголовок | Заголовок свойства |
value | string | Строка(ОписаниеСвойства.Значение) | Значение свойства строкой |
Пример:
{
"additional_properties": [
{
"type": "Число",
"id": "...",
"name": "Площадь террасы",
"value": "12,5"
},
{
"type": "Булево",
"id": "...",
"name": "Терраса",
"value": "Да"
}
]
}
Следствие для сайтовиков: состав additional_properties[] не фиксированный в коде. Он зависит от настройки конкретного узла обмена. Если в узел добавили свойство Погреб, Теплый балкон, Номер парковки, Площадь террасы и у лота есть значение, оно попадет в этот массив. Если свойство не добавлено в узел обмена, оно не выгрузится, даже если заполнено в карточке объекта недвижимости.
Важные нюансы контракта
complexeнаписано с буквойeна конце. Это текущее имя поля в фиде. Если сайт ожидаетcomplex, потребуется отдельное изменение контракта.Balconiesначинается с заглавной буквы. Это текущее имя поля в фиде.- В
sections[]нет отдельного номера секции. Есть толькоidиname. additional_properties[]динамический и зависит от настройки узла обмена.- Часть числовых значений может сериализоваться как число, а часть как строка, потому что в коде местами используется
XMLСтрока(...)илиСтрока(...). - Даты
commissioning_periodиconstruction_completionсериализуются черезЗаписатьДатуJSON(..., ФорматДатыJSON.ISO). description,address,imagesи часть файлов ограничиваютсяПОДСТРОКА(..., 1, 1000)в запросах.
1. commissioning_period и construction_completion: в чем разница?
commissioning_period - срок ввода объекта строительства в эксплуатацию, источник ОбъектСтроительства.СрокВводаВЭксплуатацию.
construction_completion - срок окончания строительства, источник ОбъектСтроительства.СрокОкончанияСтроительства.
Если сайт определяет “квартал сдачи корпуса”, нужно согласовать бизнес-смысл: ввод в эксплуатацию или окончание строительства. По названию “срок сдачи/окончание строительства” чаще подходит construction_completion, но текущие сайты уже могут использовать commissioning_period, поэтому менять интерпретацию без миграции нельзя.
2. Можно ли получать номер секции отдельным полем?
В текущем фиде отдельного поля номера секции нет. Есть только:
{
"id": "...",
"name": "Секция 2",
"flats": []
}
Получать номер из name технически можно, но это ненадежно. Рекомендуемое изменение: добавить в секцию поле number, например:
{
"id": "...",
"name": "Секция 2",
"number": "2",
"flats": []
}
Источник должен быть отдельным реквизитом секции. Если такого реквизита нет, его лучше добавить в 1С. Парсинг из наименования лучше не использовать как постоянное решение.
3. Что может попадать в additional_properties у лота?
В additional_properties попадают только свойства, настроенные в конкретном узле обмена в табличной части Дополнительные свойства (ДополнительныеРеквизитыСведения). Значения берутся из дополнительных реквизитов/сведений объекта недвижимости.
Это массив для динамических полей, которые не являются фиксированной частью JSON-контракта. Например, туда могут попадать Погреб, Терраса, Площадь террасы, Теплый балкон, Номер парковки, если они заведены как дополнительные реквизиты/сведения, добавлены в узел обмена и заполнены у объекта недвижимости.