Прием платежей на сайте через Юкассу

В данной статье описан процесс оплаты через сервис ЮKassa с помощью прямых запросов к API через PHP cURL. Также существует уже готовый SDK (с установкой через Composer).

1

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

Далее потребуется сгенерировать секретный ключ для доступа к API в разделе «Интеграция» – «Ключи API».​

2

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

В запросе к API нужно передать значение идемпотентности, т.е. уникальное значение операции на стороне сайта. Без этого значения API возвращает ошибку, сгенерировать ключ можно с помощью функции:

function gen_uuid() {
	return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
		mt_rand( 0, 0xffff ),
		mt_rand( 0, 0x0fff ) | 0x4000,
		mt_rand( 0, 0x3fff ) | 0x8000,
		mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff )
	);
}
PHP

Отправка платежных данных:

$data = array(
	'amount' => array(
 		'value' => 1000,
 		'currency' => 'RUB',
 	),
 	'capture' => true,
 	'confirmation' => array(
 		'type' => 'redirect',
 		'return_url' => 'https://example.com/success',
 	),
	'description' => 'Заказ №1',
	'metadata' => array(
 		'order_id' => 1,
 	)
);

$data = json_encode($data, JSON_UNESCAPED_UNICODE);
 	
$ch = curl_init('https://api.yookassa.ru/v3/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_USERPWD, 'ЛОГИН:КЛЮЧ');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Idempotence-Key: ' . gen_uuid()));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 	
$res = curl_exec($ch);
curl_close($ch);	
	
$res = json_decode($res, true);
print_r($res);
PHP

Ответ API:

Array(
	[id] => xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    [status] => pending
    [paid] => 
    [amount] => Array(
    	[value] => 1000.00
        [currency] => RUB
	) 
	[confirmation] => Array(
       	[type] => redirect
		[confirmation_url] => https://yoomoney.ru/checkout/payments/v2/contract?orderId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
	)
	[created_at] => 2021-05-01T05:13:52.233Z
	[description] => Заказ №1
	[metadata] => Array (
		[order_id] => 1
	)
	[recipient] => Array (
		[account_id] => 123456
		[gateway_id] => 12345678
	)
	[refundable] => [test] => 1
)

В ответе содержится номер заказа в Юкассе, его необходимо сохранить и ссылка на форму оплаты.

Редиректим пользователя на форму оплаты:

header('Location: ' . $res['confirmation']['confirmation_url'], true, 301);
exit();
PHP
Форма оплаты Юкассы

Чтобы завершить платеж нужно ввести реквизиты тестовой карты. После чего, платежная система вернет пользователя на указанный return_url без параметра статуса оплаты.

У Юкассы есть возможность уведомлений о платежах, подробнее на https://yookassa.ru/developers/using-api/webhooks

3

Получить данные платежа и его статус можно по его ID, отправив запрос:

$order_id = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx';

$ch = curl_init('https://api.yookassa.ru/v3/payments/' . $order_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERPWD, 'ЛОГИН:КЛЮЧ');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Idempotence-Key: ' . gen_uuid()));
$res = curl_exec($ch);
curl_close($ch);
	
$res = json_decode($res, true);
print_r($res);
PHP

Результат:

Array(
    [id] => xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    [status] => succeeded
    [paid] => 1
    [amount] => Array(
		[value] => 1000.00
		[currency] => RUB
	)
    [authorization_details] => Array(
		[rrn] => 2494615456943
		[auth_code] => 592673
	)
    [captured_at] => 2021-05-01T11:36:41.750Z
    [created_at] => 2021-05-01T11:36:06.124Z
    [description] => Заказ №1
    [income_amount] => Array(
		[value] => 1000.50
		[currency] => RUB
	)
    [metadata] => Array(
		[order_id] => 1
	)
    [payment_method] => Array(
		[type] => bank_card
		[id] => xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
		[saved] => 
		[card] => Array(
			[first6] => 555555
			[last4] => 4477
			[expiry_month] => 11
			[expiry_year] => 2023
			[card_type] => MasterCard
			[issuer_country] => US
		)

		[title] => Bank card *5555
	)

    [recipient] => Array(
		[account_id] => 123456
		[gateway_id] => 12345678
	)

    [refundable] => 1
    [refunded_amount] => Array(
		[value] => 0.00
		[currency] => RUB
	)
    [test] => 1
)

Статусы платежа

  • pending – платеж создан и ожидает действий от пользователя.
  • waiting_for_capture – платеж оплачен, деньги авторизованы и ожидают списания (при двухстадийной оплате).
  • succeeded – платеж успешно завершен.
  • canceled – платеж отменен
13.05.2021, обновлено 12.04.2022
24016
Следующая запись Округление чисел в PHP

Комментарии 5

Александр Симонов Александр Симонов
10 февраля 2022 в 15:35
Здравствуй, если можете помочь реализовать такую интеграцию. Пишите в телеграмм @SimonovAle обсудим.
Буду очень благодарен!
Фаниль Аминев Фаниль Аминев
14 октября 2023 в 18:52
Добрый день! Сделал интеграцию платежей для своего магазина на локальной машине. Спасибо, все прекрасно работает. Переношу на сервер, меняю shopId и ключ на боевые - не работает. На запрос о формировании ссылки выдает следующее:
Array
(
[type] => error
[id] => 0a38b760-0af2-4224-8888-e0fa8fda23ec
[code] => invalid_request
[description] => Receipt is missing or illegal
[parameter] => receipt
)
Помогите, пожалуйста! Что может быть?
Vladimir Rubtsov Vladimir Rubtsov
18 октября 2023 в 12:50
Ругается на отсутствие информации о чеке. Видимо в "боевом" магазине включена онлайн-касса.
У себя в коде добавил:
"receipt" => array(
	"customer" => array(
		"email" => $_POST['email'],
	),
	"items" => array(
		array(
			"description" => "Описание услуги",
			"quantity" => "1.00",
			"amount" => array(
					"value" => $_POST['sum'],
					"currency" => "RUB"
			),
			"tax_system_code" => "1",
			"vat_code" => "1",
			"payment_mode" => "full_prepayment",
			"payment_subject" => "service"
		)
	)
)
Сергей Кучуков Сергей Кучуков
22 февраля 2024 в 11:53
Спасибо, огромное, Добрый человек! Наконец-то подробный пример где всё работает!
Сергей Мещанов Сергей Мещанов
21 апреля 2024 в 12:31
с получением данных о платеже не понятно ничего. на return_url не приходит на каких параметров. покупатель попадает сюда в любом случае - оплатитл или нет. как получить ID платежа. внутренний order_id не проходит

, чтобы добавить комментарий.

Другие публикации

Платежи на сайте через IntellectMoney PHP
Пример PHP-скриптов для оплаты заказов на сайте через экваринг Intellectmoney.
2607
+2
Оплата заказов на сайте через Робокассу
В данной статье описан процесс оплаты заказа на сайте с помощью Робокассы. Перед тем, как преступить работе над...
23986
+8
Генерация счета на оплату PDF PHP
С помощью расширения dompdf можно легко сформировать PDF файл. По сути, dompdf - это конвертер HTML в PDF который...
66099
+33
Яндекс.Доставка работа с API в PHP
Примеры работы с API Яндекс.Доставки (для заказа перевозки грузов корпоративным клиентам).
8747
+5
Прием платежей на сайте через интернет-эквайринг Тинькофф
Предварительно, чтобы реализовать оплату заказов на своем сайте через API Интернет-эквайринга банка Тинькофф...
22965
+15
Автоматическое сжатие и оптимизация картинок на сайте
Изображения нужно сжимать для ускорения скорости загрузки сайта, но как это сделать? На многих хостингах нет...
28512
+8