Добрый день! Есть задача интеграции Плати 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" указывается при конструировании запроса как
HTTPЗапрос = Новый HTTPЗапрос("/ru/prod/tokens/v2/oauth" );
Вот мой код для получения кода доступа в сервисе Google
Соединение = Новый 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"];
404 - не найдена страница. Адрес сервера "api.sberbank.ru" (без https) указывается в параметрах соединения, а путь к ресурсу "ru/prod/tokens/v2/oauth" указывается при конструировании запроса как
HTTPЗапрос = Новый HTTPЗапрос("/ru/prod/tokens/v2/oauth" );
Вот мой код для получения кода доступа в сервисе Google
Соединение = Новый 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"];
(5)Выполнил по аналогии, подставив свои значения ID и Secret. Выдает ошибку: {"httpCode":"400", "httpMessage":"Bad Request", "moreInformation":"invalid_scope"}
400 - значит неверный формат запроса или неверное имя ключа или неверный формат данных ключа или ещё что-то )).
Я для отладки использовал сниффер (WireShark). У меня так же был работающий код на Питоне и я сравнивал запросы. Перед этим надо переключиться с https на http. Сервер, конечно, прогонит, но ответ в данном случае не нужен.
{"httpCode":"400","httpMessage":"Bad Request","moreInformation":"local:///authgw/auth/1.0/xsd/Token2Rq.jsd:42: [JSV0001] Invalid value type 'string'."}
В теле запроса параметры grant_type или scope содержат спецсимволы #*!$@%^&*()_+=-'".
Корректные данные параметров для вызова токена можно посмотреть в Параметрах запроса.
Потом я разложил тело запроса как у вас.
ТелоЗапроса = "grant_type=client_credentials";
ТелоЗапроса = ТелоЗапроса + "&scope=https%3A%2F%2Fapi.sberbank.ru%2Forder.create";
ТекстЗапроса = "/ru/prod/tokens/v2/oauth";
HTTPЗапрос = Новый HTTPЗапрос(ТекстЗапроса);
и убрал параметры из ТекстЗапроса
HTTPЗапрос.АдресРесурса = ТекстЗапроса;// + ТелоЗапроса,
Показать
но и без уточнения HTTPЗапрос.АдресРесурса не работало.
Тоже сейчас изучаю этот вопрос. После общения с техподдержкой сбербанка для тестирования в песочнице авторизации и создания заказов все работает без использования сертификата.
Хотя говорят, что требуется обязательно. Но при этом после регистрации на портале я на выходе получил лишь файл .p12 и все.
Авторизацию тоже успешно удалось пройти, получить токен доступа и срок действия токена аж 864000 секунд. Довольно много.
(9)
Сейчас все в стадии регистрации организации. member_ID - выдали после заполнения анкеты и Id_QR должен менеджер сбера сообщить (ID виртуального терминала). После регистрации организации в новом ЛК v3 разработчика будут доступны подписки, пока все в ожидании до 10 октября. У нас сценарий QR Покупателя, поэтому тест возможен только на боевом контуре. Файл сертификата я разбивал на три через openSSL. Он есть в "C:\Apache24\bin\openssl.exe".
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 (сделаны заготовки для реальной базы), осталось как и вам дождаться регистрации организации.
(10) я что-то не понял, в итоге у вас на рабочем сервере взлетело все ? Я после обновления их серверов так и не смог восстановить работу своей интеграции.
(11)
По поводу файла - cacert.pem. У меня сразу не взлетело и я искал все возможные затыки. А так пришлось на двух площадках регистрироваться тоже. Мы пока решили QR Покупателя, хотел оба сразу, но сказали нет пока...
Я так и не понял) Какой по итогу результат? Сам в прошлом году делал интеграцию для загрузки счетов эскроу. Но в декабре у сбера обновились сервера, и все перестало работать) Теперь все время приходит ответ 400
<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.
Запросов моих не видно, логов нет. Хотя ответ то приходит от их сервера.
(16)Попробуйте использовать использовать новое значение scope "https%3A%2F%2Fapi.sberbank.ru%2Fqr%2Forder.create"
Тоже была ошибка 400, оказалось, что они добавили вставку qr в тело запроса.
(18) Такое тоже пробовал. Тут где то проблема с передачей сертификата. Уже преобразовал p12 в pfx, так как меня получается сразу разворачивает nginx. А тех. поддержка уже тупо не отвечает) В последний раз был разговор что через postman работает же у вас, я говорю да, ну так разбирайтесь с вашем 1С, мы то чего =)
(19) Если еще не решили, то посмотрите строку, получаемую методом Base64Строка, там скорее всего спецсимвол закрался, сам с этим час воевал, пока не увидел его по shift + F9 ))
Решил проблему так
tmpIDSecret64 = Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(ID + ":" + Secret));
IDSecret64 = "";
Для й=1 По СтрДлина(tmpIDSecret64) Цикл
симв = Сред(tmpIDSecret64, й, 1);
Если симв > Символ(32) Тогда
IDSecret64 = IDSecret64 + симв;
КонецЕсли;
КонецЦикла;
(20)Проблему нашел, она была в методе ВызватьHTTPМетод, у меня там почему то было put с маленькими буквами, и раньше это прокатывало, а после перехода сбера на новый сервак обработчик запрос видимо изменился. Но странно что если слушать эфир сниффером он показывает что идет put запрос, но при этом идет ошибка 400. Стоило поменять на PUT, все заработало.
Здравствуйте, нужна помощь! Не могу получить токен OAUTH. Сертификат действующий.
Строка Authorization проверена вдоль и поперек - шифруется верно. Ответ на запрос токена следующий:
{"httpCode":"401","httpMessage":"Unauthorized","moreInformation":"Mismatch client ID: CertificateCN != Authorization header
добрый день, столкнулся с ответом, который не задукоментирован, может у кого было - invalid authorization format. Перепробовал, кажется все, что можно. Серты разных типом, скоупы, заворчивание в utf строку из oauth, не помогает.