Как получить токен подключения для API Плати QR Сбербанка в 1С?

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

При интеграции с внешними системами, такими как API Плати QR Сбербанка (для этого есть интеграция 1С с API Плати QR Сбербанка), одним из первых и наиболее ответственных шагов является получение токена авторизации. Этот токен необходим для всех последующих запросов к API, позволяющих создавать заказы, проверять их статус и выполнять другие операции. Однако процесс получения токена в 1С может быть сопряжен с различными техническими нюансами, включая особенности работы с HTTP-соединениями, SSL-сертификатами, кодированием данных и правильной структурой запросов. Рассмотрим этот процесс подробно, проанализируем распространенные ошибки и предложим эффективные решения.

Поток авторизации OAuth 2.0 Client Credentials Flow

Для авторизации серверных приложений (т.е. когда приложение действует от собственного имени, а не от имени конечного пользователя) Сбербанк использует поток "Client Credentials" (учетные данные клиента) протокола OAuth 2.0, как и в случае с авторизацией в сервисах Яндекс. В рамках этого потока, приложение обменивает свои уникальные идентификаторы — Client ID и Client Secret — на временный Access Token (механика схожа с Google OAuth 2.0).

Access Token — это строка, которая подтверждает право вашего приложения на выполнение определенных операций. Он имеет ограниченный срок действия (например, 60 минут или несколько часов), после чего его необходимо обновлять (аналогично работе через сервисный аккаунт Google), запрашивая новый токен по той же схеме. В некоторых случаях может быть предоставлен Refresh Token с более длительным сроком действия, но для данного потока, как правило, мы работаем непосредственно с постоянным обновлением Access Token.

Для успешной работы с API Плати QR вам также потребуются другие ключевые идентификаторы, которые вы получаете после регистрации и подписания договора со Сбербанком:

  1. Client ID: Уникальный идентификатор вашего приложения, выданный при регистрации на портале разработчиков.
  2. Client Secret: Секретный ключ вашего приложения, который выдается один раз при регистрации. Его необходимо хранить в безопасности.
  3. member_ID: Идентификатор организации, полученный после заполнения анкеты и оформления договора со Сбербанком.
  4. Terminal ID (TID) / ID QR: Идентификатор виртуального терминала или QR-кода, который сообщает менеджер Сбербанка.

Подготовка к интеграции: Регистрация и получение данных

Прежде чем приступать к написанию кода в 1С, вам необходимо выполнить ряд предварительных шагов на стороне Сбербанка:

  1. Подача заявки на подключение Плати QR СБП: Обратитесь в Сбербанк и пройдите процедуру подключения услуги "Плати QR СБП" для вашей организации — поможет автоматизация оплаты по QR-коду через виртуальный терминал.
  2. Регистрация на портале разработчиков Sber API: Зарегистрируйтесь на сайте
    
    api.developer.sber.ru
    
    . Здесь вы сможете создать свое приложение и подписаться на необходимые API.
  3. Получение Client ID и Client Secret: После создания приложения на портале разработчиков вам будут выданы Client ID и Client Secret. Client Secret обычно показывается только один раз, поэтому крайне важно сохранить его в надежном месте.
  4. Подписка на тариф: Через каталог API на портале разработчиков подпишитесь на нужный тариф, например, "QR для Продавца" или "Плати QR".
  5. Получение member_ID и ID QR: После завершения всех юридических и организационных процедур (заполнение анкеты, подписание договора) ваш менеджер Сбербанка предоставит вам member_ID и ID QR (Terminal ID) — для этого подойдёт реализация приема платежей по QR-коду в 1С.
  6. Получение SSL-сертификата: Сбербанк обычно предоставляет клиентский SSL-сертификат в формате .p12. Он будет необходим для обеспечения безопасного соединения с API в продуктивной среде.

Настройка сертификатов в 1С:Предприятии

