Интеграция с платежной системой PayKeeper в PHP

Платежная платформа PayKeeper позволяет принимать оплату заказов по ссылке, используя данный метод можно с легкостью сделать онлайн-оплату на сайте.

1

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

Подробнее о протоколе передачи данных а документации JSON API.

/* Доступы к Paykeeper */
$server   = 'https://xxxxx.server.paykeeper.ru';
$user     = 'admin';
$password = 'xxxxxxxxxx';

/* Данные клиента */
$email = '';
$phone = '';
	
/* Номер заказа */
$order_id = 9999; 

/* Массив товаров в заказе */
$basket = array(
	array(
		'name'  => 'Тортилья, 20 см, 756 г',
		'count' => '5',
		'price' => '381.00'
	)
);

/* Собираем массив товаров для paykeeper */
/* https://docs.paykeeper.ru/onlain-kassa-54-fz/tovary-v-cheke-54-fz-full/ */
$total = 0;
$prods  = array();

foreach ($basket as $row) {
	$prods[] = array(
		'name'      => $row['name'],
		'price'     => $row['price'],
		'quantity'  => $row['count'],
		'sum'       => $row['price'] * $row['count'],
		'tax'       => 'none',
		'item_type' => 'goods',
	);
	
	$total += $row['price'] * $row['count'];
}

/* Доставка */
$prods[] = array(
	'name'      => 'Доставка',
	'price'     => 300,
	'quantity'  => 1,
	'sum'       => 390,
	'tax'       => 'none',
	'item_type' => 'service',
);

$total += 300;


/* Авторизация в Paykeeper */
$base64 = base64_encode($user . ':' . $password);
$headers = array(); 
array_push($headers, 'Content-Type: application/x-www-form-urlencoded');
array_push($headers, 'Authorization: Basic ' . $base64);

$curl = curl_init($server . '/info/settings/token/'); 
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$response = curl_exec($curl);
$response = json_decode($response, true);

/* В ответе должен быть token, иначе ошибка */
if (isset($response['token'])) {
	$token = $response['token']; 
	
	/* Готовим запрос 3.4 JSON API на получение счёта */
	$payment_data = array (
		'pay_amount'   => $total,
		'orderid'      => $order_id,
		'service_name' => ';PKC|' . json_encode($prods) . '|',
		'client_email' => $email,
		'client_phone' => $phone,
	);

	$request = http_build_query(array_merge($payment_data, array('token' => $token)));

	curl_setopt($curl, CURLOPT_URL, $server . '/change/invoice/preview/');
	curl_setopt($curl, CURLOPT_HTTPHEADER , $headers);
	curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
	curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_HEADER, false);
	$response = curl_exec($curl);
	curl_close($curl);
	$response = json_decode($response, true);

	/* В ответе должен быть invoice_id */
	if (isset($response['invoice_id'])) {
		$invoice_id = $response['invoice_id']; 

		/* Сохранение invoice_id в заказе (PDO)  */
		$sth = $dbh->prepare("UPDATE `orders` SET `invoice_id` = ? WHERE `id` = ?");
		$sth->execute(array($invoice_id, $order_id));

		/* Редирект на форму оплаты */
		$link = $server . '/bill/' . $invoice_id . '/';
		header('Location: ' . $link, true, 301);
		echo "<script>window.location.replace('" . $link . "');</script>";
		echo 'Перейдите по <a href="' . $link . '">ссылке</a>.';
		exit();
	}
}
PHP

После авторизации, пользователь будет перенаправлен на страницу оплаты:

После оплаты, в личном кабинете PayKeeper появится платёж:

В некоторых случаях при отправки платежа возможна ошибка:

Тут могут быть две причины:

  1. Действительно, неправильно рассчитана финальная цена.
  2. Из-за настроек локали, в ценах и суммах используется запятая вместо точки, исправляется функцией str_replace(',', '.', $total);
2

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

/* Номер платежа */
$invoice_id	= '123456789';

/* Доступы к Paykeeper */
$server   = 'https://xxxxx.server.paykeeper.ru';
$user     = 'admin';
$password = 'xxxxxxxxxx';
 

/* Авторизация в Paykeeper */
$base64 = base64_encode($user . ':' . $password);
$headers = array(); 
array_push($headers, 'Content-Type: application/x-www-form-urlencoded');
array_push($headers, 'Authorization: Basic ' . $base64);

$curl = curl_init($server . '/info/invoice/byid/?id=' . $invoice_id);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$response = curl_exec($curl);
curl_close($curl);

$response = json_decode($response, true);
//var_dump($response);
?>

<h4>Статус online платежа</h4>
<p><strong>ID:</strong> <?php echo $response['id']; ?></p>
<p><strong>Сумма:</strong> <?php echo $response['pay_amount']; ?></p>
<p><strong>Состояние:</strong>
	<?php 
	switch ($response['status']) {
		case 'created': echo 'Создан'; break;
		case 'sent': echo 'Отправлен'; break;
		case 'paid': echo 'Оплачен'; break;
		case 'expired': echo 'Просрочен'; break;
	}
	?>
</p>
PHP
3

В Paykeeper возможен полный частичный возврат платежа с помощью метода /change/payment/reverse/. Возврат могут делать только пользователи с включённой функцией возврата.

Подробнее на https://docs.paykeeper.ru/dokumentatsiya-json-api/platezhi/#2.8

Пример запроса на полный возврат:

/* Номер платежа */
$invoice_id	= '123456789';
 
/* Доступы к Paykeeper */
$server   = 'https://xxxxx.server.paykeeper.ru';
$user     = 'admin';
$password = 'xxxxxxxxxx';

/* Авторизация в Paykeeper */
$base64 = base64_encode($user . ':' . $password);
$headers = array(
	'Content-Type: application/x-www-form-urlencoded',
	'Authorization: Basic ' . $base64
); 

$curl = curl_init($server . '/info/invoice/byid/?id=' . $invoice_id);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$info = curl_exec($curl);
curl_close($curl);

$info = json_decode($info, true);
if (!empty($info['paymentid'])) {
	$curl = curl_init($server . '/info/settings/token/'); 
	curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_HEADER, false);
	$response = curl_exec($curl);
	$response = json_decode($response, true);
				 
	/* В ответе должен быть token, иначе ошибка */
	if (isset($response['token'])) {
		$request = http_build_query(
			array(
				'id'      => $info['paymentid'], 
				'amount'  => 500, 
				'partial' => false, 
				'token'   => $response['token']
			)
		);
		
		$curl = curl_init($server . '/change/payment/reverse/');
		curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($curl, CURLOPT_POSTFIELDS, $request);	
		curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($curl, CURLOPT_HEADER, false);
		$response = curl_exec($curl);
		curl_close($curl);

		$response = json_decode($response, true);
		var_dump($response);
		exit;
	}				
}
PHP
28.02.2020, обновлено 12.04.2022
9562
Предыдущая запись Печать HTML страниц
Следующая запись Рамки блоков с градиентом

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

Александр Александр
11 августа 2022 в 19:17
Не работает начиная с php 7 и выше. Cannot modify header information - headers already sent by
Radhab Magomedov Radhab Magomedov
17 августа 2022 в 17:27
Проблема старая как мир, легко гуглится

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

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

Работа с ценами PHP
Приведение цен к общему типу, форматирование и вывод цен.
15790
+3
Шифрование полей в MySQL
В MySQL есть несколько встроенных функций шифрования. Рассмотрим основные на примерах c использованием PHP PDO.
19271
-3
Получение котировок PHP
Данный скрипт получает курсы валют с сайта ЦБ на текущую дату
9124
+5
Яндекс.Доставка работа с API в PHP
Примеры работы с API Яндекс.Доставки (для заказа перевозки грузов корпоративным клиентам).
8747
+5
Прием платежей на сайте через интернет-эквайринг Тинькофф
Предварительно, чтобы реализовать оплату заказов на своем сайте через API Интернет-эквайринга банка Тинькофф...
22968
+15
Примеры использования cURL в PHP
cURL PHP – это библиотека предназначенная для получения и передачи данных через такие протоколы, как HTTP, FTP, HTTPS....
220371
+21