Добрый день! Есть задача интеграции Плати QR от Сбербанка. Весь процесс запросов заказов на оплату начинается с запроса на получения токена соединения. Я зарегистрировался и получил ID и пароль, а также сертификат OpenSSL для теста. В тестовом шаблоне проверки API в личном кабинете запрос отрабатывает. А при попытке в тестовой обработке. Ответ 404. После ответа от поддержки получил пример авторизации на Pyton. Она выглядит так:
# -*- coding: utf8 -*-
import http.client, ssl, json, base64
from random import choice as c
client_id = ''
client_secret = ''
base64 = base64.b64encode(f'{client_id}:{client_secret}'.encode('utf-8')).decode('utf-8')
def rquid() -> str:
    """Random choice string"""
    return ''.join([c('ABCDEFabcdef1234567890') for _ in range(32)])
def token(scope: str) -> None:
    """Requests Token OAUTH"""
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.load_cert_chain('./client_cert.crt', './private_key.key')
    conn = http.client.HTTPSConnection('api.sberbank.ru', port=443, context=context)
    payload = f'grant_type=client_credentials&scope={scope}'
    headers = {'accept': 'application/json',
               'content-type': 'application/x-www-form-urlencoded',
               'rquid': rquid(),
               'authorization': f'Basic {base64}',
               'x-ibm-client-id': client_id}
    conn.request('POST', 'ru/prod/tokens/v2/oauth', payload, headers)
    data = conn.getresponse().read()
    print(json.loads(data.decode('utf-8'))['access_token'])
token('scope').

Сертификат безопасного подключения описан в запросе как личный + файл ключа
 context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
 context.load_cert_chain('./client_cert.crt', './private_key.key')

В 1С я не смог это реализовать. При помощи OpenSSL я разбил .pfx файл сертификата на три: client_cert.crt, cacerts.cer и private.key.
Добавил описание в bin\cacert.pem описание ключа в формате md5. Вроде все есть. А вот метода подобного Pyton нет.
Только
 ssl1 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто),
            Новый СертификатыУдостоверяющихЦентровWindows());

ssl2 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаWindows(),
            Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));

ssl3 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаФайл("C:/certs/user.p12", "password" ),
            Новый СертификатыУдостоверяющихЦентровФайл("C:/certs/myca.pem"));

ssl4 = Новый ЗащищенноеСоединениеOpenSSL( неопределено, неопределено );

ssl5 = Новый ЗащищенноеСоединениеOpenSSL(
            Новый СертификатКлиентаФайл("C:/certs/user.p13", "password" ),
            Новый СертификатыУдостоверяющихЦентровОС());
Не знаю как решить эту проблему.
---
404 - не найдена страница. Адрес сервера "api.sberbank.ru" (без https) указывается в параметрах соединения, а путь к ресурсу "ru/prod/tokens/v2/oauth" указывается при конструировании запроса как

```1c
    HTTPЗапрос = Новый HTTPЗапрос("/ru/prod/tokens/v2/oauth" );
```

Вот мой код для получения кода доступа в сервисе Google

