Задать вопрос
@Elven_77

Как перевести 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


При выполнении запроса, получаю ответ:
{"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 ;


в ответ получаю:
{"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"

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

ТП Сбера отказывается помогать, ТП хостера тоже. Не знаю что и делать.
  • Вопрос задан
  • 902 просмотра
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
kawabanga
@kawabanga
ChatGPT:

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

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


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

require 'vendor/autoload.php'; // Путь к файлу autoload.php из установленного Guzzle через Composer

use GuzzleHttp\Client;

$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.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы