Платежная платформа PayKeeper позволяет принимать оплату заказов по ссылке, используя данный метод можно с легкостью сделать онлайн-оплату на сайте.
Предполагается что пользователь оформил заказ, данные добавлены в БД и есть 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();
}
}
После авторизации, пользователь будет перенаправлен на страницу оплаты:
После оплаты, в личном кабинете PayKeeper появится платёж:
В некоторых случаях при отправки платежа возможна ошибка:
Тут могут быть две причины:
- Действительно, неправильно рассчитана финальная цена.
- Из-за настроек локали, в ценах и суммах используется запятая вместо точки, исправляется функцией
str_replace(',', '.', $total);
Для удобства, в панели управления заказами можно получить и вывести текущее состояние платежа.
/* Номер платежа */
$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>
В 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;
}
}