```1c
    Соединение = Новый HTTPСоединение(
    "oauth2.googleapis.com", // сервер (хост)
    443, // порт, по умолчанию для http используется 80, для https 443
    , // пользователь для доступа к серверу (если он есть)
    , // пароль для доступа к серверу (если он есть)
    , // здесь указывается прокси, если он есть
    , // таймаут в секундах, 0 или пусто - не устанавливать
    Новый ЗащищенноеСоединениеOpenSSL()
    );

    RefreshToken = Ключи["refresh_token"];

    Запрос = Новый HTTPЗапрос("/token");

    ТелоЗапроса = "grant_type=refresh_token";
    ТелоЗапроса = ТелоЗапроса + "&refresh_token="+RefreshToken;
    ТелоЗапроса = ТелоЗапроса + "&client_id= ";
    ТелоЗапроса = ТелоЗапроса + "&client_secret= ";

    Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
    Запрос.Заголовки.Вставить("Content-Type", "Application/X-Www-Form-Urlencoded");

    Результат = Соединение.ВызватьHTTPМетод("POST", Запрос);

    ОтветСтрока = Результат.ПолучитьТелоКакСтроку();

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ОтветСтрока);
    Ответ = ПрочитатьJSON(ЧтениеJSON);

    Ключи["access_token"] = Ответ["access_token"];
```
---
```1c
    Процедура АвторизацияНаСервере()
    GUID = Новый УникальныйИдентификатор();
    СтрокаGUID = СтрЗаменить(Строка(GUID),"-",");
    ID = "837c77a6-2aab-4480-9271-71b85b28****";
    Secret = "M3kJ5bS3pA8nF1bC7tP0tR6hY8dF6rX4lM1oI4rE8wV4fA****";
    IDSecret64 = ШтрихкодВBase64(ID + ":" + Secret);
    Authorization = "Basic " + IDSecret64;

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

    HTTPСоединение = Новый HTTPСоединение("dev.api.sberbank.ru",443,,,,,ssl);

    ПараметрыЗапроса = "?grant_type=client_credentials&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create"; //
    ТекстЗапроса = "https://api.sberbank.ru/ru/prod/tokens/v2/oauth";

    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
    HTTPЗапрос.АдресРесурса = ТекстЗапроса + ПараметрыЗапроса;
    HTTPЗапрос.Заголовки.Вставить("x-ibm-client-id", ID);
    HTTPЗапрос.Заголовки.Вставить("authorization", Authorization);
    HTTPЗапрос.Заголовки.Вставить("rquid", СтрокаGUID);
    HTTPЗапрос.Заголовки.Вставить("content-type","application/x-www-form-urlencoded" ); //"json"
    HTTPЗапрос.Заголовки.Вставить("accept", "application/json");

    Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);

    КонецПроцедуры
```
---
404 - не найдена страница. Адрес сервера "api.sberbank.ru" (без https) указывается в параметрах соединения, а путь к ресурсу "ru/prod/tokens/v2/oauth" указывается при конструировании запроса как

```1c
    HTTPЗапрос = Новый HTTPЗапрос("/ru/prod/tokens/v2/oauth" );
```

Вот мой код для получения кода доступа в сервисе Google

```1c
    Соединение = Новый HTTPСоединение(
    "oauth2.googleapis.com", // сервер (хост)
    443, // порт, по умолчанию для http используется 80, для https 443
    , // пользователь для доступа к серверу (если он есть)
    , // пароль для доступа к серверу (если он есть)
    , // здесь указывается прокси, если он есть
    , // таймаут в секундах, 0 или пусто - не устанавливать
    Новый ЗащищенноеСоединениеOpenSSL()
    );

    RefreshToken = Ключи["refresh_token"];

    Запрос = Новый HTTPЗапрос("/token");

    ТелоЗапроса = "grant_type=refresh_token";
    ТелоЗапроса = ТелоЗапроса + "&refresh_token="+RefreshToken;
    ТелоЗапроса = ТелоЗапроса + "&client_id= ";
    ТелоЗапроса = ТелоЗапроса + "&client_secret= ";

    Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
    Запрос.Заголовки.Вставить("Content-Type", "Application/X-Www-Form-Urlencoded");

    Результат = Соединение.ВызватьHTTPМетод("POST", Запрос);

    ОтветСтрока = Результат.ПолучитьТелоКакСтроку();

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ОтветСтрока);
    Ответ = ПрочитатьJSON(ЧтениеJSON);

    Ключи["access_token"] = Ответ["access_token"];
```
---
"&refresh_token="+RefreshToken;
Спасибо большое! Вот готовый запрос на токен авторизации. Далее запросы на оплату. Тема не закрыта.

