Ошибка "Некорректный формат переданной даты" при подключении 1С к API Wildberries. Как исправить?

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

При интеграции 1С с маркетплейсами, в частности с Wildberries, разработчики часто сталкиваются с ошибками при работе с API. Одна из самых распространенных — это ошибка формата даты при отправке запросов на получение данных за определенный период. Давайте вместе разберем реальный случай, когда при попытке получить заказы с Wildberries сервер возвращает ответ: {"error":"Некорректный формат переданной даты."}. Проанализируем исходный код, выясним причины проблемы и найдем правильное решение.

Исходная ситуация выглядит так: программист формирует GET-запрос к API Wildberries для получения заказов, передавая в параметрах дату начала и конца периода. Вот фрагмент кода, который приводит к ошибке:


Токен = "xxxxxx";
Заголовки = новый Соответствие();
Заголовки.Вставить("X-Auth-Token", Токен);
Заголовки.Вставить("Content-Type", "application/json");

SSL_Соединение = Новый ЗащищенноеСоединениеOpenSSL();
HttpСоединение = новый HttpСоединение("suppliers-orders.wildberries.ru", 443, , , , SSL_Соединение);
    
// Даты формируются в формате ISO 8601 со смещением часового пояса
Сервис = "/api/v1/orders?date_start=2020-12-20T00:00:00+03:00&date_end=2021-01-12T00:00:00+03:00";
    
HTTPЗапрос = новый HttpЗапрос(сервис, заголовки);
HttpОтвет = HTTPСоединение.Получить(HTTPЗапрос);
Результат = HttpОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

// В переменной Результат получаем: {"error":"Некорректный формат переданной даты."}

На первый взгляд, формат даты 2020-12-20T00:00:00+03:00 соответствует стандарту, и даже в старой документации Wildberries можно было встретить подобные примеры. Однако, как это часто бывает, дьявол кроется в деталях. Разберем по шагам, что здесь может быть не так.

Причина №1: Специальные символы в URL и их кодирование

Давайте внимательно посмотрим на строку запроса, а именно на параметр даты: ...T00:00:00<strong>+</strong>03:00. Символ + является специальным символом в URL. При передаче в строке запроса он по стандарту интерпретируется как пробел. Это означает, что сервер Wildberries вместо ожидаемого +03:00 получает 03:00 (с пробелом). Естественно, такая строка не может быть распознана как корректное смещение часового пояса, что и приводит к ошибке формата даты.

Решение: Все параметры, которые вставляются в URL, необходимо кодировать с помощью специального механизма URL-encoding. В 1С для этого есть функция КодироватьСтроку().

Неправильно кодировать всю строку целиком. Кодировать нужно значение каждого параметра по отдельности, а затем уже собирать итоговую строку запроса. Посмотрим на исправленный вариант формирования строки:


// Формируем даты как строки в нужном формате
ДатаНачалоСтрокой = Формат(ДатаНачала, "ДФ='yyyy-MM-ddTHH:mm:ss+03:00'");
ДатаОкончанияСтрокой = Формат(ДатаОкончания, "ДФ='yyyy-MM-ddTHH:mm:ss+03:00'");

// Кодируем ТОЛЬКО значения параметров
ЗакодированнаяДатаНачало = КодироватьСтроку(ДатаНачалоСтрокой, СпособКодированияСтроки.КодировкаURL);
ЗакодированнаяДатаОкончания = КодироватьСтроку(ДатаОкончанияСтрокой, СпособКодированияСтроки.КодировкаURL);

// Собираем итоговую строку сервиса
Сервис = "/api/v1/orders?date_start=" + ЗакодированнаяДатаНачало + "&date_end=" + ЗакодированнаяДатаОкончания;

После такого преобразования символ + будет заменен на его код %2B, и сервер получит корректную строку: ...T00:00:00%2B03:00. В большинстве случаев уже одно это действие решает проблему.

Причина №2: Формат даты и часовой пояс UTC

Даже после кодирования ошибка может сохраняться. Часто это связано с тем, что API-серверы настроены на прием даты и времени в универсальном координированном времени (UTC). Передача смещения часового пояса (например, +03:00) может быть не поддержана или работать нестабильно.

Решение: Лучшей практикой при работе с API является передача времени в формате UTC. По стандарту ISO 8601 это обозначается буквой Z в конце строки времени. Это однозначно указывает серверу, что время передано по Гринвичу (нулевой часовой пояс).

Давайте изменим код, чтобы он формировал дату в UTC:

  1. Получаем универсальную дату. В 1С для этого можно использовать функцию ТекущаяУниверсальнаяДата() или преобразовать локальную дату в UTC.

  2. Форматируем строку. При форматировании нужно добавить в конце символ Z.

Пример формирования правильной строки даты в UTC:


// Предположим, у нас есть ДатаНачала (локальное время)
// Преобразуем ее в UTC. Простой способ - вычесть разницу с UTC.
// РазницаЧасовыхПоясов = (ТекущаяДата() - ТекущаяУниверсальнаяДата()) / 3600; // в часах
// ДатаНачалаUTC = ДатаНачала - РазницаЧасовыхПоясов * 3600;

