Собираю форму заказа с несколькими товарами в Tilda для интернет-магазинов и услуг, где клиент выбирает не одну позицию, а сразу список: несколько SKU, разные варианты одного товара, комплект услуг с разным количеством. Штатная форма Tilda для этого не предназначена, и большинство проблем у клиентов начинаются именно с попытки впихнуть корзину в обычный Zero Block.
По теме статьи
Готовое решение
Подарочные сертификаты Тильда без процента с продаж
Покупатель оплачивает сертификат как обычный товар, получает код на почту и гасит его в корзине. Работает на вашем хостинге, без процента с продаж.
от30 000 ₽
Кастомный скрипт
Когда стандартных блоков не хватает
Доработка сайтов на Тильде: скрипты для корзины, промокоды, зоны доставки, интеграции с CRM и Telegram. Простой скрипт от 3 000
от3 000 ₽
Почему стандартная форма Тильды не годится для заказа нескольких товаров
Обычная форма в Tilda работает по одной простой логике: пользователь заполняет поля, жмёт «Отправить», данные улетают одним пакетом в письмо, CRM или Google Таблицу. Она не хранит состояние между блоками страницы и не умеет накапливать позиции. Если на странице десять товаров с кнопками «Добавить», а форма заказа одна и находится внизу, без дополнительного скрипта эти кнопки друг с другом не связаны никак.
На практике это выглядит так: клиент присылает бриф «нужна корзина», подключает T‑store (Tilda Ecommerce), а через неделю оказывается, что часть позиций - услуги без веса и артикула, часть - товары с вариантами по цвету и размеру, и штатная логика каталога под это не подстраивается. Разбираться, что можно закрыть встроенными средствами, а что придётся дописывать руками, лучше на старте, а не после того, как форма уже собрана криво.
Корзина Tilda Ecommerce: когда встроенного решения хватает
Если у вас однородный каталог - обычные товары с ценой, артикулом и остатком, без сложной логики выбора комплекта - включённого в Tilda модуля Ecommerce обычно достаточно. Он даёт корзину, синхронизацию остатков, применение промокодов и передачу заказа с несколькими позициями в CRM через штатные вебхуки.
Проблемы начинаются, когда нужно что-то за пределами стандартной модели: подарочная упаковка как отдельная опция, скидка за количество, разные способы доставки для разных категорий товаров в одном заказе, произвольные текстовые поля к каждой позиции (например, «текст для гравировки»). Всё это либо не поддерживается из коробки, либо поддерживается частично и требует докрутки через API Tilda.
| Критерий | Tilda Ecommerce | Кастомная форма на JS |
|---|---|---|
| Каталог и остатки | Готовая синхронизация | Нужно подключать вручную (API, Google Sheets, 1С) |
| Произвольные поля к позиции | Ограничено настройками карточки | Любые: текст, файл, чекбокс, выпадающий список |
| Заказ услуг вперемешку с товарами | Плохо совместимо | Настраивается без ограничений |
| Доработка под нестандартный сценарий | Не требуется для типовых магазинов | От 3 000 ₽ за простую форму, от 40 000 ₽ за интеграцию с CRM и эквайрингом |
Для классического магазина с десятками SKU я обычно рекомендую остаться на Ecommerce и донастроить только точечные вещи. Для лендинга с услугами, комплектами или B2B-заказом, где логика выбора нестандартная, проще и дешевле в итоге написать форму с нуля на JS, чем гнуть каталог под чужую задачу.
Кастомная форма заказа на JS: как я собираю список товаров
Логика простая: у каждой карточки товара своя кнопка «В заказ», нажатие пишет объект (название, цена, количество) в массив в памяти страницы, при отправке формы массив превращается в JSON и уходит одним скрытым полем вместе с остальными данными клиента.
let order = [];
function addToOrder(name, price) {
const existing = order.find(item => item.name === name);
if (existing) {
existing.qty += 1;
} else {
order.push({ name, price, qty: 1 });
}
renderOrder();
}
function renderOrder() {
const total = order.reduce((sum, i) => sum + i.price * i.qty, 0);
document.querySelector('#order-total').innerText = total + ' ₽';
document.querySelector('#order-hidden').value = JSON.stringify(order);
}
document.querySelectorAll('.add-btn').forEach(btn => {
btn.addEventListener('click', () => {
addToOrder(btn.dataset.name, Number(btn.dataset.price));
});
});
Скрытое поле order-hidden добавляю прямо в форму Zero Block через настройку «Добавить поле» и вешаю на него уникальное имя, чтобы оно нормально долетало в письмо и в вебхук. На стороне CRM или в письме получаю строку JSON, которую менеджер видит как читаемый список, если предварительно прогнать её через простую подстановку в шаблон письма.
Бесплатный материал
🎁 Полезный скрипт в подарок
Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.
Без спама. Отписка в 1 клик.
Отдельно слежу за лимитом: Tilda обрезает длинные значения в некоторых интеграциях, поэтому при заказе из 15-20 позиций лучше не сериализовать весь массив в одно поле, а параллельно писать краткую сводку («Товар А x2, Товар Б x1») в отдельное текстовое поле - на случай, если JSON придётся вручную парсить в CRM.
Расчёт стоимости и доставки для нескольких товаров
С суммой заказа всё просто - суммируется цена по количеству прямо в браузере, как в примере выше. Сложнее с доставкой, потому что стоимость СДЭК или почты зависит от суммарного веса и габаритов всех позиций, а не одной штуки. Здесь я обычно иду одним из двух путей.
Первый - если товаров немного и разброс весов небольшой, забиваю фиксированные тарифы по зонам прямо в скрипт формы и пересчитываю доставку на лету при каждом добавлении товара в заказ. Для типовых магазинов этого хватает, и как раз для такой задачи у меня есть готовый скрипт зон доставки для Tilda, который подставляет цену зоны по адресу клиента на Яндекс.Карте без обращения к внешнему API и блокирует оформление вне покрытия.
Второй вариант - когда вес и габариты действительно разные и нужен точный расчёт - дёргаю API СДЭК через промежуточный сервер (напрямую с фронта Tilda это не сделать из-за CORS и ключей доступа). На бэкенде суммирую вес всех позиций из заказа, отправляю запрос в СДЭК на расчёт тарифа по индексу получателя и возвращаю сумму обратно в форму через fetch. Для таких связок часто использую n8n: вебхук принимает заказ с фронта, обращается к API СДЭК и к каталогу остатков, и возвращает готовый расчёт за секунды.
Интеграция с оплатой и CRM при заказе из нескольких позиций
Тут есть нюанс, который многие упускают: по 54-ФЗ чек должен содержать список позиций с ценами, а не общую сумму заказа. Если оплата идёт через T‑Bank (бывший Тинькофф эквайринг) или другую платёжную систему с фискализацией, в запрос на создание платежа нужно передавать массив товаров - тот же самый, что собрался в скрытом поле формы, только преобразованный в структуру, которую ждёт API эквайринга (наименование, количество, цена, ставка НДС).
С CRM ситуация похожая. В amoCRM или Bitrix24 список товаров удобнее всего заводить не текстом в примечании, а через сущность «Товары в сделке» - тогда менеджер видит нормальную таблицу позиций, а не JSON-простыню. Вебхук из формы Tilda я обычно направляю в n8n или на свой промежуточный сервер, который раскладывает массив заказа по нужным полям CRM и параллельно шлёт уведомление менеджеру в Telegram через aiogram-бота, чтобы заказ не потерялся среди почты.
Клиентские данные (телефон, адрес, ФИО) в таких связках храню на серверах в РФ, а не во внешних облачных таблицах - это требование 152-ФЗ по локализации персональных данных, и для магазина с реальными заказами это не формальность.
Частые ошибки при настройке формы с несколькими товарами
- Скрытое поле с JSON не очищается после отправки - при повторном заказе в ту же сессию к новому заказу прилипают позиции из прошлого
- Нет валидации минимального количества - можно отправить заказ с товаром, у которого qty равно нулю, потому что кнопку «плюс» нажали и тут же «минус»
- Расчёт доставки не учитывает изменение состава заказа - сумма к оплате в форме не совпадает с тем, что приходит в CRM
- Для эквайринга передаётся общая сумма заказа без разбивки по позициям - чек не проходит фискализацию или формируется некорректно
- Длинный список товаров не помещается на мобильном экране - форма без ограничения высоты и скролла внутри блока корзины превращается в нечитаемую портянку
Каждая из этих ошибок по отдельности не критична, но вместе они дают заказы, которые не бьются между фронтом, платёжкой и CRM, и в итоге менеджер разбирает несостыковки руками.
Частые вопросы
Можно ли сделать корзину с несколькими товарами на Tilda без программиста?
Через встроенный Tilda Ecommerce, да, если каталог однородный и не нужны нестандартные поля к позициям. Как только появляются комплекты, услуги вперемешку с товарами или сложный расчёт доставки, без кастомного скрипта форма начинает вести себя нестабильно.
Сколько товаров можно добавить в одну заявку через кастомную форму
Технических ограничений на количество позиций в массиве нет, но у некоторых интеграций Tilda есть лимит по длине значения скрытого поля. На практике для заказов от 15-20 позиций я дополнительно передаю краткую текстовую сводку параллельно с JSON, чтобы данные точно дошли в письмо и CRM.
Как передать список товаров в T‑Bank для формирования чека с несколькими позициями
Нужно на бэкенде преобразовать массив заказа в формат, который ожидает API эквайринга: массив объектов с наименованием, количеством, ценой и ставкой НДС по каждой позиции. Напрямую с фронта Tilda это сделать нельзя, требуется промежуточный сервер или сценарий в n8n между формой и платёжным шлюзом.
Как считать доставку СДЭК, если в заказе товары разного веса
Складывать вес всех позиций заказа и отправлять запрос на расчёт тарифа через API СДЭК с промежуточного сервера, потому что напрямую из браузера обратиться к API не получится из-за CORS и закрытых ключей доступа. Для магазинов с фиксированными зонами доставки проще и быстрее считать тариф локальным скриптом без обращения к внешнему API.