Как перевести curl запрос на php с передачей сертификатов (api Сбербанка)?
Есть тестовое приложение (к нему подключена подписка Плати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.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для перевода 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;
В данном примере мы указываем путь к файлу сертификата, URL для отправки запроса, создаем новый ресурс cURL, устанавливаем необходимые параметры для SSL-соединения (включая сертификат) и выполняем запрос. После этого мы проверяем наличие ошибок и обрабатываем полученный ответ.
Убедитесь, что путь к файлу сертификата указан правильно и у вас есть все необходимые права доступа к нему. Также не забудьте проверить, что API Сбербанка поддерживает передачу сертификатов в запросах.