Когда магазин на Тильде растёт из одного города в область или доставляет в разные районы с разной стоимостью, встроенных настроек конструктора почти всегда не хватает. Зоны доставки в Тильде из коробки - это плоский список: либо фиксированная цена, либо бесплатно от суммы заказа, без привязки к конкретному адресу. Разбивку по районам, разный тариф для центра и окраины, проверку введённого адреса приходится собирать руками поверх стандартной формы. Ниже - рабочие способы, которые я применял на реальных проектах: от простой группировки в блоке оплаты до кастомного JS-скрипта с подсказками DaData и валидацией.
Зачем разбивать доставку на зоны в Тильде
Без разбивки по зонам магазин либо теряет деньги на дальних заказах (фиксированная цена не покрывает выезд курьера за МКАД или в промзону), либо отпугивает клиентов из ближних районов завышенным тарифом «по больнице». На практике разница в стоимости доставки между соседними районами одного города доходит до 150-300 ₽, а сроки - от 2 часов в пределах центра до суток на окраину. Если это не показать клиенту до оплаты, будет либо отказ от заказа на этапе оплаты, либо звонок в поддержку с вопросом «а что это у меня доставка 500 рублей».
Вторая причина - логистика. Курьерская служба или свой водитель работают по маршрутам, и если зона доставки не зашита в форму, оператор вручную сверяет адрес с картой районов при каждом заказе. На объёме 20-30 заказов в день это час-полтора работы менеджера впустую, и это как раз тот случай, когда 3-5 тысяч рублей на кастомный скрипт отбиваются за первую неделю.
Способы настроить зоны доставки в Tilda
В Tilda есть три уровня, на которых можно решить задачу, и я обычно комбинирую их в зависимости от бюджета и сложности проекта.
Встроенные зоны в блоках Zero Block и “Оплата”
Самый простой вариант - блок T‑Cart или T‑Form с полем выбора способа доставки, где вручную прописаны варианты: “Доставка по центру - 300 ₽”, “Доставка по области - 600 ₽”. Это работает, если у вас 2-4 зоны и клиент сам в состоянии определить, к какой относится его адрес. Плюс - настраивается за 10 минут без единой строчки кода. Минус - клиент ошибается с выбором, и часть заказов уходит с неверной ценой доставки, что потом разгребает менеджер.
Зоны по почтовому индексу или ключевым словам в адресе
Среднее решение - скрипт, который слушает поле адреса и сверяет введённый текст со списком районов или индексов через простое совпадение подстроки. Работает без API карт, но требует поддерживать список районов руками, и если клиент напишет “Юго-Западная” вместо “р‑н Юго-Западный”, зона не определится.
Геокодинг и полигоны зон через API карт
Самый точный вариант - определение зоны по координатам через Яндекс.Карты API или DaData: адрес превращается в координаты, координаты проверяются на попадание в заранее заданный полигон района. Это единственный способ, который не ошибается на неоднозначных адресах и работает даже если клиент ввёл адрес без указания района вообще. Сложность внедрения выше, но именно так я делаю доставку для клиентов с 8+ зонами и разной ценой в каждой.
| Способ | Точность | Трудозатраты | Когда использовать |
|---|---|---|---|
| Ручной выбор зоны клиентом | Низкая | Минимальные | 2-4 зоны, простой магазин |
| Совпадение по ключевым словам/индексу | Средняя | Скрипт + поддержка списка | 5-10 зон, стабильные названия районов |
| Геокодинг + полигоны | Высокая | Разработка + подключение API | От 8 зон, доставка в область, нестандартные адреса |
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Подсказки адреса и геокодинг через DaData
Для точной привязки к зоне адрес нужно сначала нормализовать - клиенты пишут “мск, ленинский 15” или “г. Москва Ленинский пр‑т д.15”, и без подсказок это два разных района с точки зрения тупого сравнения строк. DaData даёт автодополнение адреса с возвратом структурированных данных: город, район, улица, дом, а также координаты - то, что нужно для проверки попадания в полигон зоны.
Подключение простое: на инпут адреса вешается обработчик, который при вводе от трёх символов дёргает DaData suggestions API и подставляет варианты в выпадающий список под полем. Из ответа API берётся data.geo_lat, data.geo_lon и data.city_district - либо по названию района сразу определяем зону, либо по координатам считаем попадание в полигон.
async function getSuggestions(query) {
const res = await fetch('https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + DADATA_API_KEY
},
body: JSON.stringify({ query, count: 5 })
});
const json = await res.json();
return json.suggestions;
}
document.querySelector('#address-input').addEventListener('input', async (e) => {
if (e.target.value.length 3) return;
const suggestions = await getSuggestions(e.target.value);
renderDropdown(suggestions);
});
Ключ DaData я обычно храню не в самом JS-коде на странице (он виден в исходнике любому), а получаю через прокси-эндпоинт на своём сервере, чтобы не светить токен и не упираться в лимиты бесплатного тарифа раньше времени.
Проверка ввода адреса: маска, обязательные поля, валидация
Подсказки закрывают только часть проблемы - клиент может проигнорировать выпадающий список и ввести адрес руками с опечаткой или вообще без дома. Проверка ввода в форме доставки на Тильде держится на трёх вещах.
Первое - обязательность выбора именно из списка подсказок, а не свободного текста. Если поле осталось “грязным” (не выбран пункт из списка DaData), при сабмите формы показываю предупреждение и блокирую отправку - это сокращает долю заказов с недоставляемым адресом почти до нуля.
Второе - проверка структуры адреса на наличие обязательных частей: город, улица, номер дома. DaData возвращает это в объекте data, и если поле house пустое, значит адрес неполный - просить клиента уточнить прямо в форме дешевле, чем потом звонить.
Третье - маска и ограничение символов для полей телефона и квартиры/подъезда, чтобы в базу не улетали случайные строки вроде “позвоните за час” в поле “квартира”. В Tilda это делается через атрибут pattern на инпуте плюс JS-валидацию перед отправкой формы, потому что нативный pattern без скрипта в кастомных полях Zero Block иногда игнорируется.
Стоимость и сроки доставки по зонам: расчёт на лету
Когда зона определена, дальше нужно сразу показать клиенту цену и срок, не дожидаясь оформления заказа - это снижает число брошенных корзин на этапе оплаты. Логика простая: массив зон с ценой и сроком, поиск по коду зоны, который вернул геокодер, вывод результата в блок рядом с адресом.
const ZONES = {
center: { price: 250, days: '2-4 часа' },
mid: { price: 400, days: 'в течение дня' },
outskirts: { price: 600, days: 'на следующий день' },
region: { price: 900, days: '1-2 дня' }
};
function applyZone(zoneCode) {
const zone = ZONES[zoneCode];
if (!zone) {
document.querySelector('#delivery-result').textContent = 'Уточните адрес, зона не определена';
return;
}
document.querySelector('#delivery-result').textContent =
`Доставка: ${zone.price} ₽, срок: ${zone.days}`;
}
На паре проектов я собирал полигоны зон вручную через Яндекс.Карты Конструктор - рисуется контур района, координаты вершин сохраняются в тот же объект ZONES, а проверка попадания точки в полигон делается через простой алгоритм ray casting на клиенте, без лишних запросов к серверу на каждое движение мышкой по карте. Готовый шаблон такого скрипта под конкретный город обычно быстрее адаптировать, чем писать заново, поэтому часть таких решений я выкладываю в библиотеке готовых скриптов для Тильды - можно взять за основу и подставить свои районы и тарифы.
Интеграция с СДЭК и передача заказа курьеру
Если доставка за пределами своей зоны идёт через СДЭК, к настройке районов добавляется ещё один слой - расчёт стоимости через API СДЭК по коду пункта выдачи или адресу, плюс синхронизация статусов заказа. На практике эта связка обычно выглядит так: в своей зоне - фиксированные тарифы и свои курьеры, за её пределами - расчёт через СДЭК с реальной стоимостью на момент оформления, потому что фиксированная цена для “остальной России” либо занижена, либо завышена почти всегда.
Передача заказа в СДЭК или другую курьерскую службу после оформления в Тильде делается через вебхук Tilda → серверный обработчик → API службы доставки. Здесь же обычно подключают уведомления в Telegram для менеджера о новом заказе с указанием зоны - простой aiogram-бот с одной командой на приём вебхука закрывает эту задачу без отдельной админки. Для магазинов с 50+ заказами в день такую связку разумнее собирать через n8n - визуальный конструктор сценариев избавляет от написания и поддержки отдельного сервера под каждый вебхук.
Сложность и стоимость такой интеграции сильно зависит от количества служб доставки и CRM на другом конце: разовая доработка вроде добавления одной зоны или поля в форму - от 3 000 ₽, а комплексная интеграция с СДЭК, эквайрингом и CRM - от 40 000 ₽. Если нужна отдельная автоматизация цепочки без готовой формы Тильды - разработка на заказ под конкретный процесс обычно закрывает вопрос быстрее, чем попытки собрать всё через стандартные блоки конструктора.
Когда стандартных блоков не хватает
Кастомный скрипт
от 3 000 ₽
Подробнее →Частые вопросы
Можно ли настроить зоны доставки в Тильде без программиста?
Для 2-4 зон с ручным выбором клиента - да, через стандартный блок оплаты с вариантами доставки. Как только нужна привязка к конкретному адресу, проверка полигонов районов или интеграция с курьерской службой, без кастомного скрипта или бэкенда не обойтись - конструктор такие сценарии из коробки не покрывает.
Какой API лучше использовать для определения района по адресу - DaData или Яндекс.Карты?
DaData удобнее для подсказок при вводе и получения структурированных данных об адресе (район, дом, координаты) в одном запросе. Яндекс.Карты API я обычно подключаю отдельно для отрисовки полигонов зон на карте и визуальной проверки попадания точки. На практике связка из двух сервисов даёт точный результат без лишних затрат - DaData закрывает базовую нормализацию адреса, карта нужна только там, где важна визуализация.
Что делать, если клиент ввёл адрес вне зоны доставки?
Показывать сообщение сразу после определения зоны, до перехода к оплате, с вариантами: самовывоз, доставка через стороннюю службу по расчётной цене или контакт с менеджером. Молчаливая блокировка кнопки “Оформить” без объяснения причины - частая ошибка, из-за которой клиент просто уходит, не поняв, что не так.
Как проверить, что зоны доставки и валидация адреса реально работают после публикации сайта?
Тестирую на пограничных адресах - тех, что формально на границе двух районов, и на заведомо неполных (без номера дома, с опечаткой в улице). Отдельно проверяю поведение на мобильных - часть автодополнений и обработчиков ввода ведёт себя иначе на тач-экранах, особенно при автозаполнении браузером.