Платежи с баланса мобильного оператора
Редактировать на GitHub
Mobile Payments API открывает доступ к операциям с платежами из вашего сервиса. Поддерживаются следующие операции:
- Инициация платежа
- Проверка статуса оплаты счета
- Уведомления об оплате
Процесс оплаты заказа
Процесс оплаты выглядит следующим образом:
- Пользователь формирует заказ на сайте провайдера.
- Мерчант выполняет запрос Инициировать платеж с параметрами авторизации.
-
Сразу после инициирования платежа пользователь получает СМС от своего мобильного оператора с информацией о счете и подтверждает оплату ответным СМС. Если пользователь отказался от оплаты, то счет автоматически отклоняется.
-
Если провайдер включил отправку уведомлений на сервер провайдера, то после проведения платежа система высылает уведомление на сервер провайдера об оплате данного счета. Уведомления содержат параметры авторизации, которые необходимо проверять на сервере провайдера.
В отсутствие уведомлений провайдер может запросить текущий статус платежа.
- После подтверждения оплаты счета провайдер исполняет заказ пользователя.
Данное API можно использовать только после регистрации и подключения.
Авторизация
Запросы мерчанта к Mobile payments API авторизуются посредством HTTP basic-авторизации. Для авторизации используются API ID и API password. Заголовок представляет собой параметр Authorization, значение которого представлено как: Basic Base64(API_ID:API_PASSWORD)
curl "адрес сервера" \
--header "Authorization: Basic MjMyNDQxMjM6NDUzRmRnZDQ0Mw=="
Авторизация и работа с формами
Данные могут быть получены на сайте kassa.qiwi.com
Служебные данные
Параметр | Описание | Тип |
---|---|---|
API_ID | Обязательный параметр. Идентификатор для авторизации провайдера в API | Integer |
API_PASSWORD | Обязательный параметр. Пароль для авторизации в API | String |
ID проекта | Обязательный параметр. Числовой идентификатор провайдера (идентификатор проекта или PRV_ID) | Integer |
Инициация платежа и оплата
Запрос инициирует новый платеж на указанный номер телефона. Тип запроса - HTTP PUT.
Для подтверждения оплаты, на указанный номер телефона будет отправлен SMS код оператором сотовой связи пользователя.
Запрос → PUT
curl "https://api.qiwi.com/api/v2/prv/373712/bills/BILL-1" \
-X PUT --header "Accept: text/json" \
--header "Authorization: Basic ***" \
-d 'user=tel%3A%2B79161111111&amount=10.00&ccy=RUB&comment=test&pay_source=mobile&lifetime=2016-09-25T15:00:00'
HTTP/1.1 200 OK
Content-Type: text/json
{
"response": {
"result_code": 0,
"bill": {
"bill_id": "BILL-1",
"amount": "10.00",
"ccy": "RUB",
"status": "waiting",
"error": 0,
"user": "tel:+79161111111",
"comment": "Text comment"
}
}
}
URL https://api.qiwi.com/api/v2/prv/prv_id/bills/bill_id
-
В path params PUT-запроса используются два параметра счета:
- prv_id - числовой идентификатор провайдера (идентификатор проекта на партнерском сайте kassa.qiwi.com)
- bill_id - уникальный идентификатор счета в системе провайдера.
HEADERS
- Accept: text/json - формат ответа JSON
- Content-type: application/x-www-form-urlencoded; charset=utf-8
- Authorization: Basic XXX
Параметры
Параметры передаются в теле запроса как url-encoded formdata
Параметр | Описание | Тип |
---|---|---|
user | Обязательный параметр. Идентификатор номера QIWI Wallet, на который выставляется счет (в международном формате), с префиксом tel: |
String(20) |
amount | Обязательный параметр. Сумма, на которую выставляется счет. Округляется в меньшую сторону до двух десятичных знаков | Number(6.2) |
ccy | Обязательный параметр. Идентификатор валюты (Alpha-3 ISO 4217 код). Может использоваться любая валюта, предусмотренная договором с КИВИ | String(3) |
comment | Обязательный параметр. Комментарий к счету | String(255) |
lifetime | Обязательный параметр. Дата/время с точностью до секунд в формате ISO 8601 (ГГГГ-ММ-ДДTчч:мм:сс ). Указывается московское время. Если счет не будет оплачен до этой даты, ему присваивается финальный статус и последующая оплата станет невозможна.Внимание! По истечении 45 суток от даты выставления счет автоматически будет переведен в финальный статус. |
dateTime |
pay_source | Обязательный параметр. mobile - оплата счета будет производиться с баланса мобильного телефона пользователя |
String |
Ответ ←
Успешный ответ
HTTP/1.1 200 OK
Content-Type: text/json;charset=utf-8
{
"response": {
"result_code": 0,
"bill": {
"bill_id": "BILL-1",
"amount": "10.00",
"ccy": "RUB",
"status": "waiting",
"error": 0,
"user": "tel:+79031234567",
"comment": "Text comment"
}
}
}
Ответ в случае ошибки
HTTP/1.1 500 Internal Server Error
Content-Type: text/json;charset=utf-8
{
"response": {
"result_code": 150,
"description": "Authorization failed"
}
}
Поле ответа | Тип | Описание |
---|---|---|
result_code | Integer | Код результата |
description | String | Описание ошибки. Передается в случае ошибки |
bill | Object | Описание счета |
bill.bill_id | String | Копия параметра bill_id из исходного запроса |
bill.amount | String | Сумма счета. Округляется в меньшую сторону до двух десятичных знаков. |
bill.ccy | String | Идентификатор валюты (Alpha-3 ISO 4217 код) |
bill.status | String | Текущий статус счета |
bill.error | Integer | Константа, всегда 0 |
bill.user | String | Копия параметра user из исходного запроса |
bill.comment | String | Копия параметра comment из исходного запроса |
<?php
//Пример реализации запроса на PHP
//Идентификатор магазина из вкладки "Данные магазина"
$SHOP_ID = "21379721";
//API ID из вкладки "Данные магазина"
$REST_ID = "62573819";
//API пароль из вкладки "Данные магазина"
$PWD = "**********";
//ID счета
$BILL_ID = "99111-ABCD-1-2-1";
$PHONE = "79191234567";
$data = array(
"user" => "tel:+" . $PHONE,
"amount" => "1000.00",
"ccy" => "RUB",
"comment" => "Товар из корзины",
"lifetime" => "2015-01-30T15:35:00",
"pay_source" => "mobile"
);
$ch = curl_init('https://api.qiwi.com/api/v2/prv/'.$SHOP_ID.'/bills/'.$BILL_ID);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $REST_ID.":".$PWD);
curl_setopt($ch, CURLOPT_HTTPHEADER,array (
"Accept: application/json"
));
$results = curl_exec ($ch) or die(curl_error($ch));
echo $results;
echo curl_error($ch);
curl_close ($ch);
?>
Проверка статуса платежа
Запрос позволяет проверить текущий статус оплаты клиентом.
Запрос → GET
curl "https://api.qiwi.com/api/v2/prv/373712/bills/BILL-1" \
--header "Authorization: Basic ***" \
--header "Accept: text/json"
URL https://api.qiwi.com/api/v2/prv/prv_id/bills/bill_id
-
Параметры передаются в path params.
- prv_id - числовой идентификатор провайдера (идентификатор проекта на партнерском сайте kassa.qiwi.com)
- bill_id - уникальный идентификатор счета в системе провайдера.
HEADERS
- Authorization: Basic XXX
- Accept: text/json или Accept: application/json - формат ответа JSON
Ответ ←
Успешный ответ
HTTP/1.1 200 OK
Content-Type: text/json
{
"response": {
"result_code": 0,
"bill": {
"bill_id": "BILL-1",
"amount": "10.00",
"originAmount": "10.00"
"ccy": "RUB",
"originCcy": "RUB",
"status": "paid",
"error": 0,
"user": "tel:+79031234567",
"comment": "Text comment"
}
}
}
Ответ в случае ошибки
HTTP/1.1 500 Internal Server Error
Content-Type: text/json
{
"response": {
"result_code": 150,
"description": "Authorization failed"
}
}
Поля ответа
Поле ответа | Тип | Описание |
---|---|---|
result_code | Integer | Код результата |
description | String | Описание ошибки. Передается в случае ошибки |
bill | Object | Описание счета |
bill.bill_id | String | Уникальный идентификатор счета в системе провайдера |
bill.amount | String | Сумма счета, округленная до 2 или 3 знаков после запятой. Способ округления зависит от валюты. |
bill.originAmount | String | Сумма счета в исходной валюте счета (см. параметр originCcy ), округленная до 2 или 3 знаков после запятой. Способ округления зависит от валюты. |
bill.ccy | String | Идентификатор валюты (Alpha-3 ISO 4217 код) |
bill.originCcy | String | Идентификатор валюты выставленного счета (Alpha-3 ISO 4217 код) |
bill.status | String | Текущий статус счета |
bill.error | Integer | Константа, 0 |
bill.user | String | Идентификатор кошелька пользователя, которому выставлен счет (номер телефона в международном формате с префиксом tel: ) |
bill.comment | String | Комментарий к счету |
Статусы операций
Статусы платежей
Статус | Описание | Финальный |
---|---|---|
waiting | Платеж инициирован, ожидает оплаты | - |
paid | оплачен | + |
rejected | отклонен | + |
unpaid | Ошибка при проведении оплаты. Не оплачен | + |
expired | Время жизни платежа истекло. Не оплачен | + |
Список ошибок
Код | Описание | Fatal |
---|---|---|
0 | Успех | |
5 | Неверные данные в параметрах запроса | + |
13 | Сервер занят, повторите запрос позже | - |
78 | Недопустимая операция | + |
150 | Ошибка авторизации | + |
152 | Не подключен или отключен протокол | - |
155 | Данный идентификатор провайдера (API ID) заблокирован | + |
210 | Платеж не найден | + |
215 | Платеж с таким bill_id уже существует | + |
241 | Сумма слишком мала | + |
300 | Техническая ошибка | - |
303 | Неверный номер телефона | + |
316 | Попытка авторизации заблокированным провайдером | - |
319 | Нет прав на данную операцию | - |
339 | Ваш IP-адрес или массив адресов заблокирован | + |
341 | Обязательный параметр указан неверно или отсутствует в запросе | + |
700 | Превышен месячный лимит на операции | + |
774 | Счет клиента в системе QIWI временно заблокирован | - |
1001 | Запрещенная валюта для провайдера | + |
1003 | Не удалось получить курс конвертации для данной пары валют | - |
1019 | Не удалось определить сотового оператора для мобильной коммерции | + |
1419 | Нельзя изменить данные счета – он уже оплачивается или оплачен | + |
Уведомления об оплате счетов
Редактировать на GitHub
Уведомление представляет собой POST-запрос. Тело запроса содержит сериализованные данные счета в теле запроса (кодировка UTF-8), и параметр command=bill
.
Запрос → POST
Пример
user@server:~$ curl "https://example.com/qiwi-notify.php"
-v -w "%{http_code}"
-X POST --header "Accept: text/xml"
--header "Content-Type: application/x-www-form-urlencoded; charset=utf-8"
--Authorization: "Basic MjA0Mjp0ZXN0Cg=="
-d "bill_id=BILL-1%26status=paid%26amount=1.00%26user=tel%3A%2B79031811737%26prv_name=TEST%26ccy=RUB%26comment=test%26command=bill"
URL
HEADERS
- Authorization: Basic XXX - для авторизации по логину/паролю
- X-Api-Signature: XXX - для авторизации по цифровой подписи
- Accept: text/xml
- Content-type: application/x-www-form-urlencoded
Параметры
В теле запроса уведомления указываются параметры счета.
Параметр | Описание | Тип | Обяз. |
---|---|---|---|
bill_id | Уникальный идентификатор счета в системе провайдера | String | + |
status | Текущий статус счета | String | + |
amount | Сумма, на которую выставлялся счет, округленная до двух десятичных знаков | Number(6.2) | + |
user | Номер QIWI Кошелька, на который был выставлен счет, с префиксом tel: |
String | + |
prv_name | Название проекта, указанное на сайте kassa.qiwi.com в разделе:"Настройки" | String | + |
ccy | Идентификатор валюты (Alpha-3 ISO 4217 код) | String(3) | + |
comment | Комментарий к счету | String(255) | + |
command | bill - всегда по умолчанию |
String | + |
Ответ ←
Пример ответа на уведомление
HTTP/1.1 200 OK
Content-Type: text/xml
<?xml version="1.0"?>
<result>
<result_code>0</result_code>
</result>
Ответ на запрос должен быть в формате XML.
HEADERS
- Content-type: text/xml
Параметры
result
- Группирующий тег. Содержит описание результата обработки уведомления.result_code
- Код результата обработки уведомления (целое положительное число). Рекомендуется возвращать коды результата в соответствии с таблицей кодов завершения.
Авторизация уведомлений
Для авторизации можно использовать basic-авторизацию или авторизацию подписи. При запросах уведомлений на сервер провайдера также можно использовать SSL (в том числе самоподписанный сертификат). В HTTPS-запросах необходимо проверять серверный сертификат QIWI Wallet.
Basic-авторизация
Пример уведомления с Basic-авторизацией
POST /qiwi-notify.php HTTP/1.1
Accept: text/xml
Content-type: application/x-www-form-urlencoded
Authorization: Basic ***
Host: example.com
command=bill&bill_id=BILL-1&status=paid&error=0&amount=1.00&user=tel%3A%2B79031811737&prv_name=Retail_Store&ccy=RUB&comment=test
Логин равен ID проекта.
Для первичного получения или смены пароля на сайте QIWI Касса, нажмите кнопку "Создать пароль и сохранить" или "Сменить пароль оповещения", соответственно.
Подробнее
Авторизация по подписи
Пример уведомления с подписью
POST /qiwi-notify.php HTTP/1.1
Accept: text/xml
Content-type: application/x-www-form-urlencoded
X-Api-Signature: J4WNfNZd***V5mv2w=
Host: example.com
command=bill&bill_id=LocalTest17&status=paid&error=0&amount=0.01&user=tel%3A%2B78000005122&prv_name=Test&ccy=RUB&comment=Some+Descriptor
Для использования этого способа авторизации уведомлений, на сайте QIWI Касса достаточно активировать флаг "Использовать HMAC подпись вместо basic-авторизации".
Подробнее
Подпись уведомления отправляется в заголовке X-Api-Signature
. Для формирования подписи используется механизм проверки целостности HMAC с хэш-функцией SHA1.
- В качестве разделителей параметров используется символ
|
. - В подписи участвуют все параметры, которые присутствуют в исходном запросе выставления счета.
- Параметры для подписи переводятся в байт-представление с UTF-8 и располагаются в алфавитном порядке.
- Ключ подписи равен паролю для basic-авторизации уведомления.
Алгоритм проверки подписи:
-
Получить строку, содержащую значения всех параметров POST-запроса в алфавитном порядке перечисления параметров, разделенных символами
|
:{parameter1}|{parameter2}|…
где
{parameter1}
– значение параметра уведомления. Все значения при проверке подписи должны трактоваться как строки. - Строку и пароль для basic-авторизации уведомления преобразовать в байты с UTF-8.
-
Вычислить HMAC-хэш c шифрованием SHA1:
hash = HMAС(SHA1, Notification_password_bytes, Invoice_parameters_bytes)
где:Notification_password_bytes
– ключ функции (байт-представление basic-пароля для уведомлений);Invoice_parameters_bytes
– байт-представление тела POST-запроса;hash
– результат хэш-функции.
- HMAC-хэш преобразовать из строк в байты с использованием кодировки UTF-8 и base64-преобразовать.
- Сравнить значение заголовка
X-Api-Signature
с результатом 4.
Пример реализации
<?php
function hexToStr($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
//функция генерации подписи по ключу и строке параметров
function checkSign($key, $req){
$sign_hash = hash_hmac("sha1", $req, $key);
$sign_tr = hexToStr($sign_hash);
$sign = base64_encode($sign_tr);
return $sign;
}
//Функция возвращает упорядоченную строку значений параметров POST-запроса
function getReqParams(){
$reqparams = "";
ksort($_POST);
foreach ($_POST as $param => $valuep) {
$reqparams = "$reqparams|$valuep";
}
return substr($reqparams,1);
}
//Извлечение цифровой подписи из заголовков запроса
function getSign(){
$HEADERS = getallheaders();
foreach ($HEADERS as $header => $value) {
if ($header == 'X-Api-Signature') {
$SIGN_REQ = $value;
}
}
return $SIGN_REQ;
}
// Сортировка параметров
$Request = getReqParams();
// Пароль для уведомлений магазина
$NOTIFY_PWD = "***";
// Вычисляем подпись
$reqres = checkSign($NOTIFY_PWD, $Request);
// Подпись из запроса
$SIGN_REQ = getSign();
if ($reqres == $SIGN_REQ) {
$error = 0;
}
else $error = 151;
//Ответ
header('Content-Type: text/xml');
$xmlres = <<<XML
<?xml version="1.0"?>
<result>
<result_code>$error</result_code>
</result>
XML;
echo $xmlres;
?>
Пример на языке PHP реализует авторизацию уведомлений системы QIWI Wallet с проверкой цифровой подписи. Откройте вкладку PHP справа.
Коды уведомлений
Код завершения | Описание |
---|---|
0 | Успех |
5 | Ошибка формата параметров запроса |
13 | Ошибка соединения с базой данных |
150 | Ошибка проверки пароля |
151 | Ошибка проверки подписи |
300 | Ошибка связи с сервером |