Для обеспечения безопасного соединения HTTPS в 1С, особенно в продуктивной среде, требуется использовать клиентский SSL-сертификат. Сбербанк чаще всего предоставляет его в формате .p12 (также известный как PKCS#12 или PFX), который содержит как публичный сертификат, так и закрытый ключ.

Работа с .p12 файлом напрямую в 1С

Наиболее простой способ использования сертификата в 1С – это передача .p12 файла напрямую в конструктор ЗащищенноеСоединениеOpenSSL. Для этого вам понадобится путь к файлу и пароль, который был установлен при создании или получении этого .p12 файла.


// Пример использования .p12 сертификата
ssl = Новый ЗащищенноеСоединениеOpenSSL(
    Новый СертификатКлиентаФайл("H:\QR\nikiforovvn@mail.ru.p12", "PlatiQR2021")
);

Здесь H:\QR\nikiforovvn@mail.ru.p12 – это полный путь к вашему сертификату, а PlatiQR2021 – пароль от этого сертификата.

Преобразование сертификата с помощью OpenSSL

В некоторых случаях, особенно при отладке или если требуется более гибкое управление ключами (поможет инструмент для пошаговой отладки HTTP-запросов в 1С), может потребоваться разделить .p12 файл на отдельные компоненты: публичный сертификат (.crt или .pem) и закрытый ключ (.key). Это можно сделать с помощью утилиты OpenSSL, которая часто поставляется с веб-сервеверами, такими как Apache, или устанавливается отдельно.

Предположим, ваш .p12 файл называется nikiforovvn@mail.ru.p12 и его пароль PlatiQR2021. Ниже приведены команды для извлечения компонентов:

  1. Извлечение закрытого ключа (private.key):

    Эта команда извлекает закрытый ключ без шифрования (параметр -nodes).

    openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -nodes -nocerts -out H:\QR\private.key
  2. Извлечение публичного клиентского сертификата (client_cert.crt):

    Эта команда извлекает только публичный сертификат клиента.

    openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -clcerts -nokeys -out H:\QR\client_cert.crt
  3. Извлечение цепочки сертификатов удостоверяющих центров (cacerts.cer):

    Эта команда извлекает сертификаты удостоверяющих центров.

    openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -cacerts -nokeys -chain -out H:\QR\cacerts.cer

После извлечения закрытого ключа (например, private.key), вы можете использовать его в 1С. Однако, как показал опыт, использование .p12 файла напрямую часто оказывается более надежным, поскольку он содержит всю необходимую информацию.


// Пример использования закрытого ключа, если .p12 не работает напрямую
// Обратите внимание, что 1С может требовать публичный сертификат отдельно или в объединенном формате
ssl = Новый ЗащищенноеСоединениеOpenSSL(
    Новый СертификатКлиентаФайл("H:\QR\private.key", "PlatiQR2021") // Пароль от ключа, если он зашифрован
);

В случае проблем с валидацией сертификата сервера, может потребоваться добавление цепочки сертификатов удостоверяющих центров (извлеченных из cacerts.cer) в хранилище 1С, которое используется по умолчанию (C:\Program Files (x86)\1cv8\\bin\cacert.pem), или явное их указание в конструкторе ЗащищенноеСоединениеOpenSSL.

Формирование запроса на получение токена в 1С

Теперь, когда мы понимаем, как работать с сертификатами и какие данные нам нужны, перейдем к непосредственному формированию HTTP-запроса на получение токена в 1С.

Общие принципы формирования запроса

Запрос на токен выполняется методом POST. Целевой URL зависит от используемого контура:

Важно правильно сформировать заголовки запроса и его тело, соблюдая все требования API.

Пошаговое формирование запроса в 1С

Рассмотрим полный пример кода, объединяющий лучшие практики и решения проблем, найденные в ходе обсуждения.


&НаСервере
Процедура ПолучитьТокенСберБанк()
    
    // 1. Идентификаторы клиента и секрета
    // Используйте свои актуальные Client ID и Client Secret
    ID = "837c77a6-2aab-4480-9271-xxxxxxxxxxxx"; 
    Secret = "M3kJ5bS3pA8nF1bC7tP0tR6hY8dF6rX4lM1oI4rE8wV4fAxxxxxxxxxxxx";
    
    // 2. Генерируем уникальный идентификатор запроса (RqUID)
    GUID = Новый УникальныйИдентификатор;
    СтрокаGUID = СтрЗаменить(Строка(GUID),"-","");
    
    // 3. Кодируем Client ID:Client Secret в Base64 для заголовка Authorization
    // Важно: Удалить все лишние символы (пробелы, переносы строк) из Base64-строки
    ДвоичныеДанныеДляBase64 = ПолучитьДвоичныеДанныеИзСтроки(ID + ":" + Secret, КодировкаТекста.UTF8);
    tmpIDSecret64 = Base64Строка(ДвоичныеДанныеДляBase64);
    
    IDSecret64 = "";
    Для й=1 По СтрДлина(tmpIDSecret64) Цикл
        СимволТекущий = Сред(tmpIDSecret64, й, 1);
        Если СимволТекущий > Символ(32) Тогда // Удаляем символы с ASCII кодом <= 32 (пробелы, переносы строк и т.п.)
            IDSecret64 = IDSecret64 + СимволТекущий;
        КонецЕсли;
    КонецЦикла;
    
    Authorization = "Basic " + IDSecret64;
    
    // 4. Настраиваем защищенное соединение (SSL)
    // Используем .p12 файл напрямую. Замените путь и пароль на свои.
    // В тестовом контуре иногда работает без сертификата, но для прода он обязателен.
    Попытка
        ssl = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаФайл("H:\QR\nikiforovvn@mail.ru.p12", "PlatiQR2021")
        );
    Исключение
        Сообщить("Ошибка при загрузке сертификата: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // 5. Создаем HTTP-соединение
    // Используем тестовый контур "dev.api.sberbank.ru" и порт 443 (стандартный для HTTPS)
    Попытка
        HTTPСоединение = Новый HTTPСоединение("dev.api.sberbank.ru", 443, , , , , ssl);
    Исключение
        Сообщить("Ошибка при создании HTTP-соединения: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    // 6. Формируем тело запроса
    // grant_type всегда "client_credentials" для данного потока
    // scope - это критически важный параметр, определяющий права.
    // Для Плати QR создания заказа используется "https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create"
    ТелоЗапроса = "grant_type=client_credentials";
    ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create";
    
    // 7. Определяем адрес ресурса для запроса токена
    ТекстЗапроса = "/ru/prod/tokens/v2/oauth";
    
    // 8. Создаем HTTP-запрос
    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
    
    // Адрес ресурса устанавливается из переменной ТекстЗапроса, параметры передаются в теле.
    HTTPЗапрос.АдресРесурса = ТекстЗапроса; 
    
    // 9. Устанавливаем заголовки запроса
    HTTPЗапрос.Заголовки.Вставить("Authorization", Authorization);           // Base64-кодированный ID:Secret
    HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");             // Ожидаем JSON в ответ
    HTTPЗапрос.Заголовки.Вставить("X-IBM-Client-Id", ID);                     // Ваш Client ID
    HTTPЗапрос.Заголовки.Вставить("RqUID", СтрокаGUID);                       // Уникальный ID запроса
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded"); // Тип контента тела запроса
    
    // 10. Устанавливаем тело запроса
    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    
    // 11. Отправляем запрос и получаем ответ
    Попытка
        Результат = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос); // Метод должен быть "POST" (заглавными буквами!)
        
        // 12. Обрабатываем ответ
        Если Результат.КодСостояния = 200 Тогда
            ОтветСтрока = Результат.ПолучитьТелоКакСтроку();
            ЧтениеJSON = Новый ЧтениеJSON;
            ЧтениеJSON.УстановитьСтроку(ОтветСтрока);
            Ответ = ПрочитатьJSON(ЧтениеJSON);
            
            Сообщить("Токен успешно получен!");
            Сообщить("Access Token: " + Ответ["access_token"]);
            Сообщить("Тип токена: " + Ответ["token_type"]);
            Сообщить("Срок действия (секунд): " + Ответ["expires_in"]);
            
            // Здесь вы можете сохранить полученный токен для дальнейшего использования
            // Например, во временном хранилище или глобальной переменной.
            
            Возврат Ответ["access_token"];
            
        Иначе
            Сообщить("Ошибка получения токена. Код состояния: " + Результат.КодСостояния);
            Сообщить("Текст ошибки: " + Результат.ПолучитьТелоКакСтроку());
            Возврат Неопределено;
        КонецЕсли;
        
    Исключение
        Сообщить("Произошла ошибка при отправке HTTP-запроса: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;
    
КонецПроцедуры

Разбор типичных ошибок и их устранение

В процессе интеграции могут возникать различные ошибки. Рассмотрим наиболее частые из них и способы их решения.

  1. 404 Not Found

    Эта ошибка указывает на то, что запрашиваемый ресурс не найден на сервере. Чаще всего причина кроется в неверном URL или пути к ресурсу.

    Причины и решения:

    • Неверный домен: Убедитесь, что вы используете правильный домен для тестового (dev.api.sberbank.ru) или продуктивного (api.sberbank.ru) контура.
    • Неверный путь: Проверьте, что путь к ресурсу токена (/ru/prod/tokens/v2/oauth) указан абсолютно точно. Убедитесь, что в HTTPЗапрос.АдресРесурса не дублируются части пути или не добавляются лишние параметры, которые должны быть в теле запроса. Например, избегайте конструкций типа HTTPЗапрос.АдресРесурса = ТекстЗапроса + ПараметрыЗапроса;, если параметры должны идти в теле.
  2. 400 Bad Request

    Одна из самых распространенных и общих ошибок, указывающая на некорректно сформированный запрос. Она может быть вызвана множеством факторов.

    Причины и решения:

    • Неверный scope ("moreInformation":"invalid_scope"): Это очень частая причина. Параметр scope определяет, к каким операциям API вы запрашиваете доступ. Неверное или устаревшее значение scope приведет к ошибке. Для создания заказа через QR Сбербанка необходимо использовать scope=https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create. Всегда сверяйтесь с актуальной документацией Сбербанка для точных значений scope для каждой операции (например, для отмены заказа, получения статуса, реестра).
    • Неправильный формат тела запроса: Убедитесь, что заголовок Content-Type установлен в application/x-www-form-urlencoded и тело запроса сформировано в соответствии с этим форматом (например, grant_type=client_credentials&scope=...).
    • Проблемы с кодировкой или BOM: При использовании HTTPЗапрос.УстановитьТелоИзСтроки() убедитесь, что используется кодировка UTF8 и ИспользованиеByteOrderMark.НеИспользовать.
    • Лишние символы в строках: Пробелы, символы перевода строки или другие непечатаемые символы в Client ID, Client Secret или в результирующей Base64-строке для заголовка Authorization могут вызвать ошибку. Используйте код для очистки Base64-строки, как показано в примере выше (Если СимволТекущий > Символ(32) Тогда...).
    • Неверный HTTP-метод или регистр: Метод должен быть POST. Обратите внимание, что в 1С он должен быть указан заглавными буквами: "POST", а не "post". В старых версиях 1С или на некоторых серверах мог работать нижний регистр, но это непостоянное поведение.
    • Тело запроса не соответствует JSON-схеме ("Body of the request is not valid according to json schema"): Эта ошибка чаще относится к последующим запросам (например, созданию заказа), которые используют application/json, а не к запросу токена. В этом случае проверьте структуру вашего JSON-тела на соответствие документации API.
  3. 401 Unauthorized

    Эта ошибка означает, что предоставленные учетные данные для аутентификации недействительны или отсутствуют.

    Причины и решения:

    • Неверное кодирование Client ID:Client Secret в Base64: Проверьте, что строка Client ID:Client Secret корректно кодируется в Base64, и полученная строка не содержит лишних символов.
    • "moreInformation":"Mismatch client ID: CertificateCN != Authorization header": Это критически важное сообщение. Оно указывает, что Common Name (CN) в клиентском SSL-сертификате, который вы используете для установления защищенного соединения, не соответствует Client ID, переданному в заголовке Authorization. Убедитесь, что сертификат выдан именно на тот Client ID, который вы используете в запросе. Возможно, потребуется перевыпустить сертификат или использовать правильный сертификат.
    • Неверный формат заголовка Authorization ("invalid authorization format"): Убедитесь, что заголовок начинается с "Basic " (с пробелом) и далее следует корректная Base64-строка.

Инструменты отладки

При возникновении сложностей в процессе интеграции полезно использовать специализированные инструменты отладки, которые помогут проанализировать отправляемые запросы и получаемые ответы — для этого есть сбор и анализ HTTP-запросов для поиска ошибок интеграции.

  1. Postman (или аналоги):

    Отличный инструмент для тестирования API-запросов. Если ваш запрос успешно работает в Postman, но не в 1С, это сужает круг проблем до особенностей реализации в 1С (работа с сертификатами, кодировка, особенности HTTP-соединения). Вы можете сравнить точные заголовки и тело запроса, отправляемые из Postman, с теми, что формируются в 1С.

  2. WireShark (или Fiddler):

    Сетевой сниффер, который позволяет перехватывать и анализировать весь HTTP/HTTPS трафик, проходящий через вашу систему. С его помощью вы можете увидеть фактические байты, отправляемые и принимаемые по сети. Это позволяет сравнить запросы, отправляемые из вашей 1С, с эталонными (например, из Python-примера или Postman), чтобы выявить тонкие различия в заголовках, теле запроса или поведении SSL/TLS.

    Для отладки с WireShark иногда полезно временно переключиться на HTTP, если это возможно и безопасно для тестового контура, чтобы легче анализировать трафик без расшифровки HTTPS. Однако для продуктивного использования всегда используйте HTTPS.

  3. Техническая поддержка Сбербанка:

    При возникновении неразрешимых проблем, особенно если ошибки связаны с серверной частью или неясной документацией, не стесняйтесь обращаться в техническую поддержку Сбербанка. Предоставьте им максимально полную информацию о вашем запросе, полученных ошибках и идентификаторах запроса (RqUID), которые вы отправляли.

Надеемся, что это подробное руководство поможет вам успешно интегрировать Плати QR от Сбербанка с вашей системой 1С:Предприятие. Помните, что ключ к успеху лежит в внимательном следовании документации, тщательной проверке всех параметров и использовании инструментов отладки для выявления и устранения проблем.

← На главную