Заказы с Tilda, InSales и самописного сайта в 1С без ручного ввода: контур, сопоставление, идемпотентность
Заказ на сайте оформлен за минуту. В 1С он появляется вечером — когда менеджер или бухгалтер откроет админку, найдёт новые заказы и перенесёт их руками: покупатель, телефон, позиции, цены, скидка, доставка. Если заказов десять в день, это терпимо. Если сорок — это уже отдельная работа, у которой нет строки в бюджете, зато есть ошибки и задержка.
Я проектирую интеграции 1С с внешними системами: сайтами, CRM, своими программами заказчиков. Ниже — как я бы устроил загрузку заказов с сайта в 1С, если сайт сделан на Tilda, InSales или написан с нуля. Это не пересказ документации платформ (она меняется, читайте первоисточник), а то, из каких частей состоит контур на стороне 1С и где обычно спотыкаются. Код — упрощённые примеры для статьи.
Почему «просто выгрузить заказы» не работает
Первая мысль — взять выгрузку заказов в CSV и загружать её обработкой раз в день. Это лучше, чем ручной ввод, но три проблемы остаются:
задержка никуда не делась: склад по-прежнему видит заказ на следующий день;
повторная загрузка того же файла создаёт дубли, если обработка не умеет их узнавать;
всё, что не сопоставилось, падает целиком или, хуже, молча создаёт «новую» номенклатуру и «нового» контрагента.
Поэтому дальше речь пойдёт не о файле, а о контуре: заказ попадает в 1С в момент оформления (или с небольшой задержкой), повторная доставка не создаёт дубль, а всё непонятное ложится в очередь разбора, а не в справочники.
Контур целиком
Сайт (Tilda / InSales / свой)
│ вебхук или опрос API
▼
[Приём] HTTP-сервис в расширении 1С
│ сначала сохранить сырое тело
▼
Регистр «Входящие заказы» (сырое тело, источник, внешний ID, статус)
│ разбор: синхронно или регламентом
▼
Сопоставление: покупатель, номенклатура, доставка, оплата
│ │
│ └─ не нашлось ─► очередь «Требует внимания»
▼
Документ 1С (Заказ клиента / Счёт / Реализация — по вашей схеме)
Всё это живёт в расширении: типовая конфигурация остаётся на поддержке, документы создаются программно, формы типовых объектов не трогаются.
Как заказ доезжает до 1С: push или pull
Здесь первая развилка, и выбирать её нужно до написания кода.
Push (вебхук). Сайт сам отправляет заказ на адрес, который вы укажете. Tilda умеет отправлять данные форм и заказов на вебхук; у InSales есть вебхуки на создание и изменение заказа; свой сайт может отправлять что угодно. Плюс — минимальная задержка. Минус — адрес должен быть доступен из интернета. Если 1С стоит в офисе за NAT, придётся публиковать HTTP-сервис через веб-сервер с HTTPS, либо ставить между сайтом и 1С небольшой буфер, который принимает вебхук и хранит его, пока 1С не заберёт.
Pull (опрос API). 1С регламентным заданием раз в несколько минут спрашивает у сайта: «какие заказы появились или изменились после такой-то метки?». Наружу ничего публиковать не нужно. Минус — задержка равна периоду опроса, и у сайта должно быть API, которое умеет отдавать изменения (у InSales оно есть; у Tilda для заказов — смотрите текущие возможности, часто остаётся только вебхук).
На практике у небольших компаний часто побеждает комбинация: вебхук как основной канал и опрос раз в час как страховка — он подбирает то, что потерялось при сбое связи.
Пара мелочей, о которых вспоминают поздно:
некоторые конструкторы при подключении вебхука присылают тестовый запрос. Приём должен ответить на него 200 и не пытаться создать документ;
формат тела бывает разным:
application/x-www-form-urlencoded, JSON, вложенные массивы товаров. Разбор формата держите в отдельной функции на каждый источник, а дальше работайте с одной внутренней структурой заказа.
Приём: сначала сохранить, потом разбирать
Правило, которое я повторяю в каждой интеграции: HTTP-сервис ничего не знает про номенклатуру. Его задача — проверить, что запрос свой, сохранить тело как есть и ответить.
Функция OrdersPOST(Запрос)
Источник = Запрос.ПараметрыURL["source"]; // tilda, insales, site
Если Не ПриёмЗаказов.ИсточникРазрешён(Источник) Тогда
Возврат ПриёмЗаказов.Ответ(404, "Неизвестный источник");
КонецЕсли;
Если Не ПриёмЗаказов.ПодписьВерна(Источник, Запрос) Тогда
Возврат ПриёмЗаказов.Ответ(401, "Нет доступа");
КонецЕсли;
Тело = Запрос.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Если ПриёмЗаказов.ЭтоТестовыйЗапрос(Источник, Тело) Тогда
Возврат ПриёмЗаказов.Ответ(200, "ok");
КонецЕсли;
ПриёмЗаказов.СохранитьВходящий(Источник, Тело, Запрос.Заголовки);
Возврат ПриёмЗаказов.Ответ(200, "ok");
КонецФункции
Почему не создавать документ прямо здесь? Потому что сайт ждёт ответ ограниченное время. Если разбор заказа упрётся в блокировку или медленный запрос, сайт получит таймаут и пришлёт заказ ещё раз. А если сырое тело уже лежит в базе, вы можете разобрать его повторно после исправления справочника — не прося сайт «отправить ещё раз».
Про проверку «свой ли запрос»: если платформа подписывает вебхук — проверяйте подпись; если нет — хотя бы секретный параметр в адресе и HTTPS. Открытый HTTP-сервис, который создаёт документы по любому POST, — плохая идея.
Идемпотентность: один заказ — один документ
Повторная доставка — не исключение, а норма: ретраи после таймаута, страховочный опрос, ручная перезагрузка. Поэтому ключ заказа — это источник + внешний номер заказа, и до создания документа мы проверяем, не создан ли он уже.
Процедура РазобратьВходящий(ИдСообщения) Экспорт
Сообщение = ПрочитатьВходящий(ИдСообщения);
Заказ = РазборФорматов.ВоВнутреннийФормат(Сообщение.Источник, Сообщение.Тело);
Ключ = Сообщение.Источник + "|" + СокрЛП(Заказ.ВнешнийНомер);
Блокировка = Новый БлокировкаДанных;
Элемент = Блокировка.Добавить("РегистрСведений.СоответствиеВнешнихЗаказов");
Элемент.УстановитьЗначение("Ключ", Ключ);
НачатьТранзакцию();
Попытка
Блокировка.Заблокировать();
Документ = НайтиДокументПоКлючу(Ключ);
Если ЗначениеЗаполнено(Документ) Тогда
ОбновитьЕслиРазрешено(Документ, Заказ); // см. ниже про изменения
Иначе
Документ = СоздатьДокументЗаказа(Заказ);
ЗапомнитьКлюч(Ключ, Документ);
КонецЕсли;
УстановитьСтатус(ИдСообщения, "Обработано");
ЗафиксироватьТранзакцию();
Исключение
ОтменитьТранзакцию();
УстановитьСтатус(ИдСообщения, "Ошибка",
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Блокировка по ключу нужна на случай, когда вебхук и страховочный опрос принесли один и тот же заказ одновременно. Без неё проверка «не создан ли уже» проходит в обоих сеансах, и вы получаете два документа.
Заказ изменился после загрузки
Покупатель позвонил и поменял количество, менеджер на сайте отменил позицию, заказ оплатили. Что делать с документом в 1С — решение не техническое, а учётное, и его нужно зафиксировать до разработки:
пока документ не проведён / не передан на склад — обновляем из источника;
после этого — не трогаем документ, а кладём изменение в очередь «Требует внимания» с понятным текстом: «заказ 1234 изменён на сайте после передачи на склад».
Для сравнения удобно хранить хеш содержимого заказа: пришла та же версия — ничего не делаем; другая — применяем правило выше.
Сопоставление: самое долгое место
Код приёма пишется за день. Сопоставление — это то, на что уходит основное время, потому что упирается в данные.
Покупатель. Для физлиц на сайте обычно есть телефон и почта. Телефон нормализуйте (только цифры, приведение 8 → 7), почту — в нижний регистр. Решите заранее: каждый покупатель — отдельный контрагент или все розничные заказы идут на одного «Розничного покупателя» с данными в комментарии и контактной информации. Для юрлиц — ИНН и КПП, если сайт их собирает.
Номенклатура. Главное правило — сопоставлять по идентификатору, а не по названию. Название на сайте маркетолог поменяет к распродаже. Варианты ключа: артикул, если он одинаков на сайте и в 1С; внешний ID товара, сохранённый в регистре соответствий; штрихкод. Если товары изначально выгружались на сайт из 1С, ключ у вас уже есть — используйте его.
Модификации. Размер и цвет на сайте — это характеристики в 1С. Ключ строится по паре «товар + вариант», иначе все размеры одной футболки сольются в одну строку.
Доставка, скидки, промокоды. Доставка — отдельная строка услуги или реквизит документа? Скидка сайта — в цену строки или отдельной суммой? Эти вопросы проще задать бухгалтеру в первый день, чем переделывать документы потом.
Функция НайтиНоменклатуру(Источник, СтрокаТовара)
Ключ = Источник + "|" + НРег(СокрЛП(СтрокаТовара.ВнешнийID))
+ "|" + НРег(СокрЛП(СтрокаТовара.ВнешнийIDВарианта));
Соответствие = РегистрыСведений.СоответствиеВнешнихТоваров.Получить(
Новый Структура("Ключ", Ключ));
Если ЗначениеЗаполнено(Соответствие.Номенклатура) Тогда
Возврат Соответствие;
КонецЕсли;
// Не создаём номенклатуру сами: неизвестный товар — повод для разбора
Возврат Неопределено;
КонецФункции
Очередь «Требует внимания» вместо падения и вместо мусора
Есть два плохих способа обработать заказ с незнакомым товаром: уронить загрузку целиком или создать новую номенклатуру «как на сайте». Первый останавливает всё из-за одной строки. Второй через месяц даёт справочник с тремя версиями одного товара.
Правильный вариант — заказ откладывается в очередь с понятной причиной («товар с ID 5531 не сопоставлен»). Человек один раз указывает, какой это товар в 1С, связь запоминается в регистре соответствий, заказ перезагружается из сохранённого тела. В следующий раз этот товар найдётся сам.
Такая очередь — главный инструмент поддержки. Если в неё каждый день падает много заказов, это сигнал не к героизму, а к тому, что ключ сопоставления выбран неудачно.
Мониторинг: тишина — тоже сбой
Три сигнала, о которых ответственный должен узнавать сам:
в очереди разбора есть записи старше N часов;
сообщения со статусом «Ошибка»;
тишина: за рабочий день не пришло ни одного заказа, хотя обычно приходят. Ошибок нет, потому что нет данных — самый неприятный вид поломки (сменили адрес вебхука, истёк сертификат, сайт переехал).
Как это проверять, не трогая рабочую базу
Копия рабочей базы 1С, расширение — туда.
Тестовые заказы на сайте (или сохранённые тела реальных заказов, если сайт позволяет их получить).
Прогон тех же сохранённых тел многократно, пока сопоставление не перестанет давать сюрпризы.
Только потом — рабочая база, и первые дни с ежедневной сверкой «заказы на сайте = документы в 1С».
Что дальше по контуру
Заказы — обычно первая и самая заметная часть. Но редко единственная. Тот же приём, то же хранилище сырых сообщений и тот же механизм сопоставления переиспользуются дальше: статусы оплат с сайта, остатки и цены из 1С обратно на сайт, заявки из формы обратной связи, данные из CRM или своей программы. Каждый следующий источник — это новый разбор формата и новые правила сопоставления, а не новая архитектура. Поэтому первый документ я считаю пробой контура, а не его пределом: на нём проверяется, как схема ложится на ваши данные.
Вместо выводов
Загрузка заказов с сайта в 1С — задача, где код занимает меньше времени, чем договорённости: что считается ключом товара, что делать с изменённым заказом, куда идёт доставка. Порядок, который я считаю правильным: сохранить сырое тело → идемпотентность по внешнему номеру → сопоставление по идентификаторам → очередь разбора вместо мусора → мониторинг тишины. И всё это — в расширении, чтобы типовая обновлялась как раньше.
Если у вас сайт на Tilda, InSales или свой и вы уже пробовали подружить его с 1С — расскажите в комментариях, на чём споткнулись. Разберу интересные случаи.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.