```1c
    &НаСервере
    Процедура АвторизацияНаСервере()
    GUID = Новый УникальныйИдентификатор();
    СтрокаGUID = СтрЗаменить(Строка(GUID),"-",");
    ID = "837c77a6-2aab-4480-9271-71b85b280***";
    Secret = "M3kJ5bS3pA8nF1bC7tP0tR6hY8dF6rX4lM1oI4rE8wV4fA***";
    IDSecret64 = ШтрихкодВBase64(ID + ":" + Secret);
    Authorization = "Basic " + IDSecret64;

    ssl = Новый ЗащищенноеСоединениеOpenSSL
    (Новый СертификатКлиентаФайл("H:\QR\private.key","PlatiQR2021")); //400

    HTTPСоединение = Новый HTTPСоединение("dev.api.sberbank.ru",443,,,,,ssl);

    ТелоЗапроса = "grant_type=client_credentials";
    ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create";

    ТекстЗапроса = "/ru/prod/tokens/v2/oauth";

    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
    HTTPЗапрос.АдресРесурса = ТекстЗапроса;// + ТелоЗапроса
    HTTPЗапрос.Заголовки.Вставить("x-ibm-client-id", ID);
    HTTPЗапрос.Заголовки.Вставить("authorization", Authorization);
    HTTPЗапрос.Заголовки.Вставить("rquid", СтрокаGUID);
    HTTPЗапрос.Заголовки.Вставить("content-type","application/x-www-form-urlencoded" ); //"json"
    HTTPЗапрос.Заголовки.Вставить("accept", "application/json");

    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса,КодировкаТекста.UTF8,ИспользованиеByteOrderMark.НеИспользовать); //

    Результат = HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос);

    ОтветСтрока = Результат.ПолучитьТелоКакСтроку();

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ОтветСтрока);
    Ответ = ПрочитатьJSON(ЧтениеJSON);
    КонецПроцедуры
```
---
Выполнил по аналогии, подставив свои значения ID и Secret. Выдает ошибку: {"httpCode":"400", "httpMessage":"Bad Request", "moreInformation":"invalid_scope"}

```1c
    UID = Новый УникальныйИдентификатор();
    СтрокаUID = СтрЗаменить(Строка(UID), "-", ");
    ID = "171170c2-ed76-4b44-9263-xxx";
    Secret = "ea71fac3-5c4f-435b-8314-xxx";
    IDSecret64 = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ID + ":" + Secret));
    Authorization = "Basic " + IDSecret64;

    ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаФайл("Y:\private.key", "xxx")); //400

    HTTPСоединение = Новый HTTPСоединение("api.sberbank.ru", 8443,,,,, ssl);

    ТелоЗапроса = "grant_type=client_credentials";
    ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create";

    ТекстЗапроса = "/ru/prod/tokens/v2/oauth";

    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
    HTTPЗапрос.АдресРесурса = ТекстЗапроса;
    HTTPЗапрос.Заголовки.Вставить("Authorization", Authorization);
    HTTPЗапрос.Заголовки.Вставить("Accept", "application/json");
    HTTPЗапрос.Заголовки.Вставить("X-IBM-Client-Id", ID);
    HTTPЗапрос.Заголовки.Вставить("RqUID", СтрокаUID);
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded" );

    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

    Результат = HTTPСоединение.ВызватьHTTPМетод("POST", HTTPЗапрос);

    ОтветСтрока = Результат.ПолучитьТелоКакСтроку();

    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ОтветСтрока);
    Ответ = ПрочитатьJSON(ЧтениеJSON);
```
---
Нужно использовать новое значение scope "https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create"
---
Вот благодаря вам уже Ошибка 400 и результат

```1c
    GUID = Новый УникальныйИдентификатор();
    СтрокаGUID = СтрЗаменить(Строка(GUID),"-",");
    ID = "837c77a6-2aab-4480-9271-71b85b280***";
    Secret = "M3kJ5bS3pA8nF1bC7tP0tR6hY8dF6rX4lM1oI4rE8wV4fA4***";
    IDSecret64 = ШтрихкодВBase64(ID + ":" + Secret);
    Authorization = "Basic " + IDSecret64;

    ssl = Новый ЗащищенноеСоединениеOpenSSL
    (Новый СертификатКлиентаФайл("H:\QR\private.key","PlatiQR2021"));

    HTTPСоединение = Новый HTTPСоединение("dev.api.sberbank.ru",443,,,,,ssl);

    ТелоЗапроса = "?grant_type=client_credentials&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create"; //
    ТекстЗапроса = "/ru/prod/tokens/v2/oauth";

    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
    HTTPЗапрос.АдресРесурса = ТекстЗапроса + ТелоЗапроса;
    HTTPЗапрос.Заголовки.Вставить("x-ibm-client-id", ID);
    HTTPЗапрос.Заголовки.Вставить("authorization", Authorization);
    HTTPЗапрос.Заголовки.Вставить("rquid", СтрокаGUID);
    HTTPЗапрос.Заголовки.Вставить("content-type","application/x-www-form-urlencoded" );
    HTTPЗапрос.Заголовки.Вставить("accept", "application/json");
    HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса,КодировкаТекста.UTF8 , ИспользованиеByteOrderMark.НеИспользовать); //
    Ответ = HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос);

    "content-type" "application/json"
    "X-RateLimit-Limit" "name=token-test-rate-limit,100;"
    "Access-Control-Allow-Methods" "POST"
    "Access-Control-Expose-Headers" "APIm-Debug-Trans-Id, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-Global-Transaction-ID"
    "X-Global-Transaction-ID" "36eaba96617fb77906c04785"
    "X-RateLimit-Remaining" "name=token-test-rate-limit,99;"
    "User-Agent" "IBM-APIConnect/5.0"
    "Access-Control-Allow-Origin" "*"
    "Date" "Mon, 01 Nov 2021 09:46:33 GMT"
    "Connection" "Keep-Alive"
    "X-Backside-Transport" "OK OK"
    "Transfer-Encoding" "chunked"
```
---
400 - значит неверный формат запроса или неверное имя ключа или неверный формат данных ключа или ещё что-то )).

