QIWI и новый протокол REST в примерах

Приветствую.
Я являюсь давним читателем хабра и часто нахожу тут ответы на свои вопросы. Но вот так случилось, что ответа обнаружить не получилось. Причём нигде.
А задача была следующая. Реализовать новый (REST) протокол для системы QIWI. Мне пришлось потратить несколько дней, чтобы найти верное решение с помощью проб, ошибок, общений с менеджером и командой поддержки, т.к. примеров нигде нет, хотя задача не такая уж и сложная.
В данном сообщении я хочу поделиться теми примерами, которых мне так не хватало. Надеюсь, что это поможет кому-то.
Сразу скажу, что я не буду расписывать, разжевывать и объяснять подробно. Будет только основное, которое считаю необходимым. Всё же у каждого свои предпочтения и цели.
Для начала вам нужно зарегистрировать свой магазин http://ishopnew.qiwi.ru/
После регистрации в разделе Способы подключения вы найдёт пункт Новый протокол. Там можно скачать описание API нового протокола.

Для отправки запросов я использовал cURL.
Вот как это было:

$requestType = 'POST'; // Для REST запросы разного типа $url = 'some url'; // Зависит от выполняемого действия $parameters = array(); // Так же зависит от запроса $loginPass = $id . ':' . $password; // ID магазина и пароль(пароль нужно получить у менеджера) $headers = array(     "Accept: text/json",     "Content-Type: application/x-www-form-urlencoded; charset=utf-8" ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, $loginPass);  if ($requestType != 'GET') {     curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $requestType);     curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parameters)); } $httpResponse = curl_exec($ch); if (!$httpResponse) {     // Описание ошибки, к примеру      echo curl_error($ch).'('.curl_errno($ch).')';     return false; } $httpResponseAr = json_decode($httpResponse); return $httpResponseAr->response; 

Думаю тут всё просто и понятно.

Теперь какие операции можно осуществить.

  • Выставление счета пользователю
  • Запрос статуса счета
  • Переадресация для оплаты счета
  • Отмена неоплаченного выставленного счета
  • Возврат средств по оплаченному счету
  • Проверка статуса возврата

В документации довольно подробно всё описано. Я лишь акцентирую внимание на некоторых вещах, которые тормозили мою разработку.

Опишу отдельно для каждой операции.

1) Выставление счета пользователю

$requestType = 'PUT'; $url = 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}'; // {prv_id} – тут важно помнить, что это ваш ID магазина. // {bill_id} – любое уникальное число, к примеру номер записи операции или номер счёта из базы. $parameters = array( 	'user' => 'tel:+79999999999', 	'amount' => 0.1, 	'ccy' => 'RUB', 	'comment' => 'Оплата QIWI', 	'pay_source' => 'qw', 	'lifetime' => date('c', $timePlusHour), 	'prv_name' => 'QIWI', ); 

С параметрами всё понятно.

2) Запрос статуса счета
Если счёт не был оплачен после выставления, нам нужно проверить его статус. Возможно система задержала ответ или пользователь решил оплатить его чуть позже, в таком случае можно использовать cron.

$requestType = 'GET'; $url = 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}'; // Аналогично выше $parameters = array(); 

3) Переадресация для оплаты счета
После успешного выставления счёта нужно перенаправить пользователя на страницу оплаты. Здесь cURL не используется, просто редирект.

$url = 'https://w.qiwi.com/order/external/main.action?shop={prv_id }&transaction={bill_id}'; $url .= '&successUrl=' . $successUrl; $url .= '&failUrl=' . $failUrl; // {prv_id} и {bill_id} всегда постоянны для одного платежа.  // $successUrl и $failUrl адреса ваших обработчиков успешных и неуспешных операций по оплате. 

4) Отмена неоплаченного выставленного счета
Используется для отмены выставленного счёта. Если вы выставили счёт, но он не оплачен, система будет высылать на адрес, указанный в настройках магазина, POST запросы на подтверждение статуса счёта. Если вы не ответите, то в итоге придёт письмо на email, указанный в настройках магазина.

$requestType = 'PATCH'; $url = 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}'; // Аналогично выше $parameters = array( 	'status' => 'rejected' );  

5) Возврат средств по оплаченному счету
Вы можете потребовать вернуть оплаченные средства.

$requestType = 'PUT'; $url = 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}/refund/{refund_id}'; // Аналогично выше, только {refund_id} должен быть уникален $parameters = array( 	'amount' => $amount );  

6) Проверка статуса возврата
Так же нужно проверять статус возврата по запросу, описанному выше.

$requestType = 'GET'; $url = 'https://w.qiwi.com/api/v2/prv/{prv_id}/bills/{bill_id}/refund/{refund_id}'; // Аналогично выше, только {refund_id} должен быть уникален и совпадать с указанным выше $parameters = array();  

Ответ сервера подробно описан в документации.

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

  1. bill_id=BILL-1
  2. status=paid
  3. error=0
  4. amount=1.00
  5. user=tel%3A%2B79031811737
  6. prv_name=TEST
  7. ccy=RUB
  8. comment=test
  9. command=bill

В зависимости от того, на какой адрес пришёл запрос, вы должны проверить и решить, что делать с платежом. То ли зачислить деньги, если платёж прошёл и запрос успешен.То ли уменьшить баланс, если деньги были зачислены, но платёж оказался неудачен.

И конечно отдельное негодование хочется выразить по поводу тестирования. Система QIWI не имеет тестового режима или тестовой площадки, поэтому вам придётся использовать свой кошелёк и проводить платежи, к примеру, по 10 копеек.

Надеюсь, данным сообщением я хоть немного помог тем, кто собирается использовать новый протокол в своём проекте. Ведь он обещает возможность получать оплату со всех стран, где есть QIWI.

ссылка на оригинал статьи http://habrahabr.ru/post/198668/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *