В системе EasyPay предусмотрена возможность оперативного информирования Поставщика товаров и услуг о совершаемых пользователями платежах.
Типы Уведомлений:
Уведомление Поставщика об оплатах осуществляется по протоколу HTTP (HTTPS) в виде специальных сообщений, отсылаемых POST-запросом. Подлежат уведомлению счета, которые были приняты в обработку, оплачены и не были отменены. Каждый такой счет-заказ подтверждается одним сообщением.
При необходимости формируется ежесуточный реестр платежей и отправляется по HTTP (HTTPS) в виде XML-документа.
Каждое сообщение подписывается электронной подписью, которая имеет вид строки md5-хэша, являющейся объединением всех полей счета-заказа и секретного ключа. Чтобы получить ключ, обратитесь в службу технической поддержки EasyPay.
Запрос с Уведомлением Поставщика о совершенном платеже будет отсылаться до тех пор, пока Поставщик его не примет, то есть до получения ответа с кодом "HTTP/1.0 200 OK".
В случае, если сайт Поставщика (по техническим или другим причинам) не может обработать запрос, он должен сгенерировать ответ с любым кодом ошибки, например "HTTP/1.0 400 Bad Request". Недопустимо отвечать кодом "HTTP/1.0 200 OK" на необработанное уведомление.
Уведомления отсылаются по специальному расписанию, но не более n раз, где n = 10 (задается EasyPay). Если сервер Поставщика после n-го запроса не дает положительного ответа, то на электронный адрес Поставщика отсылается письмо с предупреждением о сбое.
Расписание отправки уведомлений:
Процессинговый центр формирует и отправляет сообщение об оплате, подписанное секретным ключом web_key, Поставщику. Ключ известен обеим сторонам, но в запросе не передается.
Поставщик проверяет электронную подпись и сверяет данные заказа.
Поставщик проверяет (одним или несколькими способами) оплату заказа:
Последний шаг не является обязательным, но его рекомендуется использовать как способ удостовериться в подлинности уведомления. Дополнительно Поставщик может установить проверку по доменному имени или по IP-адресу.
Для реализации уведомлений при подключении Поставщика к EasyPay задаются следующие параметры:
web_key – ключ (случайная последовательность символов), участвующий в электронной подписи сообщения.
При формировании каждого сообщения, которое отсылается POST-запросом на соответствующий URL, используются следующие поля:
Название полей | Формат полей | Описание полей |
---|---|---|
order_mer_code | от 1 до 20 алфавитно-цифровых символов | уникальный номер электронного счета. Формируется Поставщиком. Должен быть уникальным в течении всего периода работы с EasyPay |
sum | число больше нуля | сумма в белорусских рублях |
mer_no | 6 алфавитно-цифровых символов вида okXXXX, где X – число от 0 до 9 | номер Поставщика в EasyPay. Выдается Администратором EasyPay при регистрации |
card | PT_CARD для банковских карт, PT_ERIP для счетов ЕРИП, PT_EPOS для счетов E-POS | способ оплаты |
purch_date | ГГГГ-ММ-ДД ЧЧ:ММ:СС | дата и время оплаты счета |
notify_signature | 32 алфавитно-цифровых символов | электронная подпись электронного счета |
xml_data | От 0 до 64 килобайта текстовой информации в произвольной форме | дополнительный XML или другие текстовые данные |
При формировании реестра платежей за предыдущие сутки создается XML-документ, который передается в поле ep_notify_register:
<?xml version="1.0" encoding="windows-1251"?> <easypay function="ep_notify_register" date="2006-09-11"> <invoices count="2" total_sum="300.00"> <invoice> <order_mer_code>1000</order_mer_code> <sum>100.00</sum> <mer_no>ok6666</mer_no> <card>PT_ERIP</card> <purch_date>2006-09-11 22:45:21</purch_date> <xml_data>text</xml_data> </invoice> <invoice> <order_mer_code>1001</order_mer_code> <sum>200.00</sum> <mer_no>ok6666</mer_no> <card>PT_CARD</card> <purch_date>2006-09-11 21:44:20</purch_date> <xml_data>text</xml_data> </invoice> </invoices> </easypay>
В случае подтверждения счета, электронная подпись формируется с участием полей order_mer_code, sum, mer_no, card, purch_date, web_key, следующих в указанном порядке по алгоритму: notify_signature = md5 (order_mer_code . sum . mer_no . card . purch_date . web_key)
При получении уведомления Поставщик проверяет подлинность этого сообщения по его электронной подписи.
<?php /* Пример на PHP обработчика одиночных уведомлений (для реестра платежей аналогично) Принимает и логирует уведомления EasyPay, но ничего с ними не делает Поставщик осуществляет обработку уведомлений в соответствии с особенностями своей работы */ $logfilepath = '/test/logs/notify.log'; //путь к файлу логирования $web_key = 'dh48djklhgl5893j'; //ключ, участвующий в электронной подписи сообщения //Если у Вас нет ключа, то обратитесь в службу технической поддержки EasyPay $post_params = array ( 'order_mer_code' => isset($_POST['order_mer_code']) ? $_POST['order_mer_code'] : '', 'sum' => isset($_POST['sum']) ? $_POST['sum'] : '', 'mer_no' => isset($_POST['mer_no']) ? $_POST['mer_no'] : '', 'card' => isset($_POST['card']) ? $_POST['card'] : '', 'purch_date' => isset($_POST['purch_date']) ? $_POST['purch_date'] : '', 'notify_signature' => isset($_POST['notify_signature']) ? $_POST['notify_signature'] : '', 'xml_data' => isset($_POST['xml_data']) ? $_POST['xml_data'] : '', ); main ($logfilepath, $web_key, $post_params); function main($logfilepath, $web_key, $post_params) { // пример обработки ежесуточного реестра платежей if (isset($_POST['ep_notify_register'])) { // обработка реестра платежей $processed = ProcessDailyNotify($_POST['ep_notify_register']); if ($processed) { //реестр обработан $status = 'OK | the register is processed'; // статус обработки header("HTTP/1.0 200 OK"); // генерация HTTP-заголовка print $status; // формирование контента } else { //реестр не обработан $status = 'FAILED | the register is not processed'; header("HTTP/1.0 400 Bad Request"); print $status; } } else { // обработка уведомления //вычисляем электронную подпись и сравниваем с переданной $notify_signature = CreateAuthorizationKey ($web_key, $post_params); if($notify_signature == $post_params['notify_signature']) { //осуществляем обработку уведомления и логирование как пример $processed = ProcessNotify($post_params); if ($processed) { //уведомление обработано $status = 'OK | the notice is processed'; //статус обр. header("HTTP/1.0 200 OK"); // генерация HTTP-заголовка print $status; // формирование контента } else { //уведомление не обработано $status = 'FAILED | the notice is not processed'; header("HTTP/1.0 400 Bad Request"); print $status; } } else { //неверная электронная подпись $status = 'FAILED | incorrect digital signature'; header("HTTP/1.0 400 Bad Request"); print $status; } //подготовка параметров для логирования $params_line = ''; foreach ($post_params as $key=>$value) { $params_line .= "$key=$value; "; } CreateLog($status, $params_line); //логирование } } function CreateAuthorizationKey ($web_key, $post_params) {//функция вычисления эл. подписи // правило вычисления: // notify_signature = md5(order_mer_code. sum. mer_no. card. purch_date. web_key) $hash = md5($post_params['order_mer_code'].$post_params['sum']. $post_params['mer_no'].$post_params['card'].$post_params['purch_date'].$web_key); return $hash; } function ProcessNotify($post_params) { // функция реализует логику обработки уведомлений // Поставщик осуществляет обработку уведомлений // в соответствии с особенностями своей работы // обработка xml_data // дополнительная проверка оплаты счета через SOAP для безопасности $soap_check = SOAPIsInvoicePaid($post_params['order_mer_code']); // 1 - уведомление обработано, 0 - уведомление не обработано return 1; } fucntion SOAPIsInvoicePaid($order_mer_code) { //функция проверки оплаты счета через SOAP // Поставщик дополнительно осуществляет проверку оплаты счёта по SOAP // функцией EP_IsInvoicePaid // https://ssl.easypay.by/soap/ // 1 - счет оплачен, 0 - счет не оплачен return 1; } function ProcessDailyNotify($post_params) { // функция реализует логику обработки реестра // Поставщик осуществляет обработку реестра // в соответствии с особенностями своей работы // 1 - ежесуточный реестр обработан, 0 - не обработан return 1; } function CreateLog ($status, $request) { //функция добавления записи в логфайл global $logfilepath; $date = date("d.m.Y H:i:s"); $str = $date."\t".$status."\n\t"."ORDER_INFORMATION: ".$request."\n"; $log = fopen($logfilepath, 'a'); if($log) { fwrite($log, $str); fclose($log); } } ?>