Я для отладки использовал сниффер (WireShark). У меня так же был работающий код на Питоне и я сравнивал запросы. Перед этим надо переключиться с https на http. Сервер, конечно, прогонит, но ответ в данном случае не нужен.
---
В 5 ответе, уже работающий вариант. За сниффер (WireShark), отдельное спасибо.
---
Ругалось вот так:

{"httpCode":"400","httpMessage":"Bad Request","moreInformation":"local:///authgw/auth/1.0/xsd/Token2Rq.jsd:42: [JSV0001] Invalid value type 'string'."}
В теле запроса параметры grant_type или scope содержат спецсимволы #*!$@%^&*()_+=-'".
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.

Потом я разложил тело запроса как у вас.

```1c
    ТелоЗапроса = "grant_type=client_credentials";
    ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create";

    ТекстЗапроса = "/ru/prod/tokens/v2/oauth";

    HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);

    и убрал параметры из ТекстЗапроса
    HTTPЗапрос.АдресРесурса = ТекстЗапроса;// + ТелоЗапроса,
```

но и без уточнения HTTPЗапрос.АдресРесурса не работало.
---
Тоже сейчас изучаю этот вопрос. После общения с техподдержкой сбербанка для тестирования в песочнице авторизации и создания заказов все работает без использования сертификата.

Хотя говорят, что требуется обязательно. Но при этом после регистрации на портале я на выходе получил лишь файл .p12 и все.

Авторизацию тоже успешно удалось пройти, получить токен доступа и срок действия токена аж 864000 секунд. Довольно много.

ТС, а вы определились, какие значения нужно использовать при создании заказа: member_ID и Id_QR? Тестовые, что в описании API (https://developer.sberbank.ru/api/5df4ada7e4b05210f32c030d) или ТП вам значения выдали?
---
Сейчас все в стадии регистрации организации. member_ID - выдали после заполнения анкеты и Id_QR должен менеджер сбера сообщить (ID виртуального терминала). После регистрации организации в новом ЛК v3 разработчика будут доступны подписки, пока все в ожидании до 10 октября. У нас сценарий QR Покупателя, поэтому тест возможен только на боевом контуре. Файл сертификата я разбивал на три через openSSL. Он есть в "C:\Apache24\bin\openssl.exe".

openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -nodes -nocerts -out H:\QR\private.key -passout pass:PlatiQR2021
openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -clcerts -nokeys -out H:\QR\client_cert.crt
openssl pkcs12 -in "H:\QR\nikiforovvn@mail.ru.p12" -passin pass:PlatiQR2021 -cacerts -nokeys -chain -out H:\QR\cacerts.cer

 PlatiQR2021 - пароль при формировании сертификата.

Потом из client_cert.crt в md5 форматировал. (client_cert.pem) Здесь описание команд openSSL - https://www.openssl.org/docs/man1.0.2/man1/pkcs12.html
Текст из client_cert.pem вставил в конец файла "C:\Program Files (x86)\1cv8\8.3.18.1208\bin\cacert.pem"
---
Спасибо за ответ.

Сертификат тоже смог разбить, но разве недостаточно при создании ssl подключения в 1с указать файл p12 и пароль, чтобы не добавлять в файл cacert.pem информацию по сертификату? Или не взлетело подключение? Дело в том, что на тестовом контуре сертификат не нужен, поэтому явно проверить не удалось.

Я планирую использовать QR-код продавца под каждый заказ покупателя.

В принципе были протестированы все возможные функции API (сделаны заготовки для реальной базы), осталось как и вам дождаться регистрации организации.

Регистрацию уже делали на сайте https://api.developer.sber.ru/ ?
Потому же все тестовые запросы я формировал через сайт https://developer.sberbank.ru
---
я что-то не понял, в итоге у вас на рабочем сервере взлетело все ? Я после обновления их серверов так и не смог восстановить работу своей интеграции.
---
По поводу файла - cacert.pem. У меня сразу не взлетело и я искал все возможные затыки. А так пришлось на двух площадках регистрироваться тоже. Мы пока решили QR Покупателя, хотел оба сразу, но сказали нет пока...
---
Добрый день!
Похоже Сбер переделал что-то,
Потому же все тестовые запросы я формировал через сайт https://developer.sberbank.ru
Захожу на этот сайт, там нет примеров кодов, либо я не увидел...
---
Я так и не понял) Какой по итогу результат? Сам в прошлом году делал интеграцию для загрузки счетов эскроу. Но в декабре у сбера обновились сервера, и все перестало работать) Теперь все время приходит ответ 400

