Интеграция с логистическими сервисами, такими как Яндекс.Доставка (Cargo API), является стандартной задачей для современной автоматизации торговли. Однако при работе с b2b.taxi.yandex.net разработчики часто сталкиваются с трудностями на этапе авторизации и формирования структуры запроса. В этой статье мы подробно разберем, как правильно настроить обмен данными, избежать ошибки 401 и корректно передать координаты точек маршрута.
Одной из самых частых проблем является получение HTTP-статуса 401 Unauthorized. Проанализируем основные причины возникновения этой ошибки. Даже если у вас есть рабочий токен, сервер может отклонить запрос по следующим причинам:
OAuth. Для современного Cargo API (логистического API) стандартом является заголовок Bearer.oauth.yandex.ru, может не иметь необходимых прав (scopes) для работы с логистикой. Токен нужно генерировать в личном кабинете Яндекс Доставки в разделе «Интеграции».Accept-Language не должны содержать технических описаний типов (например, "string"), а должны указывать конкретный код языка.Рассмотрим правильное формирование заголовков в коде 1С:
Заголовки = Новый Соответствие;
// Правильный формат авторизации: Bearer [Ваш_Токен]
Заголовки.Вставить("Authorization", "Bearer AQAAAAADUfO2AAdkUhSK1tBqW0Unrm-_SYKwKzc");
// Указываем язык ответа (ru или en)
Заголовки.Вставить("Accept-Language", "ru");
// Обязательно указываем тип контента для POST-запросов
Заголовки.Вставить("Content-Type", "application/json");
Для расчета стоимости API требует массив точек маршрута route_points. Выясним важный нюанс: Яндекс ожидает координаты в формате [Долгота, Широта]. Если перепутать их местами, запрос может вернуть ошибку о нахождении точки вне зоны покрытия.
Проанализируем структуру JSON-тела запроса для метода /check-price. Обратите внимание, что координаты передаются как числа (float), а не как строки в кавычках.
{
"items": [
{
"quantity": 1,
"size": {
"height": 0.1,
"length": 0.1,
"width": 0.1
},
"weight": 1.5
}
],
"route_points": [
{
"coordinates": [37.642474, 55.735520] // [Долгота1, Широта1] - Откуда
},
{
"coordinates": [37.581223, 55.733891] // [Долгота2, Широта2] - Куда
}
],
"requirements": {
"taxi_class": "express"
},
"skip_door_to_door": false
}
Для работы с защищенным соединением используем объект ЗащищенноеСоединениеOpenSSL. Посмотрим на пример процедуры, которая формирует запрос и обрабатывает ответ сервера:
&НаСервере
Процедура РассчитатьСтоимостьНаСервере()
Сервер = "b2b.taxi.yandex.net";
Адрес = "b2b/cargo/integration/v1/check-price";
// Формируем структуру запроса
СтруктураЗапроса = Новый Структура;
// Точки маршрута
МассивТочек = Новый Массив;
МассивТочек.Добавить(Новый Структура("coordinates", Новый Массив));
МассивТочек[0].coordinates.Добавить(37.6176); // Долгота
МассивТочек[0].coordinates.Добавить(55.7558); // Широта
МассивТочек.Добавить(Новый Структура("coordinates", Новый Массив));
МассивТочек[1].coordinates.Добавить(37.6000); // Долгота
МассивТочек[1].coordinates.Добавить(55.7000); // Широта
СтруктураЗапроса.Вставить("route_points", МассивТочек);
// Требования (выбор тарифа)
Требования = Новый Структура;
Требования.Вставить("taxi_class", "express");
СтруктураЗапроса.Вставить("requirements", Требования);
// Преобразование в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураЗапроса);
ТелоЗапроса = ЗаписьJSON.Закрыть();
// Настройка соединения
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, , , , , , ЗащищенноеСоединение);
Запрос = Новый HTTPЗапрос(Адрес);
Запрос.Заголовки.Вставить("Authorization", "Bearer " + Объект.Токен);
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(ЧтениеJSON);
Сообщить("Стоимость доставки: " + Данные.price);
Иначе
Сообщить("Ошибка запроса: " + Ответ.КодСостояния);
Сообщить(Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
КонецПроцедуры
Иногда при интеграции возникает ситуация, когда в запросе мы указываем "taxi_class": "courier", а API все равно возвращает расчет для cargo. Рассмотрим причины такого поведения:
items, Яндекс автоматически проверяет, помещается ли груз в сумку курьера. Если вес превышает лимит (обычно более 15-20 кг) или размеры сторон слишком велики, система принудительно повышает класс до грузового./v1/tariffs/available.client_requirements внутри основного тела запроса.Для тестирования интеграции крайне рекомендуется использовать Sandbox (Песочницу). Это позволит вам отладить формат JSON и заголовков, не создавая реальных платных заявок. Адрес тестового сервера: b2b-sandbox.taxi.yandex.net.
Также важно помнить о кешировании. Расчет стоимости — операция быстрая, но при большом потоке запросов (например, при каждом изменении адреса в заказе 1С) можно столкнуться с ограничением 429 Too Many Requests. Рекомендуется сохранять результат расчета в памяти или временном хранилище формы 1С, если параметры маршрута и состава груза не изменились.
Использование объектов HTTPСоединение и HTTPЗапрос совместно с сериализацией в JSON через ЗаписатьJSON позволяет построить надежный и гибкий механизм взаимодействия с сервисом Яндекс.Доставка, обеспечивая актуальные данные о стоимости услуг для ваших пользователей.