Как получить расчетную стоимость доставки по API Яндекс.Доставка в 1С?

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

Интеграция с логистическими сервисами, такими как Яндекс.Доставка (Cargo API), является стандартной задачей для современной автоматизации торговли. Однако при работе с b2b.taxi.yandex.net разработчики часто сталкиваются с трудностями на этапе авторизации и формирования структуры запроса. В этой статье мы подробно разберем, как правильно настроить обмен данными, избежать ошибки 401 и корректно передать координаты точек маршрута.

Разбор проблемы авторизации (Ошибка 401)

Одной из самых частых проблем является получение HTTP-статуса 401 Unauthorized. Проанализируем основные причины возникновения этой ошибки. Даже если у вас есть рабочий токен, сервер может отклонить запрос по следующим причинам:

  1. Неверный формат заголовка: В старых методах Яндекса часто использовался префикс OAuth. Для современного Cargo API (логистического API) стандартом является заголовок Bearer.
  2. Тип токена: Токен, полученный через стандартную страницу oauth.yandex.ru, может не иметь необходимых прав (scopes) для работы с логистикой. Токен нужно генерировать в личном кабинете Яндекс Доставки в разделе «Интеграции».
  3. Некорректные дополнительные заголовки: Параметры вроде 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
}

Реализация отправки запроса в 1С

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

Проблема выбора тарифа: почему возвращается cargo вместо courier?

Иногда при интеграции возникает ситуация, когда в запросе мы указываем "taxi_class": "courier", а API все равно возвращает расчет для cargo. Рассмотрим причины такого поведения:

Рекомендации по отладке

Для тестирования интеграции крайне рекомендуется использовать Sandbox (Песочницу). Это позволит вам отладить формат JSON и заголовков, не создавая реальных платных заявок. Адрес тестового сервера: b2b-sandbox.taxi.yandex.net.

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

Использование объектов HTTPСоединение и HTTPЗапрос совместно с сериализацией в JSON через ЗаписатьJSON позволяет построить надежный и гибкий механизм взаимодействия с сервисом Яндекс.Доставка, обеспечивая актуальные данные о стоимости услуг для ваших пользователей.

← На главную