Как правильно написать GET-запрос для получения заказов с Kaspi.kz в 1С?

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

Интеграция с маркетплейсами — одна из самых частых задач, встающих перед разработчиками 1С в сфере торговли. Одной из популярных площадок является Kaspi.kz — есть готовая автоматическая загрузка данных из маркетплейсов в 1С. При работе с их API (Kaspi Merchant API) многие сталкиваются с ошибками формата запроса, особенно при попытке получить список заказов. Чаще всего сервер возвращает ответ с кодом 400 Bad Request.

В этой статье мы подробно разберем, как правильно сформировать GET-запрос к Kaspi API, как работать с датами в формате Unix Timestamp (миллисекунды) в 1С и какие подводные камни могут привести к ошибкам при формировании строки URL, а для отладки можно использовать инструменты тестирования http сервисов.

Подготовка соединения и заголовков

Для начала взаимодействия с любым современным API нам необходимо настроить HTTP-соединение. Так как Kaspi.kz работает по протоколу HTTPS, нам обязательно потребуется использование защищенного соединения. Проверить параметры подключения можно через аналог Postman на платформе 1С (удобно через инструменты разработки и отладки запросов).

Рассмотрим создание соединения. Мы будем использовать объект HTTPСоединение. Важно помнить, что для защищенного канала используется объект ЗащищенноеСоединениеOpenSSL.


Соединение = Новый HTTPСоединение(
    "kaspi.kz", 
    , 
    , 
    , 
    , 
    , 
    Новый ЗащищенноеСоединениеOpenSSL()
);

Далее нам необходимо подготовить заголовки запроса. API Kaspi следует спецификации JSON API, поэтому крайне важно указать правильный Content-Type. Если указать просто application/json, сервер может не принять запрос или вернуть данные в неверном формате. Правильный тип контента для этого API — application/vnd.api+json.

Также нам потребуется токен авторизации, который передается в заголовке X-Auth-Token (аналогичный подход используется и в других сервисах, например, при получении токена авторизации RuStore).


Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/vnd.api+json");
Заголовки.Вставить("X-Auth-Token", "ВАШ_ТОКЕН_АВТОРИЗАЦИИ");

Работа с датами: Unix Timestamp в миллисекундах

Одна из главных сложностей, с которой сталкиваются разработчики при работе с этим API, — формат передачи времени. Фильтры filter[orders][creationDate][$ge] (больше или равно) и filter[orders][creationDate][$le] (меньше или равно) требуют указания времени создания заказа.

В отличие от стандартного строкового представления даты (например, "2023-10-01T12:00:00"), Kaspi API ожидает число — количество миллисекунд, прошедших с начала эпохи Unix (1 января 1970 года). В 1С встроенные функции работы с Unix-временем часто возвращают секунды, поэтому нам необходимо выполнить преобразование вручную.

Разберем алгоритм получения текущего времени в миллисекундах:

  1. Определяем "базовую дату" (Epoch start): 01.01.1970.
  2. Вычисляем разницу между текущей датой и базовой датой. В 1С разница дат возвращается в секундах.
  3. Умножаем полученное количество секунд на 1000, чтобы получить миллисекунды.
  4. Преобразуем число в строку без разделителей групп разрядов (это важно, так как пробелы в URL недопустимы).

Посмотрим на пример кода, реализующего этот алгоритм:


// Определяем опорную дату
ИсхДата = Дата(1970, 1, 1);

// Текущая дата (конец периода)
ТекДата = ТекущаяДата();
// Рассчитываем миллисекунды: (Разница в секундах) * 1000
ДатаВМил = (ТекДата - ИсхДата) * 1000;
// Форматируем в строку без пробелов (группировок)
ДатаВМилСтрока = Формат(ДатаВМил, "ЧГ=");

// Дата начала (например, 10 дней назад)
// 600 секунд * 1000 мс * (сколько-то минут) - здесь лучше использовать стандартные функции добавления времени
// Для примера возьмем просто вычитание секунд из текущей даты
КоличествоДнейНазад = 10;
СекундВСутках = 86400;
ДатаНачала = ТекДата - (КоличествоДнейНазад * СекундВСутках);

ДатаВмилНачало = (ДатаНачала - ИсхДата) * 1000;
ДатаВМилНачалоСтрока = Формат(ДатаВмилНачало, "ЧГ=");

Обратите внимание: при использовании функции Формат параметр "ЧГ=" обязателен, иначе число "1478736000000" может превратиться в "1 478 736 000 000", что сломает URL запроса. Для более сложных сценариев взаимодействия с данными можно использовать универсальный Python-коннектор к 1С.

Обязательные параметры фильтрации

При запросе списка заказов нельзя просто обратиться к ресурсу /orders без параметров — для этой задачи есть модуль управления заказами через API маркетплейсов. API накладывает ограничения на выборку данных. Если вы не укажете определенные фильтры, сервер вернет ошибку 400.

На основе практического опыта выяснилось, что обязательными (или критически важными для корректной выборки) являются следующие параметры:

Частая ошибка — указать статус (status), но не указать состояние (state), к которому этот статус относится.

Формирование строки запроса и ошибка "Code 10"

Теперь перейдем к самой коварной ошибке, которая часто возникает при написании длинных запросов в 1С. Когда строка URL получается очень длинной, программисты часто переносят её на новую строку в редакторе кода, используя символ |.

Рассмотрим пример неправильного кода:


// ОШИБКА: Использование переноса строк внутри URL
СтрокаЗапроса = "shop/api/v2/orders?page[number]=0&page[size]=20
|&filter[orders][creationDate][$ge]=" + ДатаВМилНачалоСтрока; 

Проблема здесь заключается в том, что при компиляции такой строки в нее может попасть символ перевода строки (Code 10) или возврата каретки. Для HTTP-протокола это недопустимо в середине URL-адреса. Сервер, получив такой запрос, не сможет его распарсить и вернет ошибку:

{"errors":[{"status":"400","title":"Request parameters error","detail":"For input string: \"20\n\""}]}

В сообщении об ошибке видно \n, что прямо указывает на наличие лишнего символа переноса строки после значения параметра. Чтобы избежать этого, формируйте строку в одну линию или используйте конкатенацию (сложение строк) без символов переноса внутри строковых литералов — для поиска подобных ошибок подойдёт инструмент пошаговой отладки кода без конфигуратора.

Итоговый рабочий код

Соберем все части воедино. Мы создадим корректный GET-запрос, который запрашивает новые заказы, одобренные банком, за определенный период, включая информацию о пользователе.


// 1. Подготовка дат (Unix Timestamp ms)
ИсхДата = Дата(1970, 1, 1);
ТекДата = ТекущаяДата();

// Например, берем интервал за последние 7 дней
ДатаНачала = ТекДата - (7 * 86400); 

ДатаВМилКонец = (ТекДата - ИсхДата) * 1000;
ДатаВМилНачало = (ДатаНачала - ИсхДата) * 1000;

// Важно убрать группировку разрядов
СтрокаКонец = Формат(ДатаВМилКонец, "ЧГ=");
СтрокаНачало = Формат(ДатаВМилНачало, "ЧГ=");

// 2. Подготовка заголовков
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/vnd.api+json");
Заголовки.Вставить("X-Auth-Token", "ВАШ_ТОКЕН");

// 3. Настройка соединения
Соединение = Новый HTTPСоединение(
    "kaspi.kz", 
    , 
    , 
    , 
    , 
    , 
    Новый ЗащищенноеСоединениеOpenSSL()
);

// 4. Формирование строки URL
// Собираем строку аккуратно, чтобы избежать лишних символов переноса
АдресРесурса = "/shop/api/v2/orders";
ПараметрыЗапроса = "?page[number]=0&page[size]=20";
ПараметрыЗапроса = ПараметрыЗапроса + "&filter[orders][state]=NEW";
ПараметрыЗапроса = ПараметрыЗапроса + "&filter[orders][creationDate][$ge]=" + СтрокаНачало;
ПараметрыЗапроса = ПараметрыЗапроса + "&filter[orders][creationDate][$le]=" + СтрокаКонец;
ПараметрыЗапроса = ПараметрыЗапроса + "&filter[orders][status]=APPROVED_BY_BANK";
// Включаем данные о покупателе
ПараметрыЗапроса = ПараметрыЗапроса + "&include[orders]=user"; 

// 5. Выполнение запроса
ЗапросGET = Новый HTTPЗапрос(АдресРесурса + ПараметрыЗапроса, Заголовки);
Попытка
    Ответ = Соединение.Получить(ЗапросGET);
    
    Если Ответ.КодСостояния = 200 Тогда
        ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
        // Дальнейшая обработка JSON
        Сообщить("Заказы успешно получены!");
    Иначе
        Сообщить("Ошибка запроса: " + Ответ.КодСостояния);
        Сообщить(Ответ.ПолучитьТелоКакСтроку());
    КонецЕсли;
    
Исключение
    Сообщить("Ошибка соединения: " + ОписаниеОшибки());
КонецПопытки;

Рекомендации по улучшению кода

Хотя приведенный выше код работает, для промышленной эксплуатации рекомендуется использовать методы кодирования URL. Это обезопасит вас от проблем, если в значениях параметров (например, в токене или сложных фильтрах) встретятся спецсимволы.

В 1С для этого существует функция глобального контекста КодироватьСтроку. Однако применять её нужно не ко всей строке URL сразу (иначе закодируются символы ?, & и =, необходимые для структуры), а к значениям параметров или использовать специальные библиотеки/коннекторы для сборки HTTP-запросов.

Проанализировав данное решение, можно сделать вывод, что успех интеграции с Kaspi зависит от трех факторов: правильного формата заголовка Content-Type, математически верного расчета времени в миллисекундах и аккуратной сборки строки запроса без скрытых символов форматирования текста.

← На главную