Оплата заказов на сайте через Робокассу

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

Для корректной работы скриптов потребуется сделать настройки в разделе «Мои магазины» – «Настройки» – вкладка «​Технические настройки».

В форме нужно заполнить следующие поля:

  • Алгоритм расчета хеша: md5
  • Сгенерировать «Пароль #1» и «Пароль #2» (пока их запомнить)
  • Указать «Result Url», используется для оповещения о платеже, например:
    https://ваш_домен/pay_result.php
  • «Success Url» – адрес, куда будет перенаправлен пользователь после успешной оплаты:
    https://example.com/pay_success.php
  • «Fail Url» – адрес перенаправления в случаи ошибки или отмены платежа:
    https://ваш_домен/pay_error.php
  • Сгенерировать «Пароль #1» и «Пароль #2» для тестовых платежей, пока работать будем с ними.

На сайте заказы будут хранится в таблице `orders` c полями:

  • id – номер заказа,
  • status – статус заказа (1 - создан, 2 - оплачен, 3 - ошибка),
  • name – имя клиента,
  • text – комментарий,
  • sum – сумма заказа,
  • date_add – дата в формате unix timestamp.
CREATE TABLE `orders` (
  `id` int(11) UNSIGNED NOT NULL,
  `status` int(1) NOT NULL DEFAULT '0',
  `name` varchar(255) NOT NULL,
  `text` text NOT NULL,
  `sum` int(11) NOT NULL,
  `date_add` int(11) UNSIGNED NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `orders` ADD PRIMARY KEY (`id`);
ALTER TABLE `orders` MODIFY `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;
SQL

Для того чтобы направить пользователя на оплату, нужно добавить заказ в БД, получить его ID и сформировать URL на Робокассу.

Для упращениния отладки платежей, нужно включить тестовый режим, добавив в URL параметр IsTest=1 (не нужно будет вводить реквизиты карт).

Скрипт оформления заказа:

<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');

// Данные заказа	
$form['sum']   = '100';	
$form['name']  = 'Иван Иванов';	
$form['text']  = 'Комментарий к заказу';

// Добавление заказа в БД.
$sth = $dbh->prepare("
	INSERT INTO
		`orders`
	SET
		`name`        = :name,
		`text`        = :text,        
		`sum`         = :sum,
		`status`      = 1,
		`date_add`    = UNIX_TIMESTAMP()
");
$sth->execute($form);
 
// Получаем id вставленной записи
$order_id = $dbh->lastInsertId();

if ($order_id) {
	// Пароль #1 (для тестовых платежей)
	$mrh_pass1 = "******************"; 

	$params = array(
		'MerchantLogin' => 'Test',                // Идентификатор магазина
		'InvId'         => $order_id,             // ID заказа
		'Description'   => 'Заказ №' . $order_id, // Описание заказа (мах 100 символов)
		'OutSum'        => $form['sum'],          // Сумма заказа
		'Culture'       => 'ru',   
		'Encoding'      => 'utf-8',   
		'IsTest'        => 1,                     // Тестовый режим
	);

	// Формирование подписи
	$params['SignatureValue'] = md5("{$params['MerchantLogin']}:{$params['OutSum']}:{$params['InvId']}:{$mrh_pass1}"); 
	
	// Перенаправляем пользователя на страницу оплаты
	header('Location: https://auth.robokassa.ru/Merchant/Index.aspx?' . urldecode(http_build_query($params)));
	exit;
	
	// Или вывод ссылки
	//echo '<a href="https://auth.robokassa.ru/Merchant/Index.aspx?' . urldecode(http_build_query($params)) . '">';
}
PHP

Перейдя по сформированной ссылки, откроется форма оплаты на робокассе:

После того, как пользователь успешно оплатил заказ, он будет перенаправлен на «Success Url» с добавлением GET-параметров с данными платежа:

https://ваш_домен/pay_success.php?OutSum=100.00&InvId=1&SignatureValue=dd11434a7003d76a052910c75d8d31dc&IsTest=1&Culture=ru

В PHP-скрипте нужно сверить SignatureValue и обновить статус заказа в базе данных.

Скрипт pay_success.php

<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');

// Пароль #1 (для тестовых платежей)
$mrh_pass1 = '********************';

// Чтение параметров
$inv_id  = intval(@$_GET['InvId']);
$out_sum = @$_GET['OutSum'];
$crc     = strtoupper(@$_GET['SignatureValue']); 
		
if (empty($inv_id)) {
	echo 'Произошла ошибка';
} else {
	$sth = $dbh->prepare("SELECT * FROM `orders` WHERE `id` = ?");
	$sth->execute($inv_id);
	$order = $sth->fetch(PDO::FETCH_ASSOC);
	if (!empty($order)) {
		$my_crc = strtoupper(md5("$out_sum:$inv_id:$mrh_pass1"));
		if ($my_crc == $crc) {
			// Обновление статуса
			$sth = $dbh->prepare("UPDATE `orders` SET `status` = 2 WHERE `id` = ?");
			$sth->execute($inv_id);
			echo 'Ваш платеж обработан.';			
		} else {
			echo 'Произошла ошибка';
		}
	} else {
		echo 'Произошла ошибка';
	}
}
PHP

Т.к. пользователь может не вернутся обратно на сайт, Робакасса отправляет дополнительный запрос на «Result Url» с ожиданием ответа, пример такого запроса:

https://ваш_домен/pay_result.php?&out_summ=100&OutSum=100&inv_id=1&InvId=1&crc=dd11434a7003d76a052910c75d8d31dc&SignatureValue=dd11434a7003d76a052910c75d8d31dc&PaymentMethod=BankCard&IncSum=3000&IncCurrLabel=BankCardPSR&IsTest=1&EMail=&Fee=0.0

Скрипт pay_result.php

<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');

// Пароль #2 (для тестовых платежей)
$mrh_pass2 = '********************'; 

$inv_id  = intval(@$_GET['InvId']); 
$out_sum = @$_GET['OutSum'];
$crc     = strtoupper(@$_GET['SignatureValue']); 

if (!empty($inv_id)) {
	$sth = $dbh->prepare("SELECT * FROM `orders` WHERE `id` = ?");
	$sth->execute($inv_id);
	$order = $sth->fetch(PDO::FETCH_ASSOC);
	if (!empty($order)) {
		$my_crc = strtoupper(md5("$out_sum:$inv_id:$mrh_pass2"));
		if ($my_crc == $crc) {
			// Обновление статуса
			$sth = $dbh->prepare("UPDATE `orders` SET `status` = 2 WHERE `id` = ?");
			$sth->execute($inv_id);

			echo "OK$inv_id\n";
			exit();			
		} 			
	}
}

echo "bad sign\n";
exit();
PHP

В случаи отмены операции, пользователь перенаправляется на «Fail Url»:

https://ваш_домен/pay_error.php?OutSum=100.00&InvId=1&IsTest=1&Culture=ru

Скрипт pay_error.php

<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'логин', 'пароль');

$inv_id   = intval(@$_GET['InvId']);
$out_sum  = @$_GET['OutSum'];

if (!empty($inv_id)) {
	// Обновление статуса
	$sth = $dbh->prepare("UPDATE `orders` SET `status` = 3 WHERE `id` = ?");
	$sth->execute($inv_id);
	echo 'Платеж отменен';			
} else {
	echo 'Произошла ошибка';			
}
PHP

После окончания тестирования, нужно убрать параметр IsTest, пароли сменить на постоянные и далее можно подавать запрос на активировацию магазина в Робокассе.

05.02.2021, обновлено 12.04.2022
10934

Комментарии

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

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

Работа с ценами PHP
Приведение цен к общему типу, форматирование и вывод цен.
12035
+3
Создание товарной накладной в PHPExcel
Пример, как сформировать товарную накладную с помощью библиотеки PHPExcel. В результате получится файл в формате xlsx...
16744
+6
Вычисление процентов в PHP
Примеры и функции для расчёта процентов, скидок и наценок.
27057
+12
Генерация счета на оплату PDF PHP
С помощью расширения dompdf можно легко сформировать PDF файл. По сути, dompdf - это конвертер HTML в PDF который...
47982
+29
Расчёт средней закупочной или продажной цены
Если речь идет о закупках/продажах одного товара по разным ценам и разным количеством подойдет средняя арифметическая...
1436
0
Прием платежей на сайте через Юкассу
В данной статье описан процесс оплаты через сервис ЮKassa с помощью прямых запросов к API через PHP cURL.
11331
+5