В этой статье мы подробно разберем ситуацию, с которой часто сталкиваются разработчики при поддержке интеграции с API Сбербанка (сервис «Плати QR» / СБП). Рассмотрим сценарий, когда ранее рабочий код внезапно начинает возвращать ошибку с кодом состояния 400 Bad Request и тестом ошибки:
{
"httpCode": "400",
"httpMessage": "Validation Error. Response phase",
"moreInformation": "/qr/order/v3/creation"
}
Мы проанализируем структуру запроса, заголовки и неочевидные требования к валидации данных, которые могут измениться на стороне банка без предварительного уведомления. Для тех, кто хочет лучше освоить базовые принципы работы с веб-протоколами, рекомендуем пройти интерактивный курс по работе с HTTP-запросами, где подробно разбираются методы GET/POST, заголовки и JSON.
Ошибка HTTP 400 при работе с REST API обычно указывает на то, что сервер не может обработать запрос из-за клиентской ошибки. В случае со Сбербанком сообщение Validation Error прямо говорит о том, что данные в теле запроса (JSON) не прошли проверку по формату или содержимому. Чтобы избежать подобных проблем в будущем, можно внедрить в систему валидатор OpenApi-схем на 1С, который позволяет проверять исходящие пакеты на соответствие контракту еще до их отправки на сервер банка.
Давайте рассмотрим типичный код отправки запроса на создание заказа QR-кода, который использовался до возникновения ошибки:
// Пример формирования заголовков и запроса
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Accept", "application/json");
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("rquid", СтрокаGUID);
HTTPСоединение = Новый HTTPСоединение("mc.api.sberbank.ru", 443,,,, 3600, ssl);
АдресРесурса = "/prod/qr/order/v3/creation";
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
// Установка тела запроса
HTTPЗапрос.УстановитьТелоИзСтроки(JSON, , ИспользованиеByteOrderMark.НеИспользовать);
Результат = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
Если этот код работал ранее, а затем перестал, значит, изменились правила валидации на шлюзе. Основная причина, выявленная в ходе анализа, кроется в содержимом поля description (назначение платежа).
Главным виновником ошибки Validation Error часто является использование недопустимых спецсимволов. Банк ужесточил правила проверки строковых полей для защиты от инъекций и обеспечения совместимости.
Критичная ошибка: Использование символа номера — «№».
Согласно обновленным спецификациям API Сбербанка (регулярное выражение ^[A-Za-zА-Яa-я0-9' '!"#$%&'()*+,-.\/:;<=>?@[\]^_`{|}~]{1,140}), символ «№» не входит в список разрешенных. Его наличие в JSON-строке приводит к мгновенному отказу с 400-й ошибкой.
Решение: Нам необходимо реализовать очистку или замену спецсимволов перед формированием JSON. Давайте напишем функцию, которая подготовит строку описания:
Функция ПодготовитьОписаниеДляСБП(ИсходнаяСтрока)
Результат = СокрЛП(ИсходнаяСтрока);
// Замена символа номера, который вызывает ошибку
Результат = СтрЗаменить(Результат, "№", "N");
// Также рекомендуется убрать переносы строк и кавычки, если они могут сломать JSON
Результат = СтрЗаменить(Результат, Символы.ПС, " ");
Результат = СтрЗаменить(Результат, Символы.ВК, " ");
Результат = СтрЗаменить(Результат, """", "'"); // Замена двойных кавычек на одинарные
// Обрезаем до максимально допустимой длины (обычно 140 символов)
Если СтрДлина(Результат) > 140 Тогда
Результат = Лев(Результат, 140);
КонецЕсли;
Возврат Результат;
КонецФункции
При формировании JSON используйте эту функцию:
СтруктураJSON.Вставить("description", ПодготовитьОписаниеДляСБП(ОписаниеПлатежа));
Помимо спецсимволов, давайте проверим еще два важных момента, которые могут вызывать проблемы на этапе Response phase.
Обратите внимание на различие заголовков на разных этапах обмена:
application/x-www-form-urlencoded./creation) заголовок строго: application/json.Метод 1С УстановитьТелоИзСтроки по умолчанию может добавлять маркер последовательности байтов (BOM) в начало отправляемых данных. Многие банковские API (включая Сбер) не умеют корректно парсить JSON с BOM в начале.
Всегда явно указывайте третий параметр метода:
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапросаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Если вы получили ошибку 400, исправили тело запроса (например, убрали символ «№») и отправили запрос снова с тем же самым RqUID (идентификатором запроса) или order_number, вы снова можете получить ошибку или некорректный ответ, так как банк может посчитать это дублем первоначального ошибочного запроса.
При каждой новой попытке генерации заказа (даже при отладке) генерируйте новый RqUID. Он должен быть строкой из 32 шестнадцатеричных символов (без дефисов).
// Генерация чистого RqUID без дефисов
ГСЧ = Новый ГенераторСлучайныхЧисел;
УИД = Новый УникальныйИдентификатор;
СтрокаGUID = СтрЗаменить(Строка(УИД), "-", ""); // Убираем дефисы для RqUID
Давайте соберем воедино рабочий алгоритм взаимодействия с API mc.api.sberbank.ru. При разработке сложных систем обмена часто бывает полезно использовать универсальный модуль с процедурами для работы с HTTP-сервисами, который позволяет быстро масштабировать ваше API.
Этап 1: Получение токена (OAuth)
Если для авторизации в других сервисах вам когда-либо потребуется более сложная подпись, изучите пример того, как реализуется подпись RSA с хешированием SHA512 в 1С. В случае со Сбербанком обычно достаточно Basic Auth:
// Настройка SSL с сертификатом
ssl = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаФайл(ПутьКСертификату, ПарольСертификата)
);
HTTPСоединение = Новый HTTPСоединение("mc.api.sberbank.ru", 443,,,, 5, ssl);
// Формируем Basic Auth из ClientID и Secret
СтрокаAuth = ClientID + ":" + ClientSecret;
Двоичные = ПолучитьДвоичныеДанныеИзСтроки(СтрокаAuth, КодировкаТекста.UTF8, Ложь);
AuthorizationBasic = "Basic " + ПолучитьBase64СтрокуИзДвоичныхДанных(Двоичные);
// Очистка от переносов строк, которые могут добавить Base64 функции
AuthorizationBasic = СтрЗаменить(AuthorizationBasic, Символы.ПС, "");
AuthorizationBasic = СтрЗаменить(AuthorizationBasic, Символы.ВК, "");
АдресТокена = "/prod/tokens/v3/oauth";
HTTPЗапрос = Новый HTTPЗапрос(АдресТокена);
// Важные заголовки для получения токена
HTTPЗапрос.Заголовки.Вставить("Authorization", AuthorizationBasic);
HTTPЗапрос.Заголовки.Вставить("x-ibm-client-id", ClientID);
HTTPЗапрос.Заголовки.Вставить("rquid", СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""));
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");
ТелоЗапроса = "grant_type=client_credentials&scope=https://api.sberbank.ru/qr/order.create";
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса);
Ответ = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
// ... здесь парсим JSON ответа и извлекаем access_token
Этап 2: Создание заказа QR (Исправленный)
Чтобы организовать интеграцию между системами 1С без боли и страданий, важно придерживаться строгой типизации данных в JSON. Ниже приведен пример исправленного запроса:
// Используем полученный Токен
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
// Для самого заказа тип контента JSON!
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Accept", "application/json");
Заголовки.Вставить("rquid", СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""));
АдресРесурса = "/prod/qr/order/v3/creation";
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
// Формируем JSON (пример структуры)
СтруктураЗаказа = Новый Структура;
СтруктураЗаказа.Вставить("rq_uid", СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", ""));
СтруктураЗаказа.Вставить("rq_tm", Формат(ТекущаяДатаСеанса(), "ДФ=yyyy-MM-ddTHH:mm:ss") + "Z");
СтруктураЗаказа.Вставить("member_id", MemberID);
СтруктураЗаказа.Вставить("order_number", НомерЗаказа);
СтруктураЗаказа.Вставить("order_sum", СуммаВКопейках); // Внимательно! Сумма часто в копейках
СтруктураЗаказа.Вставить("currency", "643");
// ВАЖНО: Используем функцию очистки описания
СтруктураЗаказа.Вставить("description", ПодготовитьОписаниеДляСБП(ОписаниеЗаказа));
СтруктураЗаказа.Вставить("sbp_member_id", SBPMemberID);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураЗаказа);
СтрокаJSON = ЗаписьJSON.Закрыть();
// Отправка без BOM
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Результат = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);
Стоит упомянуть, что у Сбербанка существует другой шлюз — для интернет-эквайринга (адрес ecommerce.sberbank.ru). Работа с ним отличается: авторизация происходит по логину и паролю (без сертификатов), а методы API другие (/register.do). Если вы планируете создание BackEnd на 1С для мобильного приложения с поддержкой оплаты, обязательно уточните, какой именно протокол обмена используется в вашем договоре.
Однако проблема с валидацией спецсимволов, таких как «№», актуальна для большинства банковских API. Поэтому рекомендация по очистке поля description остается универсальной.
Для исправления ошибки 400 при работе со Сбер СБП:
description, заменив его на латинскую «N».RqUID уникален для каждого запроса и не содержит дефисов.ИспользованиеByteOrderMark.НеИспользовать).Content-Type: application/json для запросов бизнес-логики.