Как перевести curl запрос на php с передачей сертификатов (api Сбербанка)?

Ссылка скопирована
1 ответ

Есть тестовое приложение (к нему подключена подписка ПлатиQR, включен тестовый SandBox SberPay.QR и поставлены заглушки через ТП ) зарегистрированное на api.developer.sberbank.ru

Для него имеются:
https://api.developer.sber.ru/how-to-use/token_oauth
Сертификат полученный от Сбера (пароль RiKZcN3Z) и сертификат Минцифры https://disk.yandex.ru/d/QnKdVBIFhyqM_w

На хостинге используется php 5.6

Есть рабочий curl запрос (работает в терминале и получает в ответ токен):

curl --location --request POST 'https://mc.api.sberbank.ru:443/prod/tokens/v3/oauth'  --header 'RqUID: 25Ec70328e2CE4DF39e828E1dF75EFa0'  --header 'Authorization: Basic MTgwYmYzNTItNDlhZC00MGVhLTgyYmItMDcwMTRiMjdjODQ5OjUwM2NhNmUwLWE5OWEtNDYzZC05OTIzLWJlZWUzYjVhYzYzNA=='  --header 'Content-Type: application/x-www-form-urlencoded'  --data-urlencode 'grant_type=client_credentials'  --data-urlencode 'scope=https://api.sberbank.ru/qr/order.create'  --cert-type P12 --cert {абсолютный путь до серта}/certif.p12:RiKZcN3Z  --cacert {абсолютный путь до серта}/russian-trusted-cacert.pem

curl --location --request POST 'https://mc.api.sberbank.ru:443/prod/tokens/v3/oauth' --header 'RqUID: 25Ec70328e2CE4DF39e828E1dF75EFa0' --header 'Authorization: Basic MTgwYmYzNTItNDlhZC00MGVhLTgyYmItMDcwMTRiMjdjODQ5OjUwM2NhNmUwLWE5OWEtNDYzZC05OTIzLWJlZWUzYjVhYzYzNA==' --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=client_credentials' --data-urlencode 'scope=https://api.sberbank.ru/qr/order.create' --cert-type P12 --cert {абсолютный путь до серта}/certif.p12:RiKZcN3Z --cacert {абсолютный путь до серта}/russian-trusted-cacert.pem

При выполнении запроса, получаю ответ:

{"access_token":"066b7134-45a1-45b6-88b9-5234b34c4c59","expires_in":60,"scope":"https://api.sberbank.ru/qr/order.create","session_state":"3851e870-5a62-4ee7-8074-884685f31a81","token_type":"bearer"}

{"access_token":"066b7134-45a1-45b6-88b9-5234b34c4c59","expires_in":60,"scope":"https://api.sberbank.ru/qr/order.create","session_state":"3851e870-5a62-4ee7-8074-884685f31a81","token_type":"bearer"}

сделал на php curl запрос:

$token_url = "https://mc.api.sberbank.ru/prod/tokens/v3/oauth"; $client_id = "180bf352-49ad-40ea-82bb-07014b27c849"; $client_secret = "80254d2c-a9fb-40fd-a3a0-d68da8549d75";  function getAccessToken() { 	global $token_url, $client_id, $client_secret;          $data = http_build_query(array(         "grant_type"  => "client_credentials",         "scope" => "https://api.sberbank.ru/order.create"                                ));  	$authorization = base64_encode("$client_id:$client_secret"); 	$header = array("accept: application/json", "Authorization: Basic ".$authorization,"Content-Type: application/x-www-form-urlencoded","rquid: 25Ec70328e2CE4DF39e828E1dF75EFa0"); 	$sCertPath="{абсолютный путь до серта}/certif.p12"; 	$sCertPath2="{абсолютный путь до серта}/russian-trusted-cacert.pem";         $sCertPassword="RiKZcN3Z"; 	$curl = curl_init(); 	curl_setopt_array($curl, array( 		CURLOPT_URL => $token_url, 		CURLOPT_HTTPHEADER => $header, 		CURLOPT_SSLCERTTYPE => "P12", 		CURLOPT_SSLCERT => $sCertPath, 		CURLOPT_SSLCERTPASSWD => $sCertPassword,                 CURLOPT_CAINFO => $sCertPath2, 		CURLOPT_CAPATH => $sCertPath2,                 CURLOPT_RETURNTRANSFER => true, 		CURLOPT_POST => true, 		CURLOPT_POSTFIELDS => $data 	)); 	$response = curl_exec($curl); 	curl_close($curl);  // return json_decode($response)->access_token;     return $response; }  $access_token = getAccessToken(); echo $access_token ;

$token_url = "https://mc.api.sberbank.ru/prod/tokens/v3/oauth"; $client_id = "180bf352-49ad-40ea-82bb-07014b27c849"; $client_secret = "80254d2c-a9fb-40fd-a3a0-d68da8549d75"; function getAccessToken() { global $token_url, $client_id, $client_secret; $data = http_build_query(array( "grant_type" => "client_credentials", "scope" => "https://api.sberbank.ru/order.create" )); $authorization = base64_encode("$client_id:$client_secret"); $header = array("accept: application/json", "Authorization: Basic ".$authorization,"Content-Type: application/x-www-form-urlencoded","rquid: 25Ec70328e2CE4DF39e828E1dF75EFa0"); $sCertPath="{абсолютный путь до серта}/certif.p12"; $sCertPath2="{абсолютный путь до серта}/russian-trusted-cacert.pem"; $sCertPassword="RiKZcN3Z"; $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => $token_url, CURLOPT_HTTPHEADER => $header, CURLOPT_SSLCERTTYPE => "P12", CURLOPT_SSLCERT => $sCertPath, CURLOPT_SSLCERTPASSWD => $sCertPassword, CURLOPT_CAINFO => $sCertPath2, CURLOPT_CAPATH => $sCertPath2, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $data )); $response = curl_exec($curl); curl_close($curl); // return json_decode($response)->access_token; return $response; } $access_token = getAccessToken(); echo $access_token ;

