В данном примере рассматривается процесс формирования ссылки на оплату, исходя из предоставленных параметров. При переходе по данной ссылке плательщик будет перенаправлен на страницу оплаты для завершения транзакции.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
/* Доступы к 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' => 300, '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(); } } |
После перехода по ссылке $link пользователь будет направлен на страницу оплаты.
На языке PHP обработку запросов от PayKeeper об успешных платежах можно реализовать следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<?php // Фиксируем время запроса $time = date("Y-m-d H:i:s"); // Получаем данные из POST-запроса об оплате $id = $_POST['id'] ?? null; $sum = $_POST['sum'] ?? null; $clientid = $_POST['clientid'] ?? null; $orderid = $_POST['orderid'] ?? null; $key = $_POST['key'] ?? null; $service_name = $_POST['service_name'] ?? null; $client_email = $_POST['client_email'] ?? null; $client_phone = $_POST['client_phone'] ?? null; $ps_id = $_POST['ps_id'] ?? null; $batch_date = $_POST['batch_date'] ?? null; $fop_receipt_key = $_POST['fop_receipt_key'] ?? null; $bank_id = $_POST['bank_id'] ?? null; $card_number = $_POST['card_number'] ?? null; $card_holder = $_POST['card_holder'] ?? null; $card_expiry = $_POST['card_expiry'] ?? null; // Секретный ключ $secret = '********'; $md5hash = md5($id . $sum . $clientid . $orderid . $secret); // Устанавливаем заголовок ответа header('Content-Type: text/html; charset=UTF-8'); // Проверяем хеш if ($key === $md5hash) { // Генерируем ответ $hash = md5($id . $secret); $ret = "OK $hash"; echo $ret; // Запись лога для отладки $logMessage = "$time Ret=$ret id=$id sum=$sum key=$key, my key is $md5hash\n"; file_put_contents('/tmp/paykeeperlog.txt', $logMessage, FILE_APPEND); } else { // Вывод сообщения об ошибке (опционально) echo "Invalid key"; } exit; |
Полный перечень параметров в POST-оповещении можно посмотреть здесь.
В ответ на данный запрос должна быть отправлена строка вида:
Важно отметить, что ответ данного скрипта должен быть исключительно в указанном формате и ни байтом больше, в противном случае PayKeeper будет считать, что ваш сайт неправильно обработал оповещение об успешном платеже.
В PayKeeper возможен полный возврат платежа с помощью метода /change/payment/reverse/. Возврат могут делать только пользователи с включённой функцией возврата. Подробнее можно ознакомиться в документации JSON API. Пример запроса на полный возврат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
/* Номер платежа */ $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; } } |
Менеджер перезвонит вам и расскажет про детали подключения