Простая интеграция Яндекс.Кассы на PHP

Простая интеграция Яндекс.Кассы на PHP

26 января 2022 PHP

На сегодняшний день Яндекс.Касса — это один из самых популярных мерчантов для подключения оплаты на любом сайте. Касса позволяет принимать платежи с помощью банковских карт и Яндекс.Денег, а так же подключить онлайн-кассу.

Если у вас интернет-магазин на одной из популярных CMS, то подключить оплату с помощью Яндекс.Кассы не представит каких-либо проблем. На официальном сайте представлено большое количество готовых модулей для различных CMS, фреймворков и даже мессенджеров. Но что если касса нужна для сайта-каталога без корзины, или например, для сайта-лендинга. В этом случае нужно будет интегрировать Яндекс.Кассу с помощью API.

Модули Яндекс.Кассы

Прием оплаты на сайте со старой версией API был организован, как и у большинства мерчантов, с помощью HTML-формы, отправляющей данные вместе с пользователем на платежный шлюз. На данный момент старая версия API функционирует, и в ближайшее время прекращать его работу не планируется, как сообщает поддержка Яндекс.Кассы. Но все же в документации рекомендуется перейти на новую версию, о чем сигнализирует предупреждение в красной рамке.

Старая версия API

Мы конечно же рассмотрим интеграцию Яндекс.Кассы c новой версией API на PHP.

Получение API-ключа

Для начала необходимо зарегистрироваться на сайте kassa.yandex.ru или авторизоваться с существующим логином и паролем от Яндекс.Почты.

Для получения боевого API-ключа необходимо предоставить документы и подписать договор. Но для начала разработки можно воспользоваться тестовыми ключами, которые после успешного тестирования можно заменить на боевые. Для этого создайте тестовый магазин нажав в верхнем меню Все магазины → Создать тестовый магазин.

Создание тестового магазина

Введите URL-адрес сайта и нажмите «Добавить», после чего, перед вами откроется окно с уже полученными ключами.

Добавление сайта

Если это не произошло, то необходимо выбрать все в том же верхнем меню «Все магазины» вновь добавленный сайт, и перейти в раздел «Ключи API» в левом меню.

Ключи API

HTML-форма

В этом примере создадим форму, в которую пользователь будет самостоятельно вводить номер заказа, сумму, телефон и e-mail, но это все условно, и в вашем случае эти данные могут передаваться автоматически, например в скрытом поле <input type="hidden" name="sum" value="100">

<form id="kassa-form" action="/kassa/pay.php" method="POST">
	<input type="text" name="order" required placeholder="Номер заказа">
	<input type="number" step="0.01" min="1.0" name="sum" required placeholder="Сумма заказа">
	<input type="tel" name="phone" required placeholder="Ваш телефон">
	<input type="email" name="email" required placeholder="Ваш E-mail">
	<input type="submit" name="submit" value="Оплатить">
</form>

Создание платежа

В новой версии API необходимо создать так называемый объект платежа отправив в сервис Яндекс.Кассы сумму и ссылку по которой вернется пользователь на исходный сайт. В ответ касса отдает объект платежа, в котором содержится ссылка на платежный шлюз. В отправленных данных так же можно указать дополнительные параметры, например описание, где мы и будем указывать данные пользователя и заказа.

аренда sony playstation

Для работы с платежами по API Яндекс.Кассы на PHP существует уже готовая библиотека, которую можно скачать здесь.

Скачиваем и разархивируем из архива папку lib. Для всех файлов обработчика я сделал отдельную папку kassa. Туда и добавляем папку lib. Там же создайте файл pay.php. Именно на него будут приходить данные с формы и в нем будет создаваться объект платежа. Далее по полученной ссылке пользователь будет переадресован на оплату в Яндекс.Кассу. Для пользователя это будет происходить практически незаметно. Не забудьте указать ваш секретный ключ и идентификатор магазина полученные ранее в $client->setAuth.

<?
require __DIR__ . '/lib/autoload.php';
use YandexCheckout\Client;

$order = $_POST["order"];
$sum = $_POST["sum"];
$phone = $_POST["phone"];
$email = $_POST["email"];
?>
<?if(!empty($order) && !empty($sum) && !empty($phone) && !empty($email)) {
	$description = 'Заказ № '.$order.' Тел.: '.$phone.' E-mail: '.$email;
	$client = new Client();
	$client->setAuth('<Идентификатор магазина>', '<Секретный ключ>');
	$payment = $client->createPayment(
		array(
			'amount' => array(
				'value' => $sum,
				'currency' => 'RUB',
			),
			'confirmation' => array(
				'type' => 'redirect',
				'return_url' => 'https://it-blog.ru/',
			),
			'capture' => true,
			'description' => $description,
		),
		uniqid('', true)
	);
	header('Location: ' . $payment["confirmation"]["confirmation_url"]);
	?>
	<p>Сейчас вы будете перенаправлены на страницу оплаты, если этого не произошло нажмите на ссылку ниже:</p>
	<p><a href="<?=$payment["confirmation"]["confirmation_url"];?>">Оплатить</a></p>
<?} else {?>
<p>Произошла ошибка. Попробуйте еще раз.</p>
<?}?>

Обработчик получает данные переданные из формы методом POST, и если они существуют, то создает объект платежа, и переадресовывает пользователя по полученной ссылке из объекта. Если что-то идет не так, то выводятся ошибки или предлагается перейти на оплату по ссылке самостоятельно.

Протестировать платеж можно с помощью тестовых карт, например 5555555555554444. В качестве срока действия укажите любую дату (но больше текущей) и любой CVC-код.

Получение уведомления о платеже

После оплаты в личном кабинете, в разделе «Операции» вы можете увидеть полные данные платежа.

История платежей

Чтобы получать мгновенные оповещения, например на E-mail, то необходим обработчик, к которому Яндекс.Касса будет обращаться при каком-либо платежном событии. Для настройки уведомлений перейдите в раздел Интеграция → HTTP-уведомления.

HTTP-уведомления

Включите, те уведомления, сообщения о которых вам необходимо получать. Например payment.succeeded возникает при успешно проведенном платеже. Уведомления можно передавать только на сайт с установленным SSL-сертификатом. Создайте в папке kassa файл mail.php.

<?php
require __DIR__ . '/lib/autoload.php';

// Получите данные из POST-запроса от Яндекс.Кассы
$source = file_get_contents('php://input');
$requestBody = json_decode($source, true);

// Создайте объект класса уведомлений в зависимости от события
// NotificationSucceeded, NotificationWaitingForCapture,
// NotificationCanceled,  NotificationRefundSucceeded

use YandexCheckout\Model\Notification\NotificationSucceeded;
use YandexCheckout\Model\Notification\NotificationWaitingForCapture;
use YandexCheckout\Model\NotificationEventType;
use YandexCheckout\Model\PaymentStatus;

try {
  $notification = ($requestBody['event'] === NotificationEventType::PAYMENT_SUCCEEDED)
	? new NotificationSucceeded($requestBody)
	: new NotificationWaitingForCapture($requestBody);
} catch (Exception $e) {
	// Обработка ошибок при неверных данных
}

// Получите объект платежа
$payment = $notification->getObject();

if($payment->getStatus() === PaymentStatus::SUCCEEDED) {
	// Отправка сообщения
	$mailTo = "[email protected]"; // Ваш e-mail
	$subject = "На сайте совершен платеж"; // Тема сообщения
	// Сообщение
	$message = "Платеж на сумму: " . $payment->amount->value . "<br/>";
	$message .= "Детали платежа: " . $payment->description . "<br/>";
	
	$headers= "MIME-Version: 1.0\r\n";
	$headers .= "Content-type: text/html; charset=utf-8\r\n";
	$headers .= "From: [email protected] <[email protected]>\r\n";
	
	mail($mailTo, $subject, $message, $headers);
}
?>

В случае успешно проведенного платежа, Яндекс.Касса будет обращаться к этому скрипту, который отправит E-mail сообщение. Данные об объекте платежа содержатся в переменной $payment.

Если вам понравилась статья, вы можете отблагодарить автора любой суммой, какую сочтете для себя приемлемой:
Остались вопросы по статье? Задайте их прямо сейчас!
Телеграм бот на PHP отправляющий сообщения с сайта

Что если сообщения с сайта будут приходить не только на ваш e-mail, но и моментально в мессенджер телеграм. Удобно же! Нужно было реализовать такой функционал, ну как и всегда все оказалось довольно просто. Так же стояла задача отправлять сообщения не Читать далее

Отправка формы без перезагрузки страницы на PHP и Ajax

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

Вывести на PHP месяц и день недели на русском

Довольно часто приходится сталкиваться с выводом названий месяцев и дней недели по-русски. При чем в различных вариантах, к примеру с полным названием или сокращенным, с большой буквы или с маленькой. Можно воспользоваться одним из этих 2 вариантов для вывода даты Читать далее

Парсер яндекс погоды на PHP

Рабочий пример PHP парсера, который получает погоду с Яндекса по ID города. Скрипт сохраняет данные в файле кеша на сайте, и обновляет его раз в час. Так же расскажу как выводить на сайте собственные иконки погоды вместо стандартных от Яндекса. Читать далее

