Как исправить ошибку "Unexpected token in JSON at position 0" при REST-запросах из 1С к API Мегамаркет?

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

При настройке интеграции 1С с маркетплейсами, в частности с платформой Мегамаркет (ранее СберМегаМаркет / Goods.ru), разработчики часто сталкиваются с неочевидными ошибками на этапе отправки POST-запросов с JSON-телом. Одна из самых распространенных ситуаций: сервер возвращает успешный HTTP-код 200 OK, но внутри ответа содержится сообщение об ошибке синтаксиса: {"success":0,"error":{"errorText":"Unexpected token Т in JSON at position 0","errorCode":"SyntaxError"}}.

Рассмотрим подробнее, почему возникает данная проблема, проанализируем ошибки в коде и разберем по шагам правильный алгоритм формирования запросов по API без скрытых символов кодировки.

Анализ исходной проблемы и выявление ошибок в коде

Давайте посмотрим на фрагмент кода, который чаще всего приводит к подобной ошибке. Разработчик пытается сформировать JSON, записать его в текстовый документ, а затем передать в тело запроса:


ТекстовыйФайл = Новый ТекстовыйДокумент;
ТекстовыйФайл.УстановитьТекст(JSON.СтрокаJSON);
ТекстовыйФайл.Записать(ФайлЗапроса, КодировкаТекста.UTF8);

HTTPЗапрос.УстановитьТелоИзСтроки(ТекстовыйФайл);

Проанализируем ситуацию. Здесь допущены сразу две грубые ошибки, которые ломают структуру передаваемых данных:

  1. Неверная передача объекта в тело запроса: Метод УстановитьТелоИзСтроки ожидает на вход тип данных Строка. Если передать туда объект ТекстовыйДокумент, платформа 1С неявно преобразует его в строку. В результате сервер Мегамаркета получает не структуру JSON, а системное строковое представление объекта, которое начинается с буквы "Т" (от слова "ТекстовыйДокумент"). Именно на это и ругается парсер: Unexpected token Т.
  2. Скрытый маркер BOM (Byte Order Mark): Даже если мы передадим непосредственно текст, платформа 1С при работе со строками и файлами в кодировке UTF-8 по умолчанию добавляет в начало невидимый символ спецификации порядка байтов (BOM). Парсер маркетплейса ожидает, что первым символом валидного JSON будет фигурная скобка {, но натыкается на спецсимвол. Из-за этого мы можем увидеть ошибки вида Unexpected token З или Unexpected token ".

Шаг 1: Правильное формирование JSON-строки без BOM-маркера

Выясним причину лишних действий. Для отправки JSON по API нам совершенно не нужно создавать промежуточные текстовые документы или временные файлы на диске. Давайте перепишем алгоритм так, чтобы формировать строку напрямую в памяти, и жестко отключим добавление BOM-маркера.

Посмотрим на корректный пример сборки JSON и подготовки HTTP-запроса:


// Формируем структуру с данными
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("data", ВнутренняяСтруктураСДанными);
СтруктураДанных.Вставить("meta", Новый Структура);

// Записываем структуру в JSON
ЗаписьJSON = Новый ЗаписьJSON;
// Не передаем параметры записи, используем настройки по умолчанию
ЗаписьJSON.УстановитьСтроку(); 
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);

// Получаем чистую строку
СтрокаТелаДляОтправки = ЗаписьJSON.Закрыть();

// Формируем запрос
HTTPЗапрос = Новый HTTPЗапрос(ПутьНаСервере, ЗаголовкиHTTP);

// ВАЖНО: Устанавливаем тело из строки с явным отключением BOM
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаТелаДляОтправки, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Использование свойства ИспользованиеByteOrderMark.НеИспользовать гарантирует, что первым байтом переданной информации будет именно открывающая скобка JSON-объекта, и сервер корректно распарсит наш запрос.

Шаг 2: Разбор ошибки "No valid token"

