Современные веб-проекты чаще всего используют реактивный фронтенд и легковесный бэкенд на популярных фреймворках (например, Laravel, Node.js, Django). В то же время бизнес-логика, складской учет, взаиморасчеты и обработка заказов традиционно ведутся в «1С:Предприятии». Интеграция этих систем — стандартная задача для разработчика. В этой статье мы подробно разберем, как спроектировать и реализовать надежный, быстрый и юридически чистый двусторонний обмен данными между веб-сайтом и 1С с использованием современных механизмов платформы.
В платформе 1С начиная с версии 8.3 существуют два основных механизма для построения REST API. Рассмотрим их подробнее, чтобы понять, какой инструмент лучше выбрать для решения нашей задачи.
Автоматический REST-интерфейс (стандарт OData). Это встроенный механизм, который позволяет буквально в один клик опубликовать всю базу данных 1С во внешний мир. Платформа сама генерирует готовые эндпоинты для всех справочников, документов и регистров.
Преимуществом OData является скорость развертывания. Однако для веб-интеграции этот подход имеет критические недостатки:
HTTP-сервисы (Рекомендуемый подход). Этот механизм позволяет программисту вручную проектировать API. Мы сами создаем структуру URL, определяем поддерживаемые методы (GET, POST, PUT, DELETE) и полностью контролируем код обработки запросов на языке 1С. Это дает максимальную гибкость, безопасность и высокую скорость работы.
Проанализируем процесс создания собственного HTTP-сервиса в конфигураторе 1С. Наша задача — принять от сайта JSON-пакет с новым заказом покупателя, записать его в базу данных и вернуть сайту статус операции и уникальный номер созданного документа.
ОбменССайтом. Укажем корневой URL, например, api_v1./orders.POST. Укажем имя обработчика в модуле HTTP-сервиса (например, СоздатьЗаказ).Теперь перейдем в модуль HTTP-сервиса и напишем код обработчика. Для работы с JSON в 1С используются встроенные объекты ЧтениеJSON и ЗаписьJSON.
Функция СоздатьЗаказ(Запрос)
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// Получаем тело запроса в виде строки
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку("UTF-8");
Если ПустаяСтрока(СтрокаJSON) Тогда
Ответ.КодСостояния = 400;
Ответ.УстановитьТелоИспользованиемСтроки("{""error"": ""Пустое тело запроса""}");
Возврат Ответ;
КонецЕсли;
// Парсинг JSON в структуру 1С
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
Попытка
ДанныеЗаказа = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Исключение
Чтение.Закрыть();
Ответ.КодСостояния = 400;
Ответ.УстановитьТелоИспользованиемСтроки("{""error"": ""Ошибка парсинга JSON""}");
Возврат Ответ;
КонецПопытки;
// Создание документа в транзакции
НачатьТранзакцию();
Попытка
НовыйЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
НовыйЗаказ.Дата = ТекущаяДата();
// Поиск контрагента по ИНН или уникальному коду с сайта
КонтрагентСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("IDНаСайте", ДанныеЗаказа.user_id);
Если КонтрагентСсылка.Пустая() Тогда
// Создаем нового контрагента, если он не найден
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.Наименование = ДанныеЗаказа.user_name;
НовыйКонтрагент.IDНаСайте = ДанныеЗаказа.user_id;
НовыйКонтрагент.Записать();
КонтрагентСсылка = НовыйКонтрагент.Ссылка;
КонецЕсли;
НовыйЗаказ.Контрагент = КонтрагентСсылка;
// Заполнение табличной части товары
Для Каждого СтрокаТовара Из ДанныеЗаказа.items Цикл
НоваяСтрока = НовыйЗаказ.Товары.Добавить();
НоменклатураСсылка = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", СтрокаТовара.sku);
Если НоменклатураСсылка.Пустая() Тогда
ВызватьИсключение "Товар с артикулом " + СтрокаТовара.sku + " не найден в базе 1С";
КонецЕсли;
НоваяСтрока.Номенклатура = НоменклатураСсылка;
НоваяСтрока.Количество = СтрокаТовара.qty;
НоваяСтрока.Цена = СтрокаТовара.price;
НоваяСтрока.Сумма = СтрокаТовара.qty * СтрокаТовара.price;
КонецЦикла;
НовыйЗаказ.Записать(РежимЗаписиДокумента.Проведение);
ЗафиксироватьТранзакцию();
// Формируем успешный JSON-ответ
РезультатСтруктура = Новый Структура;
РезультатСтруктура.Вставить("success", Истина);
РезультатСтруктура.Вставить("order_id", Строка(НовыйЗаказ.Ссылка.УникальныйИдентификатор()));
РезультатСтруктура.Вставить("number", НовыйЗаказ.Номер);
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, РезультатСтруктура);
Ответ.УстановитьТелоИспользованиемСтроки(Запись.Закрыть());
Исключение
ОтменитьТранзакцию();
Ответ.КодСостояния = 500;
ОшибкаСтруктура = Новый Структура;
ОшибкаСтруктура.Вставить("success", Ложь);
ОшибкаСтруктура.Вставить("error", ОписаниеОшибки());
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, ОшибкаСтруктура);
Ответ.УстановитьТелоИспользованиемСтроки(Запись.Закрыть());
КонецПопытки;
Возврат Ответ;
КонецФункции
Выясним, какое программное окружение потребуется для работы нашего API под управлением ОС Linux. Современная платформа 1С полностью поддерживает работу в этой операционной системе.
Для публикации HTTP-сервисов 1С необходима следующая связка ПО:
wsap24.so) для трансляции HTTP-запросов к СУБД и серверу 1С.Важное примечание по файловой версии: Файловая база 1С тоже может быть опубликована на веб-сервере Apache под Linux. Но помните, что файловая СУБД при записи данных блокирует таблицы целиком. Если ваш сайт будет делать частые параллельные запросы к API, веб-сервер начнет выстраивать запросы в очередь, что приведет к задержкам ответов (тайм-аутам). Для промышленной эксплуатации и стабильного API необходим полноценный клиент-серверный вариант 1С.
Разберем юридические правила лицензирования фирмы «1С». Это один из самых спорных вопросов при интеграции сайтов с системами учета.
Существует официальное понятие — мультиплексирование. Согласно лицензионному соглашению 1С, использование программных средств (в нашем случае веб-сайта), которые уменьшают количество пользователей, имеющих непосредственный доступ к 1С, не уменьшает количество необходимых клиентских лицензий.
Если ваш сайт работает по принципу «прямого запроса» (например, покупатель нажимает кнопку «Оформить заказ» на сайте, сайт в ту же секунду через curl-запрос дергает HTTP-сервис 1С под одной технической учетной записью, проводит документ и отдает ответ клиенту), то с юридической точки зрения каждый покупатель сайта является пользователем 1С. Если на сайте одновременно оформляют заказы 100 человек — вы обязаны купить 100 клиентских лицензий 1С. Работа по такой схеме с одной лицензией нарушает авторские права правообладателя.
Как организовать обмен законно и обойтись минимальным количеством лицензий 1С (даже одной)? Выход один — использовать асинхронный обмен через промежуточную базу данных сайта (MySQL/PostgreSQL).
Проанализируем архитектуру правильного асинхронного обмена:
При такой схеме конечные пользователи сайта вообще никак не взаимодействуют с платформой 1С. С базой 1С работает только один автоматический процесс (робот-синхронизатор) в монопольном режиме. Для работы такой схемы абсолютно легально требуется всего одна клиентская лицензия 1С.
Такой подход не только экономит средства на лицензиях, но и делает веб-ресурс невероятно отказоустойчивым: если сервер 1С уйдет на техническое обслуживание или перезагрузку, сайт продолжит принимать заказы пользователей в штатном режиме, а когда 1С вернется в сеть, фоновый скрипт синхронизации спокойно передаст накопившиеся документы.