При интеграции учетной системы 1С:Предприятие 7.7 со службой доставки Boxberry разработчики часто сталкиваются с ошибкой ответа сервера: «Ошибка входящих данных. Не удалось преобразовать JSON строку обратно в массив». Данное сообщение не содержит информации о конкретном ошибочном поле, что усложняет поиск причины сбоя.
Разберем детально, почему возникает эта ошибка, как правильно составить структуру данных для создания посылки и как корректно отправить HTTP-запрос средствами 1С 7.7.
Выясним причину, по которой парсер на стороне сервера Boxberry отклоняет запрос. При интеграции с API Boxberry обычно допускаются две критические ошибки:
ParselCreate) ожидает данные не в виде сырого JSON (raw application/json), а в формате формы application/x-www-form-urlencoded. В этом формате JSON-строка должна передаваться как значение отдельного POST-параметра (обычно sdata).encodeURIComponent), спецсимволы и кириллица разорвут структуру HTTP-запроса, из-за чего сервер не сможет распарсить значение параметра sdata.Рассмотрим структуру JSON-документа, которую ожидает сервис доставки. Обратите внимание на вложенные объекты спецификации товаров и габаритов посылки.
Посмотрим на пример структуры JSON, содержащей данные получателя, состав заказа и весогабаритные характеристики мест:
{
"updateByTrack": "0",
"order_id": "Заказ-00123",
"PalletNumber": "0",
"barcode": "0",
"price": 4741,
"payment_sum": 4741,
"delivery_sum": 0,
"vid": 1,
"Shop": {
"name": "Основной склад",
"name1": ""
},
"customer": {
"fio": "Иванов Иван Иванович",
"Phone": "9150000000",
"Phone2": "9150000000",
"email": "client@example.com",
"name": "Иванов Иван Иванович",
"adress": "г. Москва, ул. Ленина, д.1, кв.1",
"inn": "",
"kpp": "",
"r_s": "",
"bank": "",
"kor_s": "",
"bik": ""
},
"kurdost": {
"index": "",
"city": "",
"addressp": "",
"timesfrom1": "",
"timesto1": "",
"timesfrom2": "",
"timesto2": "",
"timep": "",
"comentk": ""
},
"items": {
"0": {
"id": "8060",
"name": "Варежки шерстяные",
"UnitName": "шт.",
"nds": "20",
"price": "290",
"quantity": "1"
},
"1": {
"id": "2035",
"name": "Шапка мужская",
"UnitName": "шт.",
"nds": "20",
"price": "790",
"quantity": "1"
}
},
"weights": {
"weight": "0.466",
"barcode": "",
"weight2": "0",
"barcode2": "",
"weight3": "0",
"barcode3": "",
"weight4": "0",
"barcode4": "",
"weight5": "0",
"barcode5": ""
}
}
Обратите внимание на блок items: серверный обработчик PHP на стороне Boxberry корректно воспринимает товарные позиции в виде ассоциативного массива объектов с числовыми ключами "0", "1", "2" и так далее.
Разберем по шагам, как организовать отправку через COM-объект HTTP-клиента (WinHttp.WinHttpRequest.5.1) с правильными заголовками и преобразованием кодировки.
ParselCreate).ДанныеЗаказаJSON).MSScriptControl.ScriptControl (функция encodeURIComponent).token=...&method=...&sdata=....Content-Type со значением application/x-www-form-urlencoded и отправляем POST-запрос.Посмотрим на практический пример кода на языке 1С 7.7:
// Инициализация объекта для работы со скриптами (JScript)
СкриптКонтрол = СоздатьОбъект("MSScriptControl.ScriptControl");
СкриптКонтрол.Language = "JScript";
// Параметры подключения к API
ТокенАвторизации = "10000.rbpqbafb";
Метод = "ParselCreate";
АдресСкрипта = "http://api.boxberry.ru/json.php";
// Кодирование строки JSON в UTF-8 URL-формат
ДанныеЗаказаУТФ8 = СкриптКонтрол.Run("encodeURIComponent", ДанныеЗаказаJSON);
// Формирование тела POST-запроса
ТелоЗапроса = "token=" + ТокенАвторизации + "&method=" + Метод + "&sdata=" + ДанныеЗаказаУТФ8;
// Инициализация HTTP-клиента
ВинХТТП = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
ВинХТТП.Open("POST", АдресСкрипта, 0);
// Установка обязательных заголовков
ВинХТТП.SetRequestHeader("Content-Language", "ru");
ВинХТТП.SetRequestHeader("Content-Charset", "utf-8");
ВинХТТП.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Отправка данных на сервер
ВинХТТП.Send(ТелоЗапроса);
// Проверка статуса ответа
Если ВинХТТП.Status = 200 Тогда
ОтветСервера = ВинХТТП.ResponseText;
Сообщить("Ответ получен: " + ОтветСервера);
Иначе
Сообщить("Ошибка HTTP: " + Строка(ВинХТТП.Status) + " " + ВинХТТП.StatusText);
КонецЕсли;
При чтении свойства ResponseText в 1С 7.7 кириллические символы могут отображаться некорректно («кракозябрами»), так как платформа ожидает строку Windows-1251. Для правильного декодирования ответа рекомендуется считывать бинарный поток ResponseBody через COM-объект ADODB.Stream:
Поток = СоздатьОбъект("ADODB.Stream");
Поток.Type = 1; // adTypeBinary
Поток.Open();
Поток.Write(ВинХТТП.ResponseBody);
Поток.Position = 0;
Поток.Type = 2; // adTypeText
Поток.Charset = "utf-8";
РезультатТекст = Поток.ReadText();
Поток.Close();
Такой подход обеспечивает корректную обработку русскоязычных сообщений об ошибках и номеров накладных, возвращаемых сервером Boxberry.