Pull to refresh

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

Reading time 4 min
Views 42K
Приветствую.
Я являюсь давним читателем хабра и часто нахожу тут ответы на свои вопросы. Но вот так случилось, что ответа обнаружить не получилось. Причём нигде.
А задача была следующая. Реализовать новый (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.
Tags:
Hubs:
+6
Comments 11
Comments Comments 11

Articles