Как встроить видео с YouTube канала на сайт

Для вывода списка видеозаписей из канала или плейлиста YouTube на сайте можно воспользоваться этим полностью рабочим решением на PHP. С помощью этой функции можно получить все необходимые данные видеозаписей: название, изображение и идентификатор видео. Вам понадобится идентификатор канала или плейлиста. Читать далее

Курсы доллара и евро с сайта Центробанка на PHP

Парсер получает курсы доллара и евро с сайта Центробанка каждые 24 часа и записывает их в файл кеша /log/course.txt Скрипт полностью готов к работе и не требует каких-либо дополнительных настроек. <? function loadCourse(){ define("tsCourse","15:00:00"); # Время смены курса центральным банком Читать далее

Календарь на PHP и Ajax

Пример календаря на PHP и Ajax с переключением месяцев. Можно использовать как заготовку для решения любых задач. Я использовал его для создания плагина календаря мероприятий на WordPress. Скрипт использует процедурный подход, но имеет разделенную структуру с шаблоном , что довольно Читать далее

24 комментария на «Простая интеграция Яндекс.Кассы на PHP»

  1. Константин:

    Браво!
    Единственная адекватная статья с работоспособным примером

  2. Валерий:

    Помогите, не могу настроить интеграцию.
    Нажимаю Оплатить и вылазит ошибка:
    Fatal error: Uncaught exception ‘YandexCheckout\Common\Exceptions\BadApiRequestException’ with message ‘Receipt is missing or illegal. Error code: invalid_request. Parameter name: receipt.’ in /home/mathvaz/domains/mathvaz.ru/public_html/kassa/lib/Client/BaseClient.php:310 Stack trace: #0 /home/mathvaz/domains/mathvaz.ru/public_html/kassa/lib/Client.php(249): YandexCheckout\Client\BaseClient->handleError(Object(YandexCheckout\Common\ResponseObject)) #1 /home/mathvaz/domains/mathvaz.ru/public_html/kassa/pay.php(27): YandexCheckout\Client->createPayment(Array, ‘5f2c4f8a31b1c7….’) #2 {main} thrown in /home/mathvaz/domains/mathvaz.ru/public_html/kassa/lib/Client/BaseClient.php on line 310

  3. Антон:

    Добрый день!

    Скорее всего вы подключили онлайн кассу в личном кабинете.
    В этом случае необходимо в объекте платежа еще передавать параметр чека receipt. Вот тут подробнее: https://kassa.yandex.ru/developers/54fz/payments

  4. Антон:

    У кого ранее не работало оповещение на E-mail, обновил код файла mail.php, теперь он точно работает, а так же отправляет детали платежа на указанную почту.

  5. Дмитрий Александрович:

    Спасибо огромное!!! Все просто, за 5 мин подключил к форме лэндинга. Я новичок в PHP, самостоятельно очень сложно разобраться! Спасибо, спасибо, спасибо!!!!

  6. Макс:

    Не тот формат заголовка. Как это исправить?

  7. Антон:

    Какая именно ошибка выводится при переходе на оплату?

  8. Макс:

    Fatal error: Uncaught YandexCheckout\Common\Exceptions\UnauthorizedException: Incorrect password format in the Authorization header. Use Secret key issued in Merchant Profile as the password. Error code: invalid_credentials. Parameter name: Authorization

  9. Макс:

    Fatal error: Uncaught YandexCheckout\Common\Exceptions\UnauthorizedException: Incorrect password format in the Authorization header. Use Secret key issued in Merchant Profile as the password. Error code: invalid_credentials. Parameter name: Authorization. in /home/host1820018/host1820018.hostland.pro/htdocs/www/kassa/lib/Client/BaseClient.php:316 Stack trace: #0 /home/host1820018/host1820018.hostland.pro/htdocs/www/kassa/lib/Client.php(249): YandexCheckout\Client\BaseClient->handleError(Object(YandexCheckout\Common\ResponseObject)) #1 /home/host1820018/host1820018.hostland.pro/htdocs/www/kassa/pay.php(26): YandexCheckout\Client->createPayment(Object(YandexCheckout\Request\Payments\CreatePaymentRequest), ‘5f56821c6277b1….’) #2 {main} thrown in /home/host1820018/host1820018.hostland.pro/htdocs/www/kassa/lib/Client/BaseClient.php on line 316

  10. Антон:

    Проверьте, что указан верный секретный ключ в скрипте.

  11. Светлана:

    Скажите, пожалуйста, ‘return_url’ — это адрес, на который возвращается клиент именно после успешной оплаты? Или клиент возвращается на эту страницу в любом случае, независимо от того, прошла оплата или нет. Мне нужно перенаправлять клиента на определенную страницу именно после оплаты, на которой будут расписаны дальнейшие шаги…

  12. Антон:

    На ‘return_url’ пользователь возвращается в любом случае. После возвращения, на этой странице вам надо будет проверять как прошла оплата, и в зависимости от статуса платежа выводить нужную информацию, или как в вашем случае переадресовывать пользователя на другие страницы. Как вариант, можно при создании объекта платежа сохранять его в базу, и менять там его статус, который приходит через HTTP-уведомления, далее проверять успешный платёж или нет.

  13. Светлана:

    Спасибо, Антон, постараюсь разобраться, как это делать… На сайте Яндекс.Касса невозможно вообще ничего понять, если ты не программист. Единственная ваша статья написана человеческим языком))

  14. Артур:

    Добрый день. У меня ошибка 404 по /kassa/pay.php. В чем может быть проблема?

  15. Антон:

    Файл по этому пути не найден.

  16. Алиса:

    Парни подскажите как быть со страницей на которую возвращает Яндекс после оплаты. В документации Яндекса ничего не понятно.
    Я правильно понимаю, я создаю страницу ‘return_url’ на которую пользователь попадает после оплаты и размещаю на этой странице код:

    // Получите данные из POST-запроса от Яндекс.Кассы

    // Создайте объект класса уведомлений в зависимости от события
    // NotificationSucceeded, NotificationWaitingForCapture,
    // NotificationCanceled, NotificationRefundSucceeded

    // Получите объект платежа

    getObject();
    ?>

  17. Алиса:

    use YandexCheckout\Model\Notification\NotificationSucceeded;
    use YandexCheckout\Model\Notification\NotificationWaitingForCapture;
    use YandexCheckout\Model\NotificationEventType;

    try {
    $notification = ($requestBody[‘event’] === NotificationEventType::PAYMENT_SUCCEEDED)
    ? new NotificationSucceeded($requestBody)
    : new NotificationWaitingForCapture($requestBody);
    } catch (Exception $e) {
    // Обработка ошибок при неверных данных
    }

    // Получите объект платежа

    getObject();
    ? >

  18. Алиса:

    Я правильно понимаю, я создаю страницу ‘return_url’ на которую пользователь попадает после оплаты и размещаю на этой странице этот код:
    https://kassa.yandex.ru/developers/using-api/webhooks#sdk-php

    или еще что то нужно, заранее благодарю.

  19. Антон:

    ‘return_url’ — это просто страница, куда переходит пользователь. Делать на ней какой-то функционал, или нет, это уже решать вам. В этом примере пользователь просто переходит на главную страницу.

  20. Дима:

    Ничего не работает. Я надеюсь что я не настолько туп, но всё же. Скопировал в точности файловую систему как здесь указано, прописал id и ключ. И вот что он выводит мне на /kassa/pay.php :

    setAuth(‘*****’, ‘******’); $payment = $client->createPayment( array( ‘amount’ => array( ‘value’ => $sum, ‘currency’ => ‘RUB’, ), ‘confirmation’ => array( ‘type’ => ‘redirect’, ‘return_url’ => ‘https://melishev.ru/’, ), ‘capture’ => true, ‘description’ => $description, ), uniqid(», true) ); header(‘Location: ‘ . $payment[«confirmation»][«confirmation_url»]); ?>
    Сейчас вы будете перенаправлены на страницу оплаты, если этого не произошло нажмите на ссылку ниже:

    Оплатить

    Произошла ошибка. Попробуйте еще раз.

  21. Антон:

    Похоже, что у вас не интерпретируется PHP код, либо ошибка в синтаксисе.

  22. Дима:

    Ну я запускаю на mamp (локальный хостинг), так что вряд ли он не интерпретирует PHP, а по поводу ошибки — я скопировал ваш код в точности, заменив только id магазина и тестовый ключ.

  23. Дима:

    Снизил версию PHP в MAMP, заработало, но теперь в логах события Яндекс касса пишет 400 ошибку «Неправильный запрос. Чаще всего этот статус выдается из-за нарушения правил взаимодействия с API». И сам ответ сервера «»type»: «error»,
    «id»: «a18d6b81-ca19-49da-b861-0262f4ba27b2»,
    «code»: «invalid_request»,
    «description»: «Receipt is missing or illegal»,
    «parameter»: «receipt»»

  24. Богдан:

    Здравствуйте, помогите пожалуйста с ошибкой
    Ошибка — Could not connect to Yandex Money API. Please check your internet connection and try again. (Network error [errno 7]: Failed to connect to payment.yandex.net 10 port 443: No route to host)

    Очень буду благодарен, если поможете

Добавить комментарий