Как реализовать интеграцию 1С с API МойСклад: авторизация и обработка GZIP

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

Интеграция 1С с внешними сервисами через HTTP-запросы — одна из самых востребованных задач для современного разработчика. В данной статье мы подробно разберем, как настроить взаимодействие с JSON API 1.2 сервиса «МойСклад». Мы пройдем путь от получения первичного токена до решения специфических проблем, таких как работа со сжатыми данными в формате GZIP и правильное формирование структуры JSON для создания документов.

Понимание основ авторизации в API МойСклад

Прежде чем отправлять данные, нам необходимо авторизоваться. Сервис «МойСклад» поддерживает два основных способа: 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

Рассмотрим по шагам процесс получения токена. Это разовая операция, после которой полученный 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;
        Чтение.Закрыть();
    КонецЕсли;
Исключение
    Сообщить("Ошибка при запросе: " + ОписаниеОшибки());
КонецПопытки;

Проблема GZIP: почему приходят «непонятные символы»?

Часто разработчики сталкиваются с ситуацией: запрос уходит успешно (код 200), но вместо привычного JSON в теле ответа содержится нечитаемый набор символов. Проанализируем ситуацию: это происходит потому, что сервер «МойСклад» по умолчанию или по требованию заголовка Accept-Encoding: gzip сжимает данные для экономии трафика.

Здесь есть два пути решения в зависимости от вашей версии платформы 1С:

  1. Версия 8.3.26 и выше: Платформа научилась автоматически распаковывать GZIP. Если в заголовках ответа присутствует Content-Encoding: gzip, методы ПолучитьТелоКакСтроку() вернут уже распакованный текст.
  2. Версии ниже 8.3.26: Вам придется обрабатывать сжатие самостоятельно. Самый простой способ — попросить сервер не сжимать данные, удалив заголовок 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.

Лимиты и ограничения (Rate Limiting)

Работая с API, мы должны помнить о лимитах. Стандартное ограничение — 45 запросов в секунду. Если ваша обработка в 1С выполняет массовую выгрузку товаров в цикле, вы быстро получите ошибку 429 Too Many Requests.

Для стабильной работы разберем механизм контроля лимитов через заголовки ответа:

Рекомендуется в коде 1С проверять Ответ.Заголовки.Получить("X-RateLimit-Remaining"). Если значение приближается к нулю, следует вызвать команду Приостановить(ВремяОжидания).

Работа с пагинацией при получении больших списков

Если мы хотим прочитать все заказы из сервиса, мы не сможем сделать это одним запросом. API возвращает максимум 1000 записей. Рассмотрим, как реализовать перебор страниц с помощью параметров limit и offset.


Лимит = 1000;
Смещение = 0;
ВсегоЗаписей = 1; // Условное начальное значение

Пока Смещение < ВсегоЗаписей Цикл
    ПараметрыЗапроса = "?limit=" + Формат(Лимит, "ЧГ=0") + "&offset=" + Формат(Смещение, "ЧГ=0");
    Запрос = Новый HTTPЗапрос(ИмяМетода + ПараметрыЗапроса, Заголовки);
    Ответ = Соединение.Получить(Запрос);
    
    // ... обработка JSON ...
    // Обновляем общее количество из поля "meta.size" в ответе
    ВсегоЗаписей = ДанныеJSON.meta.size;
    Смещение = Смещение + Лимит;
КонецЦикла;

Типичные ошибки и способы их отладки

Выясним причины самых частых сбоев:

  1. Ошибка 400 Bad Request: Скорее всего, вы передали поле со значением Null. API «МойСклад» этого не любит. Для отладки таких запросов удобно использовать инструменты тестирования http сервисов. Если данных нет, поле нужно исключить из структуры JSON совсем, а не передавать его пустым.
  2. Ошибка 401 Unauthorized: Проверьте корректность кодирования в Base64. В строке не должно быть лишних пробелов или символов перевода строки. Также убедитесь, что вы используете заголовок Authorization: Bearer [токен] для обычных запросов после получения токена.
  3. Непонятные ошибки в 1С: Посмотрите раздел «Аудит» в самом интерфейсе «МойСклад». Там логируются все входящие API-запросы с подробным описанием, какое именно поле не прошло валидацию.

Проанализировав все вышеперечисленные аспекты, мы видим, что интеграция 1С с «МойСклад» требует внимательного отношения к заголовкам, формату данных и версии платформы. Использование современных версий 1С (8.3.26+) значительно упрощает жизнь разработчику благодаря автоматической обработке GZIP, однако понимание базовых механизмов работы протокола HTTP остается критически важным для качественной отладки.

← На главную