в ответ получаю:

{"httpCode":"400", "httpMessage":"Bad Request", "moreInformation":"unauthorized_client"}

{"httpCode":"400", "httpMessage":"Bad Request", "moreInformation":"unauthorized_client"}

Помогите составить корректный запрос на php.

Смотрел похожий пост: Как скормить курлу сертификаты сбербанка для приложения, если они проверки openssl не проходят и вообще не читаются?, но там в основном про сертификат.

Думал проблема в сертификате минцифры. Хостер отказывается на сервере добавлять сертификат в глобальное хранилище. пробую добавлять серт в запрос через CURLOPT_CAINFO, CURLOPT_CAPATH.

Добавление в htaccess:

php_value curl.cainfo "/home/e/elven/lk.logohelp.pro/public_html/ca-certificates.crt" php_value openssl.cafile "/home/e/elven/lk.logohelp.pro/public_html/ca-certificates.crt"

php_value curl.cainfo "/home/e/elven/lk.logohelp.pro/public_html/ca-certificates.crt" php_value openssl.cafile "/home/e/elven/lk.logohelp.pro/public_html/ca-certificates.crt"

тоже не помогло.

ТП Сбера отказывается помогать, ТП хостера тоже. Не знаю что и делать.

Дополнительно:

думаю что ошибка в $sCertPath, тут нужен сертификат, а не весь контейнер
извлекаю сертификат из .p12

openssl pkcs12 -in certificate.p12 -out file_crt.pem -clcerts -nokeys

openssl pkcs12 -in certificate.p12 -out file_crt.pem -clcerts -nokeys

потом

curl_setopt($curl, CURLOPT_SSLCERT,  'путьдофайла/file_crt.pem');

curl_setopt($curl, CURLOPT_SSLCERT, 'путьдофайла/file_crt.pem');

и scope https://api.sberbank.ru/qr/order.create, хотя где-то в доках сбера указана ссылка без qr
у меня завелось без установки Guzzle

ChatGPT:

Для отправки этого cURL запроса в Guzzle PHP, вам потребуется установить Guzzle HTTP клиент, если он еще не установлен. Выполните следующие шаги:

Установите Guzzle через Composer (если вы этого еще не сделали):

composer require guzzlehttp/guzzle

В вашем PHP-скрипте используйте следующий код для отправки запроса:

<?php  require 'vendor/autoload.php'; // Путь к файлу autoload.php из установленного Guzzle через Composer  use GuzzleHttpClient;  $baseUrl = 'https://mc.api.sberbank.ru/prod/tokens/v3/oauth'; $rqUID = '25Ec70328e2CE4DF39e828E1dF75EFa0'; $authorization = 'Basic MTgwYmYzNTItNDlhZC00MGVhLTgyYmItMDcwMTRiMjdjODQ5OjUwM2NhNmUwLWE5OWEtNDYzZC05OTIzLWJlZWUzYjVhYzYzNA=='; $scope = 'https://api.sberbank.ru/qr/order.create'; $certPath = '/absolute/path/to/certif.p12'; $certPassword = 'RiKZcN3Z'; $cacertPath = '/absolute/path/to/russian-trusted-cacert.pem';  $client = new Client();  $response = $client->request('POST', $baseUrl, [     'headers' => [         'RqUID' => $rqUID,         'Authorization' => $authorization,         'Content-Type' => 'application/x-www-form-urlencoded',     ],     'form_params' => [         'grant_type' => 'client_credentials',         'scope' => $scope,     ],     'cert' => [$certPath, $certPassword],     'verify' => $cacertPath, ]);  // Выводим результат запроса echo $response->getBody()->getContents();

<?php require 'vendor/autoload.php'; // Путь к файлу autoload.php из установленного Guzzle через Composer use GuzzleHttpClient; $baseUrl = 'https://mc.api.sberbank.ru/prod/tokens/v3/oauth'; $rqUID = '25Ec70328e2CE4DF39e828E1dF75EFa0'; $authorization = 'Basic MTgwYmYzNTItNDlhZC00MGVhLTgyYmItMDcwMTRiMjdjODQ5OjUwM2NhNmUwLWE5OWEtNDYzZC05OTIzLWJlZWUzYjVhYzYzNA=='; $scope = 'https://api.sberbank.ru/qr/order.create'; $certPath = '/absolute/path/to/certif.p12'; $certPassword = 'RiKZcN3Z'; $cacertPath = '/absolute/path/to/russian-trusted-cacert.pem'; $client = new Client(); $response = $client->request('POST', $baseUrl, [ 'headers' => [ 'RqUID' => $rqUID, 'Authorization' => $authorization, 'Content-Type' => 'application/x-www-form-urlencoded', ], 'form_params' => [ 'grant_type' => 'client_credentials', 'scope' => $scope, ], 'cert' => [$certPath, $certPassword], 'verify' => $cacertPath, ]); // Выводим результат запроса echo $response->getBody()->getContents();

Пожалуйста, замените /absolute/path/to/certif.p12 и /absolute/path/to/russian-trusted-cacert.pem на абсолютные пути к вашим сертификатам. Также убедитесь, что у вас есть правильные данные для RqUID и Authorization заголовков.

Этот код отправит POST запрос с указанными данными и получит ответ от сервера Sberbank.

  • Большое, спасибо! Получилось
  • Elven_77, у меня подобная проблема. Я не поняла, а в чём у вас было таки дело? Вроде бы в ответе Dmitry Bay всё то же самое, что и в вашем вопросе, только на Guzzle.
Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Юрий Linux Ответ

Для перевода curl запроса на PHP с передачей сертификатов для API Сбербанка, вам потребуется использовать функцию curl_setopt для установки необходимых параметров. Ниже приведен пример кода на PHP, который демонстрирует это:

// Путь к файлу сертификата
$certPath = '/path/to/certificate.pem';
 
// URL для отправки запроса
$url = 'https://api.sberbank.com';
 
// Создаем новый ресурс cURL
$ch = curl_init();
 
// Устанавливаем параметры запроса
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_CAINFO, $certPath);
 
// Выполняем запрос
$response = curl_exec($ch);
 
// Проверяем наличие ошибок
if (curl_errno($ch)) {
    echo 'Ошибка: ' . curl_error($ch);
}
 
// Закрываем соединение
curl_close($ch);
 
// Обрабатываем ответ
echo $response;

// Путь к файлу сертификата $certPath = '/path/to/certificate.pem'; // URL для отправки запроса $url = 'https://api.sberbank.com'; // Создаем новый ресурс cURL $ch = curl_init(); // Устанавливаем параметры запроса curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_CAINFO, $certPath); // Выполняем запрос $response = curl_exec($ch); // Проверяем наличие ошибок if (curl_errno($ch)) { echo 'Ошибка: ' . curl_error($ch); } // Закрываем соединение curl_close($ch); // Обрабатываем ответ echo $response;

В данном примере мы указываем путь к файлу сертификата, URL для отправки запроса, создаем новый ресурс cURL, устанавливаем необходимые параметры для SSL-соединения (включая сертификат) и выполняем запрос. После этого мы проверяем наличие ошибок и обрабатываем полученный ответ.

Убедитесь, что путь к файлу сертификата указан правильно и у вас есть все необходимые права доступа к нему. Также не забудьте проверить, что API Сбербанка поддерживает передачу сертификатов в запросах.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно