
При работе с Bitrix24 понадобилось сохранить адрес из Google Maps в стандартное поле Address у лида. Не просто строку, а полноценный адрес: с координатами, разбивкой на части и корректной работой всей CRM-логики.
REST API рассматривался первым, но быстро стало ясно, что в этом сценарии неудобен. Нужно было переносить адрес между сущностями Bitrix24, сохраняя связи с модулем location. REST такого контроля не даёт.
При этом в Bitrix24 уже есть стандартное поле address, связанное с Google Maps и модулем location. Оно умеет хранить координаты и структуру адреса, но в документации нет описания, как правильно заполнять его через код.
В статье разберу практический кейс: как сохранить адрес из Google Geocode во внутренние сущности Bitrix24 без REST API и без пользовательского интерфейса.
Почему стандартное поле Address сложно заполнить из кода
На первый взгляд поле Address в Bitrix24 выглядит готовым к использованию. Оно уже связано с Google Maps, умеет хранить координаты и красиво отображается в интерфейсе.
Но стоит попробовать заполнить его из кода, и начинаются сюрпризы. Простая запись текстового значения даёт только визуальный эффект. Адрес показывается, но связи с модулем location нет. Координаты не сохраняются. Структура адреса разваливается. Внутренние связи либо отсутствуют, либо выглядят странно.
Дело в том, что Address — это не одно поле. Это набор связанных сущностей и таблиц. Если заполнить их не полностью или не в том порядке, адрес перестаёт быть «живым». Он не участвует в логике CRM, его нельзя безопасно переносить между сущностями и использовать повторно.
При этом официальная документация никак не помогает. Там просто нет описания, какие сущности трогать и в какой последовательности, если нужен полноценный адрес, а не просто текст.
Как на самом деле хранится адрес в Bitrix24
Поле Address — это связка нескольких сущностей. При корректном сохранении они выглядят примерно так:

b_location— хранитexternalIdиз Google Geocode и координатыb_location_address— основная сущность адресаb_location_addr_fld— разбивка адреса на частиb_location_addr_link— связь адреса с сущностьюb_crm_addr— связь адреса с CRM
Если не создать все эти записи, поле Address работает только наполовину. Простая запись строки не создаёт адрес в понимании Bitrix24.
Что нужно получить в итоге
С самого начала было важ��о понять, какой результат считается правильным. Речь шла не просто о заполненном поле, а о полноценной интеграции с модулем location и CRM-логикой.
В итоге адрес должен:
хранить
latitudeиlongitudeиз Google Geocodeбыть связан с локацией и её родителями
иметь разбивку на компоненты
спокойно переноситься между сущностями Bitrix24
работать как стандартное поле
Addressв карточке лида
И важный момент: после сохранения адрес должен без ограничений редактироваться через интерфейс, так же, как если бы его ввёл пользователь вручную.
Какие сущности участвуют в сохранении адреса
Для этого используется внутреннее API модулей location и CRM. По факту задействованы три ключевые сущности.
1. Bitrix\Location\Entity\Location
Location хранит информацию о самой локации. Здесь лежат источник данных, внешний идентификатор, координаты и тип.
При работе с Google Maps сюда передаются:
externalIdиз Google Geocodeисточник (
GOOGLE)тип локации
координаты
язык
Пример инициализации:
$location = (new Location()) ->setExternalId(...) ->setLatitude(...) ->setLongitude(...);
2. Разбивка адреса на части (fieldsCollection)
Компоненты адреса Bitrix24 хранит в виде числовых типов. Их нужно маппить вручную.
Пример соответствия компонентов Google и типов Bitrix24:
protected const LOCATION_FIELD_MAP = [ 'postal_code' => 50, 'country' => 100, 'administrative_area_level_1' => 200, 'administrative_area_level_2' => 210, 'locality' => 310, 'route' => 340, 'street_number' => 400, 'full_address' => 410, ]; $location->setFieldValue($itemType, $itemValue);
Эти данные попадают в таблицу b_location_addr_fld и формируют структурированный адрес.
3. Bitrix\Location\Entity\Address
Address связывает локацию, координаты и компоненты адреса. Именно эта сущность делает адрес полноценным.
При создании:
задаются координаты
указывается
Locationзаполняются компоненты
создаётся связь с CRM
Пример:
$address = (new Address()) ->setLatitude(...) ->setLongitude(...) ->setLocation(...); $address->addLink('1.1.' . $leadId, 'CRM_LEAD_ADDRESS'); foreach ($fieldCollection as $itemType => $itemValue) { $address->setFieldValue($itemType, $itemValue); }
4. CRM-сущность \Bitrix\Crm\EntityAddress
На финальном шаге адрес регистрируется в CRM и привязывается к лиду.
$addressFields = [ 'ADDRESS_1' => $parts['address1'], 'ADDRESS_2' => $parts['address2'], 'CITY' => $parts['city'], 'REGION' => $parts['state'], 'PROVINCE' => $parts['province'], 'POSTAL_CODE' => $parts['zip'], 'COUNTRY' => $parts['country'], 'COUNTRY_CODE' => $parts['country_code'], 'LOC_ADDR_ID' => $address->getId(), ]; \Bitrix\Crm\EntityAddress::register( \CCrmOwnerType::Lead, $leadId, \Bitrix\Crm\EntityAddressType::Primary, $addressFields );
Адрес считается сохранённым корректно только после этого шага. Если его пропустить, CRM просто не увидит адрес.
Полный пример кода лежит здесь: https://github.com/RogSC/bitrix-address-api
Получение данных из Google Geocode
Для координат и компонентов используется Google Geocode API. Важно, чтобы данные легко ложились в модель Bitrix24.
Здесь используется серверный ключ, который уже настроен в модуле location Bitrix24. Это избавляет от дублирования конфигурации.
Получение API-ключа
function getApiKey(): string { $sourceService = \Bitrix\Location\Service\SourceService::getInstance(); $source = $sourceService->getSource(); $config = $source->getConfig(); return $config->getValue('API_KEY_BACKEND'); }
Используется тот же ключ, что и в интерфейсе CRM.
Вызов Google Geocode API
const URL = 'https://geocode.googleapis.com/v4beta/geocode/address/'; $httpClient = new \Bitrix\Main\Web\HttpClient([ 'version' => '1.1', 'socketTimeout' => 30, 'streamTimeout' => 30, 'redirect' => true, 'redirectMax' => 5, ]); $httpClient ->setHeader('Referer', 'https://crm.example.com/') ->setHeader('Content-Type', 'application/json') ->setHeader('X-Goog-Api-Key', getApiKey()); function geocodeAddress(string $address): array { $url = self::URL . urlencode($address); $response = $httpClient->get($url); return Json::decode($response); }
На выходе — координаты, placeId и компоненты адреса.
Последовательность сохранения адреса
Порядок здесь критичен. Если его нарушить, связи ломаются.
Общая схема такая:
Создать
LocationЗаписать компоненты адреса
Создать
AddressЗарегистрировать адрес в CRM
Шаг 1. Location
$location = (new Location()) ->setExternalId((string)$data['externalId']) ->setSourceCode('GOOGLE') ->setType(Location\Type::ADDRESS_LINE_1) ->setName($data['name']) ->setLanguageId('en') ->setLatitude($data['latitude']) ->setLongitude($data['longitude']);
Шаг 2. Компоненты адреса
foreach ($fieldCollection as $itemType => $itemValue) { $location->setFieldValue($itemType, $itemValue); } $location->save();
Шаг 3. Address
$address = (new Address('en')) //languageId ->setLatitude($parts['lat']) ->setLongitude($parts['lon']) ->setLocation($location); $address->addLink('1.1.' . $leadId, 'CRM_LEAD_ADDRESS'); foreach ($fieldCollection as $itemType => $itemValue) { $address->setFieldValue($itemType, $itemValue); } $address->save();
Шаг 4. Регистрация в CRM
\EntityAddress::register( \CCrmOwnerType::Lead, $leadId, \Bitrix\Crm\EntityAddressType::Primary, [ 'ADDRESS_1' => $parts['address1'], 'ADDRESS_2' => $parts['address2'], 'CITY' => $parts['city'], 'REGION' => $parts['state'], 'PROVINCE' => $parts['province'], 'POSTAL_CODE' => $parts['zip'], 'COUNTRY' => $parts['country'], 'COUNTRY_CODE' => $parts['country_code'], 'LOC_ADDR_ID' => $address->getId(), ] );
После этого адрес полностью работает в CRM.
Проверка результата
Проверить всё можно двумя способами: в базе и в интерфейсе.
b_location
Там появляется запись с EXTERNAL_ID, источником GOOGLE и координатами.
b_location_addr_fld
Здесь видно, что адрес реально разложен по частям, а не хранится одной строкой.
Связи с CRM
В b_crm_addr появляется связь с CRM-сущностью и LOC_ADDR_ID.
Карточка лида
В интерфейсе адрес выглядит как обычное поле Address. Его можно редактировать, Google Maps работает как обычно.

Подводные камни
Есть несколько моментов, о которых лучше знать заранее.
Зависимость от внутреннего API
Сущности не публичные. Обновления Bitrix24 могут что-то сломать.
Порядок важен
Нарушил последовательность — потерял связи.
Типы полей (b_location_addr_fld)
Ошибся в маппинге — адрес выглядит нормально, но структура не сохраняется.
ЯзыкlanguageId влияет на нормализацию адреса.
Google API
Следи за лимитами, особенно при массовой обработке.
Итоги
Поле Address в Bitrix24 — это не текст, а набор связанных сущностей. Чтобы заполнить его корректно, нужно работать с внутренним API и соблюдать порядок действий.
Этот подход позволяет сохранить адрес из Google Geocode полностью: с координатами, структурой и рабочей интеграцией с CRM. Адрес ведёт себя так же, как введённый вручную.
Решение не использует REST API и оправдано в сценариях, где важно сохранить все связи и переносить адреса между сущностями. Для простых задач REST может быть проще.
Код с минимальной реализацией лежит в репозитории: https://github.com/RogSC/bitrix-address-api