Простая интеграция Яндекс.Кассы на PHP
На сегодняшний день Яндекс.Касса — это один из самых популярных мерчантов для подключения оплаты на любом сайте. Касса позволяет принимать платежи с помощью банковских карт и Яндекс.Денег, а так же подключить онлайн-кассу.
Если у вас интернет-магазин на одной из популярных CMS, то подключить оплату с помощью Яндекс.Кассы не представит каких-либо проблем. На официальном сайте представлено большое количество готовых модулей для различных CMS, фреймворков и даже мессенджеров. Но что если касса нужна для сайта-каталога без корзины, или например, для сайта-лендинга. В этом случае нужно будет интегрировать Яндекс.Кассу с помощью API.
Прием оплаты на сайте со старой версией API был организован, как и у большинства мерчантов, с помощью HTML-формы, отправляющей данные вместе с пользователем на платежный шлюз. На данный момент старая версия API функционирует, и в ближайшее время прекращать его работу не планируется, как сообщает поддержка Яндекс.Кассы. Но все же в документации рекомендуется перейти на новую версию, о чем сигнализирует предупреждение в красной рамке.
Мы конечно же рассмотрим интеграцию Яндекс.Кассы c новой версией API на PHP.
Получение API-ключа
Для начала необходимо зарегистрироваться на сайте kassa.yandex.ru или авторизоваться с существующим логином и паролем от Яндекс.Почты.
Для получения боевого API-ключа необходимо предоставить документы и подписать договор. Но для начала разработки можно воспользоваться тестовыми ключами, которые после успешного тестирования можно заменить на боевые. Для этого создайте тестовый магазин нажав в верхнем меню Все магазины → Создать тестовый магазин.
Введите URL-адрес сайта и нажмите «Добавить», после чего, перед вами откроется окно с уже полученными ключами.
Если это не произошло, то необходимо выбрать все в том же верхнем меню «Все магазины» вновь добавленный сайт, и перейти в раздел «Ключи 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 необходимо создать так называемый объект платежа отправив в сервис Яндекс.Кассы сумму и ссылку по которой вернется пользователь на исходный сайт. В ответ касса отдает объект платежа, в котором содержится ссылка на платежный шлюз. В отправленных данных так же можно указать дополнительные параметры, например описание, где мы и будем указывать данные пользователя и заказа.
Для работы с платежами по 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-уведомления.
Включите, те уведомления, сообщения о которых вам необходимо получать. Например 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
.
Браво!
Единственная адекватная статья с работоспособным примером
Помогите, не могу настроить интеграцию.
Нажимаю Оплатить и вылазит ошибка:
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
Добрый день!
Скорее всего вы подключили онлайн кассу в личном кабинете.
В этом случае необходимо в объекте платежа еще передавать параметр чека receipt. Вот тут подробнее: https://kassa.yandex.ru/developers/54fz/payments
У кого ранее не работало оповещение на E-mail, обновил код файла mail.php, теперь он точно работает, а так же отправляет детали платежа на указанную почту.
Спасибо огромное!!! Все просто, за 5 мин подключил к форме лэндинга. Я новичок в PHP, самостоятельно очень сложно разобраться! Спасибо, спасибо, спасибо!!!!
Не тот формат заголовка. Как это исправить?
Какая именно ошибка выводится при переходе на оплату?
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
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
Проверьте, что указан верный секретный ключ в скрипте.
Скажите, пожалуйста, ‘return_url’ — это адрес, на который возвращается клиент именно после успешной оплаты? Или клиент возвращается на эту страницу в любом случае, независимо от того, прошла оплата или нет. Мне нужно перенаправлять клиента на определенную страницу именно после оплаты, на которой будут расписаны дальнейшие шаги…
На ‘return_url’ пользователь возвращается в любом случае. После возвращения, на этой странице вам надо будет проверять как прошла оплата, и в зависимости от статуса платежа выводить нужную информацию, или как в вашем случае переадресовывать пользователя на другие страницы. Как вариант, можно при создании объекта платежа сохранять его в базу, и менять там его статус, который приходит через HTTP-уведомления, далее проверять успешный платёж или нет.
Спасибо, Антон, постараюсь разобраться, как это делать… На сайте Яндекс.Касса невозможно вообще ничего понять, если ты не программист. Единственная ваша статья написана человеческим языком))
Добрый день. У меня ошибка 404 по /kassa/pay.php. В чем может быть проблема?
Файл по этому пути не найден.
Парни подскажите как быть со страницей на которую возвращает Яндекс после оплаты. В документации Яндекса ничего не понятно.
Я правильно понимаю, я создаю страницу ‘return_url’ на которую пользователь попадает после оплаты и размещаю на этой странице код:
// Получите данные из POST-запроса от Яндекс.Кассы
// Создайте объект класса уведомлений в зависимости от события
// NotificationSucceeded, NotificationWaitingForCapture,
// NotificationCanceled, NotificationRefundSucceeded
// Получите объект платежа
getObject();
?>
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();
? >
Я правильно понимаю, я создаю страницу ‘return_url’ на которую пользователь попадает после оплаты и размещаю на этой странице этот код:
https://kassa.yandex.ru/developers/using-api/webhooks#sdk-php
или еще что то нужно, заранее благодарю.
‘return_url’ — это просто страница, куда переходит пользователь. Делать на ней какой-то функционал, или нет, это уже решать вам. В этом примере пользователь просто переходит на главную страницу.
Ничего не работает. Я надеюсь что я не настолько туп, но всё же. Скопировал в точности файловую систему как здесь указано, прописал 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»]); ?>
Сейчас вы будете перенаправлены на страницу оплаты, если этого не произошло нажмите на ссылку ниже:
Оплатить
Произошла ошибка. Попробуйте еще раз.
Похоже, что у вас не интерпретируется PHP код, либо ошибка в синтаксисе.
Ну я запускаю на mamp (локальный хостинг), так что вряд ли он не интерпретирует PHP, а по поводу ошибки — я скопировал ваш код в точности, заменив только id магазина и тестовый ключ.
Снизил версию PHP в MAMP, заработало, но теперь в логах события Яндекс касса пишет 400 ошибку «Неправильный запрос. Чаще всего этот статус выдается из-за нарушения правил взаимодействия с API». И сам ответ сервера «»type»: «error»,
«id»: «a18d6b81-ca19-49da-b861-0262f4ba27b2»,
«code»: «invalid_request»,
«description»: «Receipt is missing or illegal»,
«parameter»: «receipt»»
Здравствуйте, помогите пожалуйста с ошибкой
Ошибка — 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)
Очень буду благодарен, если поможете