После того как мы исправляем синтаксис JSON, запрос начинает успешно проходить парсинг, но сервер может вернуть новую логическую ошибку: {"success":0,"error":{"message":"No valid token.","code":0}}. Разберем основные причины, почему Мегамаркет бракует переданный токен авторизации.

  1. Устаревший URL-адрес API: В старых примерах интеграции часто встречается домен partner.goodsteam.tech. Это устаревший адрес платформы Goods.ru. Современные токены, сгенерированные в новых личных кабинетах, могут не проходить валидацию на старых контурах. Обязательно проверьте документацию и используйте актуальные адреса (например, partner.megamarket.ru).
  2. Конфликт токена в заголовках и теле: API маркетплейса имеет свою специфику. Согласно инструкции метода order/shipping, токен передается внутри JSON в узле data.token. Если вы одновременно пытаетесь передать его в HTTP-заголовках (например, Заголовки.Вставить("Authorization", Токен);), сервер может запутаться и забраковать запрос. Оставьте авторизацию только там, где того требует конкретный метод.
  3. Несоответствие схемы работы (FBS/DBS): Токены в Мегамаркете привязаны к конкретной модели логистики или магазину. Если вы вызываете метод отгрузки курьеру, но ваш магазин работает по схеме "Доставка силами продавца (DBS)", токен будет признан невалидным для этой операции.
  4. Пустой объект meta: Обратите внимание на блок "meta": {} в вашем JSON. Для некоторых методов платформа требует передавать в мета-данных техническую информацию (идентификаторы сессий или мерчанта). Убедитесь по документации, действительно ли этот блок может быть пустым.

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

Соберем все рекомендации воедино и посмотрим на очищенный, рабочий вариант функции для отправки данных. В ней мы избавляемся от работы с файлами, корректно формируем заголовки и контролируем кодировку.


Функция ОтправитьПодтверждениеОтгрузки(Токен, ДанныеОтгрузки)
    
    // Формирование структуры JSON согласно API
    ДанныеData = Новый Структура;
    ДанныеData.Вставить("token", СокрЛП(Токен));
    ДанныеData.Вставить("shipments", ДанныеОтгрузки);
    
    СтруктураОтправки = Новый Структура;
    СтруктураОтправки.Вставить("data", ДанныеData);
    СтруктураОтправки.Вставить("meta", Новый Структура);
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, СтруктураОтправки);
    СтрокаJSON = ЗаписьJSON.Закрыть();
    
    // Подготовка HTTP запроса
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    Заголовки.Вставить("Accept", "application/json");
    // Если документация требует, добавляем Authorization, если нет - убираем
    
    // Используем актуальный адрес API
    АдресСервера = "partner.megamarket.ru";
    ПутьНаСервере = "/api/market/v1/orderService/order/shipping";
    
    HTTPСоединение = Новый HTTPСоединение(АдресСервера, 443, , , , 60, Новый ЗащищенноеСоединениеOpenSSL);
    HTTPЗапрос = Новый HTTPЗапрос(ПутьНаСервере, Заголовки);
    
    // Передаем строку без BOM-маркера
    HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    
    Попытка
        Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
        ОтветСтрока = Ответ.ПолучитьТелоКакСтроку();
        
        Если Ответ.КодСостояния = 200 Тогда
            Сообщить("Запрос успешно отправлен. Ответ сервера: " + ОтветСтрока);
            // Дальнейший разбор успешного ответа
        Иначе
            Сообщить("Ошибка HTTP: " + Ответ.КодСостояния + ". " + ОтветСтрока);
        КонецЕсли;
        
    Исключение
        Сообщить("Ошибка сетевого соединения: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецФункции

Следуя этим правилам, вы навсегда избавитесь от фантомных ошибок синтаксиса при межсистемном обмене. Всегда проверяйте актуальность URL-адресов в документации маркетплейсов и внимательно относитесь к тому, какие типы данных вы передаете в базовые методы платформы 1С. Для настройки интеграции в УТ 11, КА 2 или ERP без ручного написания кода применяется модуль обмена 1С с маркетплейсом МегаМаркет.

← На главную