// Более надежный способ получить текущее время UTC и отформатировать его
ДатаНачалаUTC = ТекущаяУниверсальнаяДата();
ДатаОкончанияUTC = ТекущаяУниверсальнаяДата() + 3600; // например, +1 час

// Форматируем строку в соответствии со стандартом, добавляя 'Z' вручную
ДатаНачалоСтрокой = Формат(ДатаНачалаUTC, "ДФ='yyyy-MM-ddTHH:mm:ss'") + "Z";
ДатаОкончанияСтрокой = Формат(ДатаОкончанияUTC, "ДФ='yyyy-MM-ddTHH:mm:ss'") + "Z";

// Кодировать значения уже не нужно, так как в них нет спецсимволов, но оставим это как хорошую практику
ЗакодированнаяДатаНачало = КодироватьСтроку(ДатаНачалоСтрокой, СпособКодированияСтроки.КодировкаURL);
ЗакодированнаяДатаОкончания = КодироватьСтроку(ДатаОкончанияСтрокой, СпособКодированияСтроки.КодировкаURL);

Сервис = "/api/v1/orders?date_start=" + ЗакодированнаяДатаНачало + "&date_end=" + ЗакодированнаяДатаОкончания;

Использование формата с Z — наиболее надежный и кроссплатформенный способ передачи времени, который понимают практически все современные API.

Критически важное замечание: актуальность API

В процессе решения проблемы выяснился еще один важный аспект: версия API. В исходном коде используется эндпоинт /api/<strong>v1</strong>/orders. Wildberries, как и многие другие крупные платформы, постоянно развивает свой API. Старые версии (v1, v2) могут быть объявлены устаревшими (deprecated), работать нестабильно или вовсе отключаться.

Решение: Всегда сверяйтесь с актуальной официальной документацией для разработчиков на портале Wildberries. На сегодняшний день для работы с заказами используются более новые версии API (например, `v3`), которые имеют другие требования:

Таким образом, если вы столкнулись с подобной ошибкой, первым делом убедитесь, что вы используете актуальную и поддерживаемую версию API.

Итоговый пример и рекомендации

Соберем все рекомендации воедино и напишем итоговый, современный вариант кода для подключения к API Wildberries. Будем использовать актуальный метод авторизации и формат даты UTC.


// Используйте API-ключ нового формата!
Токен = "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjMtMDYtMj..."; 
    
Заголовки = Новый Соответствие();
// Актуальный заголовок авторизации
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Accept", "application/json"); // Рекомендуемый заголовок
    
// Используем актуальный хост для API поставщиков
HttpСоединение = Новый HttpСоединение("suppliers-api.wildberries.ru", 443, , , , Новый ЗащищенноеСоединениеOpenSSL());
    
// Даты в UTC и формате YYYY-MM-DDTHH:MM:SSZ
ДатаНачалаUTC = ТекущаяУниверсальнаяДата() - 86400; // Сутки назад
ДатаОкончанияUTC = ТекущаяУниверсальнаяДата();
    
ДатаНачалоСтрокой = Формат(ДатаНачалаUTC, "ДФ='yyyy-MM-ddTHH:mm:ss'") + "Z";
ДатаОкончанияСтрокой = Формат(ДатаОкончанияUTC, "ДФ='yyyy-MM-ddTHH:mm:ss'") + "Z";

// Кодируем значения параметров на случай наличия спецсимволов
ЗакодированнаяДатаНачало = КодироватьСтроку(ДатаНачалоСтрокой, СпособКодированияСтроки.КодировкаURL);
ЗакодированнаяДатаОкончания = КодироватьСтроку(ДатаОкончанияСтрокой, СпособКодированияСтроки.КодировкаURL);

// Используем актуальный эндпоинт (пример, уточняйте в документации!)
Сервис = "/api/v3/orders?limit=100&next=0&dateFrom=" + ЗакодированнаяДатаНачало + "&dateTo=" + ЗакодированнаяДатаОкончания;
    
HTTPЗапрос = Новый HttpЗапрос(Сервис, Заголовки);
    
Попытка
    HttpОтвет = HttpСоединение.Получить(HTTPЗапрос);
    Если HttpОтвет.КодСостояния >= 200 И HttpОтвет.КодСостояния < 300 Тогда
        Результат = HttpОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        Сообщить("Успешный ответ от сервера!");
        // Дальнейшая обработка JSON...
    Иначе
        ТекстОшибки = HttpОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        Сообщить("Ошибка при запросе. Код: " + HttpОтвет.КодСостояния + ". Ответ: " + ТекстОшибки);
    КонецЕсли;
Исключение
    Сообщить("Исключение при выполнении HTTP-запроса: " + ОписаниеОшибки());
КонецПопытки;

Для отладки всегда выводите в лог итоговую строку Сервис, которую вы отправляете, а также полный ответ сервера, включая код состояния и тело ответа. Это поможет быстро локализовать проблему, если она возникнет снова.

← На главную