```1c
    <ht ml>
    <head><title>400 Bad Request</title></head>
    <body>
    <center><h1>400 Bad Request</h1></center>
    <hr><center>nginx/1.20.1</center>
    </body>
    </html>
```

Причем делая аналогичный запрос в postman, все работает корректно) Где-то уже месяц с поддержкой общаюсь, и результатов 0.
Запросов моих не видно, логов нет. Хотя ответ то приходит от их сервера.

Вот такие пироги, и куда копать уже не знаю.
---
Попробуйте использовать использовать новое значение scope "https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create"
Тоже была ошибка 400, оказалось, что они добавили вставку qr в тело запроса.

ТелоЗапроса = "grant_type=client_credentials";
ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create";
---
Такое тоже пробовал. Тут где то проблема с передачей сертификата. Уже преобразовал p12 в pfx, так как меня получается сразу разворачивает nginx. А тех. поддержка уже тупо не отвечает) В последний раз был разговор что через postman работает же у вас, я говорю да, ну так разбирайтесь с вашем 1С, мы то чего =)
---
Если еще не решили, то посмотрите строку, получаемую методом Base64Строка, там скорее всего спецсимвол закрался, сам с этим час воевал, пока не увидел его по shift + F9 ))

Решил проблему так

```1c
    tmpIDSecret64 = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ID + ":" + Secret));

    IDSecret64 = ";

    Для й=1 По СтрДлина(tmpIDSecret64) Цикл

    симв = Сред(tmpIDSecret64, й, 1);

    Если симв > Символ(32) Тогда

    IDSecret64 = IDSecret64 + симв;

    КонецЕсли;

    КонецЦикла;
```
---
Проблему нашел, она была в методе ВызватьHTTPМетод, у меня там почему то было put с маленькими буквами, и раньше это прокатывало, а после перехода сбера на новый сервак обработчик запрос видимо изменился. Но странно что если слушать эфир сниффером он показывает что идет put запрос, но при этом идет ошибка 400. Стоило поменять на PUT, все заработало.
---
Здравствуйте, нужна помощь! Не могу получить токен OAUTH. Сертификат действующий.
Строка Authorization проверена вдоль и поперек - шифруется верно. Ответ на запрос токена следующий:
{"httpCode":"401","httpMessage":"Unauthorized","moreInformation":"Mismatch client ID: CertificateCN != Authorization header
---
Решил. CN в сертификате не совпадает с ид клиента. Как так получилось не знаю! Перевыпустил сертификат, все заработало.
---
Что в итоге? на запрос получить реестр или создать код возвращается

{"httpCode":"400","httpMessage":"Bad Request","moreInformation":"Body of the request is not valid according to json schema"}
---
добрый день, столкнулся с ответом, который не задукоментирован, может у кого было - invalid authorization format. Перепробовал, кажется все, что можно. Серты разных типом, скоупы, заворчивание в utf строку из oauth, не помогает.