Интеграция 1С с внешними сервисами через HTTP-запросы — одна из самых востребованных задач для современного разработчика. В данной статье мы подробно разберем, как настроить взаимодействие с JSON API 1.2 сервиса «МойСклад». Мы пройдем путь от получения первичного токена до решения специфических проблем, таких как работа со сжатыми данными в формате GZIP и правильное формирование структуры JSON для создания документов.
Прежде чем отправлять данные, нам необходимо авторизоваться. Сервис «МойСклад» поддерживает два основных способа: Basic Auth (используется для получения долгосрочного токена) и Bearer Token (используется для всех последующих операций). В некоторых случаях разработчикам также полезно изучить примеры того, как реализована авторизация с помощью токена (OAuth2.0) в других системах. Рассмотрим, как правильно подготовить запрос для авторизации.
Согласно документации, при использовании Basic Auth необходимо передать заголовок Authorization, содержащий строку Basic и закодированную в Base64 пару логин:пароль. Проанализируем, как это реализовать в коде 1С. Для кодирования в Base64 мы будем использовать встроенный объект Base64Строка, предварительно преобразовав строку в двоичные данные.
// Пример формирования заголовка авторизации
Логин = "admin@mycompany";
Пароль = "secret_password";
СтрокаАвторизации = Логин + ":" + Пароль;
// Помним, что Base64Строка работает с ДвоичнымиДанными
ДвоичныеДанныеАвторизации = ПолучитьДвоичныеДанныеИзСтроки(СтрокаАвторизации, КодировкаТекста.UTF8);
ТокенBase64 = Base64Строка(ДвоичныеДанныеАвторизации);
// Удаляем возможные переносы строк, которые иногда добавляет платформа
ТокенBase64 = СтрЗаменить(ТокенBase64, Символы.ПС, "");
ТокенBase64 = СтрЗаменить(ТокенBase64, Символы.ВК, "");
ЗаголовокАвторизации = "Basic " + ТокенBase64;
Рассмотрим по шагам процесс получения токена. Это разовая операция, после которой полученный access_token следует сохранить в константе или в настройках интеграции, так как он является бессрочным (до момента отзыва в личном кабинете). Аналогичные механизмы хранения и обновления доступа применяются и в других сервисах, например, когда настраивается интеграция 1С с Google Таблицами.
Выясним причину, по которой иногда возникают ошибки при первом соединении. Чаще всего это связано с неправильной настройкой SSL. Поскольку «МойСклад» работает по защищенному протоколу HTTPS, в объекте HTTPСоединение обязательно нужно указывать параметр ЗащищенноеСоединениеOpenSSL.
Хост = "api.moysklad.ru";
ИмяМетода = "/api/remap/1.2/security/token";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", ЗаголовокАвторизации);
// Укажем серверу, что мы ожидаем ответ в формате JSON
Заголовки.Вставить("Content-Type", "application/json");
SSL = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Хост, , , , , , SSL);
Запрос = Новый HTTPЗапрос(ИмяМетода, Заголовки);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
// Разберем JSON для извлечения токена
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТелоОтвета);
ДанныеJSON = ПрочитатьJSON(Чтение);
ТвойТокен = ДанныеJSON.access_token;
Чтение.Закрыть();
КонецЕсли;
Исключение
Сообщить("Ошибка при запросе: " + ОписаниеОшибки());
КонецПопытки;
Часто разработчики сталкиваются с ситуацией: запрос уходит успешно (код 200), но вместо привычного JSON в теле ответа содержится нечитаемый набор символов. Проанализируем ситуацию: это происходит потому, что сервер «МойСклад» по умолчанию или по требованию заголовка Accept-Encoding: gzip сжимает данные для экономии трафика.
Здесь есть два пути решения в зависимости от вашей версии платформы 1С:
Content-Encoding: gzip, методы ПолучитьТелоКакСтроку() вернут уже распакованный текст.Accept-Encoding или явно указав identity. Если же сервер настаивает на GZIP, потребуется использование внешних компонент или библиотек, таких как ЧтениеДанных с использованием потоков.Рассмотрим, как принудительно отключить сжатие, если ваша версия 1С не поддерживает автоматическую распаковку:
// В заголовках запроса удаляем упоминание gzip
Заголовки.Удалить("Accept-Encoding");
// Или явно указываем отсутствие сжатия
Заголовки.Вставить("Accept-Encoding", "identity");
Перейдем к более сложной задаче — отправке данных в «МойСклад». При создании заказа (POST запрос на /api/remap/1.2/entity/customerorder) критически важно соблюдать структуру метаданных. В «МойСклад» недостаточно передать просто ID товара, нужно передать объект meta, который указывает на тип сущности и содержит прямую ссылку на объект в API.
Проанализируем структуру JSON для позиции заказа (если вам требуется интеграция не из 1С, а во внешние системы, может быть интересен Python-коннектор к 1С с поддержкой метаданных):
СтруктураЗаказа = Новый Структура;
СтруктураЗаказа.Вставить("organization", Новый Структура("meta", ПолучитьМетаДанные("organization", "id_твоей_орг")));
СтруктураЗаказа.Вставить("agent", Новый Структура("meta", ПолучитьМетаДанные("counterparty", "id_контрагента")));
МассивПозиций = Новый Массив;
Позиция = Новый Структура;
Позиция.Вставить("quantity", 1);
Позиция.Вставить("price", 10000); // Цена в копейках (зависит от настроек API)
// Важный момент: Метаданные товара
МетаТовара = Новый Структура;
МетаТовара.Вставить("href", "https://api.moysklad.ru/api/remap/1.2/entity/product/" + ТоварИдентификатор);
МетаТовара.Вставить("type", "product");
МетаТовара.Вставить("mediaType", "application/json");
Позиция.Вставить("assortment", Новый Структура("meta", МетаТовара));
МассивПозиций.Добавить(Позиция);
СтруктураЗаказа.Вставить("positions", МассивПозиций);
Обратите внимание на объект assortment. В терминологии «МойСклад» это универсальное поле для товаров, услуг и модификаций. Если вы продаете товар с характеристикой, тип в meta должен быть variant.
Работая с API, мы должны помнить о лимитах. Стандартное ограничение — 45 запросов в секунду. Если ваша обработка в 1С выполняет массовую выгрузку товаров в цикле, вы быстро получите ошибку 429 Too Many Requests.
Для стабильной работы разберем механизм контроля лимитов через заголовки ответа:
X-RateLimit-Limit — общий лимит запросов.X-RateLimit-Remaining — сколько запросов осталось в текущем окне.X-RateLimit-Reset — время в миллисекундах до сброса лимита.Рекомендуется в коде 1С проверять Ответ.Заголовки.Получить("X-RateLimit-Remaining"). Если значение приближается к нулю, следует вызвать команду Приостановить(ВремяОжидания).
Если мы хотим прочитать все заказы из сервиса, мы не сможем сделать это одним запросом. API возвращает максимум 1000 записей. Рассмотрим, как реализовать перебор страниц с помощью параметров limit и offset.
Лимит = 1000;
Смещение = 0;
ВсегоЗаписей = 1; // Условное начальное значение
Пока Смещение < ВсегоЗаписей Цикл
ПараметрыЗапроса = "?limit=" + Формат(Лимит, "ЧГ=0") + "&offset=" + Формат(Смещение, "ЧГ=0");
Запрос = Новый HTTPЗапрос(ИмяМетода + ПараметрыЗапроса, Заголовки);
Ответ = Соединение.Получить(Запрос);
// ... обработка JSON ...
// Обновляем общее количество из поля "meta.size" в ответе
ВсегоЗаписей = ДанныеJSON.meta.size;
Смещение = Смещение + Лимит;
КонецЦикла;
Выясним причины самых частых сбоев:
Null. API «МойСклад» этого не любит. Для отладки таких запросов удобно использовать инструменты тестирования http сервисов. Если данных нет, поле нужно исключить из структуры JSON совсем, а не передавать его пустым.Authorization: Bearer [токен] для обычных запросов после получения токена.Проанализировав все вышеперечисленные аспекты, мы видим, что интеграция 1С с «МойСклад» требует внимательного отношения к заголовкам, формату данных и версии платформы. Использование современных версий 1С (8.3.26+) значительно упрощает жизнь разработчику благодаря автоматической обработке GZIP, однако понимание базовых механизмов работы протокола HTTP остается критически важным для качественной отладки.