Вопросы
bss@qiwi.com
NAV Navbar
PHP SDK Node.js SDK Java SDK .Net SDK HTTP

Процесс интеграции через SDK

Ознакомьтесь с документацией для API P2P-счетов.

Шаг 1. Подготовка среды разработки

//Установка с помощью npm

$ npm install @qiwi/bill-payments-node-js-sdk --save
//Установка с помощью composer

$ composer require qiwi/bill-payments-php-sdk
//Установка с помощью maven

<dependency>
    <groupId>com.qiwi</groupId>
    <artifactId>bill-payments-java-sdk</artifactId>
    <version>1.5.0</version>
</dependency>
//Установка с помощью Nuget

nuget install Qiwi.BillPayments

Шаг 2. Создание секретного ключа

Выпуск новых ключей прекращён. Простите за доставленные неудобства.

Шаг 3. Авторизация

const QiwiBillPaymentsAPI = require('@qiwi/bill-payments-node-js-sdk');

const SECRET_KEY = 'eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************=';
const qiwiApi = new QiwiBillPaymentsAPI(SECRET_KEY);
<?php
const SECRET_KEY = 'eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************=';

$billPayments = new Qiwi\Api\BillPayments(SECRET_KEY);

?>
String secretKey = "eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************=";

BillPaymentClient client = BillPaymentClientFactory.createDefault(secretKey);
var client = BillPaymentClientFactory.Create(
    secretKey: "eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************="
);

В разрабатываемом коде заведите константу SECRET_KEY и присвойте ей значение секретного ключа, вставив его из буфера обмена комбинацией клавиш Ctrl+V.

Проверьте, что ключ скопирован полностью: в конце должен быть знак "равно" =.

См. также примеры авторизации.

Если возвращается ошибка авторизации HTTP/1.1 401 Unauthorized, это значит что-то не так с секретным ключом. Выпустите новый ключ и скопируйте его полностью: в конце должен быть знак "равно" =.

Шаг 4. Выставление счета

Реализуйте вызов метода createBill.

Пример генерации billId

<?php

/** @var \Qiwi\Api\BillPayments $billPayments */
$billId = $billPayments->generateId();
//e9b47ee9-b2f9-4b45-9438-52370670e2a6

?>
const billId = qiwiApi.generateId();
//e9b47ee9-b2f9-4b45-9438-52370670e2a6

Примеры генерации expirationDateTime. Входной параметр - сколько дней счёт будет доступен, по умолчанию 45 дней. Метод возвращает строку в формате ISO 8601 UTC±0:00

<?php

//now: 2021-01-28T17:16:58.033Z
/** @var \Qiwi\Api\BillPayments $billPayments */
$lifetime = $billPayments->getLifetimeByDay(1);
//2021-01-29T17:16:58.033Z

?>

<?php

//now: 2021-01-28T17:16:58.033Z
/** @var \Qiwi\Api\BillPayments $billPayments */
$lifetime = $billPayments->getLifetimeByDay(0.5);
//2021-01-29T05:16:58.033Z

?>
//now: 2021-01-28T17:16:58.033Z
const lifetime = qiwiApi.getLifetimeByDay(1);
//2021-01-29T17:16:58.033Z

//now: 2021-01-28T17:16:58.033Z
const lifetime = qiwiApi.getLifetimeByDay(0.5);
//2021-01-29T05:16:58.033Z

Запрос создания счета

const billId = 'cc961e8d-d4d6-4f02-b737-2297e51fb48e';

const fields = {
    amount: 1.00,
    currency: 'RUB',
    comment: 'Hello world',
    expirationDateTime: '2020-08-28T19:44:07',
    email: 'example@mail.org',
    account : 'client4563',
    customFields : {themeCode: 'кодСтиля'}
};

qiwiApi.createBill( billId, fields ).then( data => {
    //do with data
});
<?php

$billId = 'cc961e8d-d4d6-4f02-b737-2297e51fb48e';
$customFields = ['themeCode' => 'кодСтиля'];
$fields = [
  'amount' => 1.00,
  'currency' => 'RUB',
  'comment' => 'Hello world',
  'expirationDateTime' => '2020-08-28T19:44:07+03:00',
  'email' => 'example@mail.org',
  'account' => 'client4563',
  'customFields' => $customFields,
  ];

/** @var \Qiwi\Api\BillPayments $billPayments */
$response = $billPayments->createBill($billId, $fields);

print_r($response);

?>
CreateBillInfo billInfo = new CreateBillInfo(
                UUID.randomUUID().toString(),
                new MoneyAmount(
                        BigDecimal.valueOf(199.90),
                        Currency.getInstance("RUB")
                ),
                "Hello world",
                ZonedDateTime.now().plusDays(45),
                new Customer(
                        "example@mail.org",
                        UUID.randomUUID().toString(),
                        "79123456789"
                ),
                ""
        );
BillResponse response = client.createBill(billInfo);
client.CreateBill(
    info: new CreateBillInfo
    {
        BillId = Guid.NewGuid().ToString(),
        Amount = new MoneyAmount
        {
            ValueDecimal = 199.9m,
            CurrencyEnum = CurrencyEnum.Rub
        },
        Comment = "Hello world",
        ExpirationDateTime = DateTime.Now.AddDays(45),
        Customer = new Customer
        {
            Email = "example@mail.org",
            Account = Guid.NewGuid().ToString(),
            Phone = "79123456789"
        },
        CustomFields: new CustomFields
        {
            ThemeCode = "Ivan-VbRVlW-YGL"
        }
    },
);
curl --location \
  --request PUT \
  'https://api.qiwi.com/partner/bill/v1/bills/cc961e8d-d4d6-4f02-b737-2297e51fb48e' \
  --header 'content-type: application/json' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer <SECRET_KEY>' \
  --data-raw '{
     "amount": {
       "currency": "RUB",
       "value": "1.00"
     },
     "comment": "Text comment",
     "expirationDateTime": "2025-12-10T09:02:00+03:00",
     "customer": {
       "phone": "78710009999",
       "email": "test@tester.com",
       "account": "454678"
     },
     "customFields" : {
       "paySourcesFilter":"qw",
       "themeCode": "Yvan-YKaSh",
       "yourParam1": "64728940",
       "yourParam2": "order 678"
     }
  }'

Обязательные параметры:

Рекомендуем использовать дополнительные параметры:

alt_text

Необязательные параметры для выставления счета:

Ответ

{
  "siteId": "270305",
  "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
  "amount": {
    "currency": "RUB",
    "value": "1.00"
  },
  "status": {
    "value": "WAITING",
    "changedDateTime": "2020-07-28T19:44:07.855+03:00"
  },
  "comment": "Мой комментарий",
  "customFields": {
    "themeCode": "кодСтиля",
  },
  "creationDateTime": "2020-07-28T19:44:07.855+03:00",
  "expirationDateTime": "2020-08-28T19:44:07.855+03:00",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=bb773791-9bd9-42c1-b8fc-3358cd108422"
}
Array
(
    [siteId] => 270305
    [billId] => cc961e8d-d4d6-4f02-b737-2297e51fb48e
    [amount] => Array
        (
            [currency] => RUB
            [value] => 1.00
        )

    [status] => Array
        (
            [value] => WAITING
            [changedDateTime] => 2020-07-28T19:44:38.855+03:00
        )

    [comment] => Hello world
    [customFields] => Array
        (
            [themeCode] => кодТемы
        )
    [creationDateTime] => 2020-07-28T19:44:07.855+03:00
    [expirationDateTime] => 2020-08-28T19:44:07.855+03:00
    [payUrl] => https://oplata.qiwi.com/form/?invoice_uid=bb773791-9bd9-42c1-b8fc-3358cd108422
)
{
  "siteId": "270304",
  "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
  "amount": {
    "value": "199.90",
    "currency": "RUB"
  },
  "status": {
    "value": "WAITING",
    "changedDateTime": "2020-08-28T19:44:51.407Z"
  },
  "comment": "Мой комментарий",
  "customer": {
    "email": "example@mail.org",
    "account": "040c3bb8-b207-4ecc-9ff9-90168d3bc34f",
    "phone": "79123456789"
  },
  "creationDateTime": "2020-07-28T19:49:07.407Z",
  "expirationDateTime": "2020-09-10T19:49:07.407Z",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=c77a9051-1467-416b-991e-c25f06c61168",
  "customFields": {
    "apiClient": "java_sdk",
    "apiClientVersion": "1.0.0"
  }
}
new BillResponse
{
    SiteId = "270304",
    BillId = "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
    Amount = new MoneyAmount
    {
        ValueString = "199.90",
        CurrencyString = "RUB"
    },
    Status = new ResponseStatus
    {
        ValueString: "WAITING",
        ChangedDateTime: BillPaymentsUtils.ParseDate("2020-07-28T19:44:07+03:00")
    },
    Comment = "Hello world",
    Customer = new Customer
    {
        Email = "example@mail.org",
        Account = "040c3bb8-b207-4ecc-9ff9-90168d3bc34f",
        Phone = "79123456789"
    },
    CreationDateTime = BillPaymentsUtils.ParseDate("2020-07-28T19:44:07+03:00"),
    ExpirationDateTime = BillPaymentsUtils.ParseDate("2020-09-10T19:44:07+03:00"),
    PayUrl = new Uri("https://oplata.qiwi.com/form/?invoice_uid=c77a9051-1467-416b-991e-c25f06c61168"),
    CustomFields = new CustomFields
    {
        ApiClient = "dotnet_sdk",
        ApiClientVersion = "0.1.0",
        ThemeCode = "Ivan-VbRVlW-YGL"
    }
};
{
    "siteId": "9hh4jb-00",
    "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
    "amount": {
        "currency": "RUB",
        "value": "1.00"
    },
    "status": {
        "value": "WAITING",
        "changedDateTime": "2021-01-18T14:22:56.672+03:00"
    },
    "customer": {
        "phone": "78710009999",
        "email": "test@tester.com",
        "account": "454678"
    },
    "customFields": {
        "paySourcesFilter": "qw",
        "themeCode": "Yvan-YKaSh",
        "yourParam1": "64728940",
        "yourParam2": "order 678"
    },
    "comment": "Text comment",
    "creationDateTime": "2021-01-18T14:22:56.672+03:00",
    "expirationDateTime": "2025-12-10T09:02:00+03:00",
    "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=aa0fa2bb-5452-47ca-9190-cd9c1a73718f"
}

В ответе на запрос выставления счета возвращаются следующие поля:

Если на запрос создания счёта вернулась ошибка — проверьте формат переданных в запрос параметров.

Для тестирования и отладки сервиса рекомендуем выставлять и оплачивать счета суммой 1 рубль.

См. также документацию с примерами выставления счетов.

Шаг 5. Установка дополнительных параметров к ссылке на счёт

https://oplata.qiwi.com/form/?invoice_uid=aa0fa2bb-5452-47ca-9190-cd9c1a73718f&paySource=qw

При выставлении счета через API в ответе присутствует поле payUrl, содержащее ссылку на форму. К данной ссылке можно добавить следующий параметр:

Шаг 6. Редирект пользователя на платежную форму

Пример получения URL оплаты по счету

<?php
/** @var array $bill */
/** @var \Qiwi\Api\BillPayments $billPayments */
$payUrl = $billPayments->getPayUrl($bill, 'http://test.ru/');
// https://oplata.qiwi.com/form/?invoice_uid=d875277b-6f0f-445d-8a83-f62c7c07be77
?>

Реализуйте на вашем сайте перенаправление пользователя на платежную форму по ссылке, полученной в поле payUrl ответа на запрос выставления счёта или по ссылке с дополнительными параметрами, сформированной на шаге 5.

Добавьте реферальные ссылки для платежей с сайта. Полная ссылка подтвердит его реальность и позволит избежать проблем с блокировкой кошелька.

Пример передачи реферальной ссылки

<?php header("Referrer-Policy: no-referrer-when-downgrade"); ?>

Для того, чтобы в новых версиях браузеров передавался полный referer при переходе, необходимо выставить дополнительный заголовок Referrer-Policy в ответе сервера. Это можно сделать для всего сайта или отдельно на той странице, где отрисовывается ссылка на форму оплаты. Значение заголовка должно быть no-referrer-when-downgrade.

Шаг 7. Получение серверных уведомлений об оплате счетов или опрос статуса счета - что выбрать?

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

Формат уведомлений описан в документации.

Данные приходят в теле запроса (body). Данные запроса хранятся в формате JSON.

Так как для отладки уведомлений тестовый контур не предусмотрен, рекомендуем выставлять счета на 1 рубль и оплачивать их самостоятельно.

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

Условия интеграции с API уведомлений

Если вы пока не можете определиться, ознакомьтесь с условиями обслуживания интеграции с API уведомлений:

Если вы выберете механизм уведомлений для интеграции и получения сообщений об успешных платежах, мы все же рекомендуем использовать в дополнение к нему опрос статуса счета.

Шаг 8*. Настройка серверных уведомлений

Пример уведомления

POST /qiwi-notify.php HTTP/1.1
Accept: application/json
Content-type: application/json
X-Api-Signature-SHA256: J4WNfNZd***V5mv2w=
Host: example.com

{ "bill":
  {
     "siteId":"23044",
     "billId":"1519892138404fhr7i272a2",
     "amount":{
        "value":"100",
        "currency":"RUB"
     },
     "status":{
        "value":"PAID",
        "datetime":"2018-03-01T11:16:12"
     },
     "customer":{},
     "customFields":{},
     "creationDateTime":"2018-03-01T11:15:39",
     "expirationDateTime":"2018-04-01T11:15:39+03:00"
   },
  "version":"1"
}

Пример получения уведомления

<?php
    $log_file = fopen(__DIR__ . '/qiwi.txt', 'a+');
    fwrite($log_file, print_r(json_decode(file_get_contents('php://input')), true).PHP_EOL);
    fwrite($log_file, print_r(getallheaders(), true).PHP_EOL);
    fclose($log_file);
?>

Уведомление представляет собой входящий POST-запрос.

Тело запроса содержит JSON-сериализованные данные счета (кодировка UTF-8).

Если не приходят уведомления по счету

  1. Проверьте заголовки. По стандарту они регистронезависимы и ваш клиент может их изменить – смотрите документацию вашего клиента.
  2. Попробуйте отправить себе уведомление, заменив в примере https://test.com/notif.php на URL, который вы указали при создании ключей для получения уведомлений.

    Пример:

    curl --location --request POST 'https://test.com/notif.php' --header 'Accept: application/json' --header 'Content-type: application/json' --header 'Cookie: laravel_session=qePlTipWuv7zuRn0WTp9StDVFv2nAREe30gte7zk' --data-raw '{"bill":{"siteId":"2304","billId":"151989213804fhr7i272a2","amount":{"value":"1","currency":"RUB"},"status":{"value":"PAID","datetime":"2020-07-28T11:16:12"},"customer":{},"customFields":{},"creationDateTime":"2020-07-28T11:15:39","expirationDateTime":"2020-08-28T11:15:39+03:00"},"version":"1"}'

  3. Если вы используете сторонние сервисы, создающие готовые эндпоинты для приема запросов по https (например, Google Apps Scripts), убедитесь, что можно отправлять запросы в ваш сервис без дополнительной авторизации (в том числе анонимным пользователям).
  4. Если вы не используете облачные сервисы для приема уведомлений (например, Amazon или Heroku), а настраивали свой веб-сервер и SSL в нем самостоятельно, проверьте ssl сертификат.

    Если ssl сертификат для установления соединения по https выпущен не общеизвестным доверенным центром сертификации (например, Comodo, Verisign, Thawte и т.п.), проверьте, что ваш сервер при установке соединения отправляет полную цепочку сертификатов, включая доверенный корневой центр сертификации в начале цепочки.

    Убедиться в том, что сервер присылает полную цепочку сертификатов, можно при помощи утилиты командной строки openssl, пример есть здесь.

    Полную цепочку сертификатов вы можете загрузить на сайте центра сертификации, выпустившего ваш сертификат.

Шаг 9*. Проверка подписи уведомлений

Настоятельно рекомендуем проверять уведомления на подлинность, т.к. мы не несем ответственности, если будут приходить поддельные уведомления от мошенников.

Процесс проверки подлинности уведомлений описан в документации.

Данные приходят в теле запроса (body). Данные запроса хранятся в формате JSON.

Для проверки подлинности используется механизм цифровой подписи. Подпись уведомления отправляется в HTTP-заголовке X-Api-Signature-SHA256. Для формирования подписи используется механизм проверки целостности HMAC с хэш-функцией SHA256.

Пример

const validSignatureFromNotificationServer =
      '07e0ebb10916d97760c196034105d010607a6c6b7d72bfa1c3451448ac484a3b';

const notificationData = {
    bill: {
        siteId: '270304',
        billId: 'cc961e8d-d4d6-4f02-b737-2297e51fb48e',
        amount: {value: 1, currency: 'RUB'},
        status: {value: 'PAID'}
    },
    version: '3'
};

const merchantSecret = 'eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************';

qiwiApi.checkNotificationSignature(
    validSignatureFromNotificationServer, notificationData, merchantSecret
); // true
<?php

$validSignatureFromNotificationServer = '07e0ebb10916d97760c196034105d010607a6c6b7d72bfa1c3451448ac484a3b';
$notificationData = [
  'bill' => [
    'siteId' => '270304',
    'billId' => 'cc961e8d-d4d6-4f02-b737-2297e51fb48e',
    'amount' => ['value' => 1, 'currency' => 'RUB'],
    'status' => ['value' => 'PAID']
  ],
  'version' => '3'
];
$merchantSecret = 'eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************';

/** @var \Qiwi\Api\BillPayments $billPayments */
$billPayments->checkNotificationSignature(
  $validSignatureFromNotificationServer, $notificationData, $merchantSecret
); // true

?>
String merchantSecret = "eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************";
Notification notification = new Notification(
        new Bill(
                "270304",
                "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
                new MoneyAmount(
                        BigDecimal.ONE,
                        Currency.getInstance("RUB")
                ),
                BillStatus.PAID
        ),
        "3"
);
String validSignature = "07e0ebb10916d97760c196034105d010607a6c6b7d72bfa1c3451448ac484a3b";

BillPaymentsUtils.checkNotificationSignature(validSignature, notification, merchantSecret); //true
Assert.IsTrue(
    condition: BillPaymentsUtils.CheckNotificationSignature(
        validSignature: "07e0ebb10916d97760c196034105d010607a6c6b7d72bfa1c3451448ac484a3b",
        notification: new Notification
        {
            Bill = new Bill
            {
                SiteId = "270304",
                BillId = "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
                Amount = new MoneyAmount
                {
                    ValueDecimal = 1m,
                    CurrencyEnum = CurrencyEnum.Rub
                },
                Status = new BillStatus
                {
                    ValueEnum = BillStatusEnum.Paid
                }
            ),
            Version = "1"
        },
        merchantSecret: "eyJ2ZXJzaW9uIjoicmVzdF92MyIsImRhdGEiOnsibWVyY2hhbnRfaWQiOjUyNjgxMiwiYXBpX3VzZXJfaWQiOjcxNjI2MTk3LCJzZWNyZXQiOiJmZjBiZmJiM2UxYzc0MjY3YjIyZDIzOGYzMDBkNDhlYjhiNTnONPININONPN090MTg5Z**********************"
    )
);

Алгоритм проверки подписи:

  1. Объединить значения следующих параметров уведомления в одну строку с разделителем |:

    invoice_parameters = {amount.currency}|{amount.value}|{billId}|{siteId}|{status.value}

    где {*} – значение параметра. Все значения при проверке подписи должны трактоваться как строки.

  2. Вычислить HMAC-хэш c алгоритмом хэширования SHA256:

    hash = HMAС(SHA256, invoice_parameters, secret_key)

    где: secret_key – секретный ключ, при помощи которого был выставлен счёт; invoice_parameters – строка из п.1.

  3. Сравнить значение заголовка X-Api-Signature-SHA256 с результатом из п.2.

В разрабатываемом коде заведите константу merchantSecret и присвойте ей значение секретного ключа, который выпустили в личном кабинете. Значение должно быть то же самое, что в константе SECRET_KEY на шаге авторизации.

Проверьте, что ключ скопирован полностью, в конце должен быть знак "равно" =.

Шаг 10*. Обработка уведомлений - отправка 200 OK

HTTP/1.1 200 OK
Content-Type: application/json

{
 "error":"0"
}

После проверки уведомлений на подлинность отправьте QIWI ответ на уведомление успешным статусом.

Если вы наблюдаете задержки в получении уведомлений более 10 минут (увеличился баланс вашего кошелька или написал клиент, что оплатил, а уведомление так и не пришло) – рекомендуем в дополнение переключиться на поллинг статусов счетов – см. следующий шаг.

Шаг 11*. Проверка статуса перевода по счету

Пример

const billId = 'cc961e8d-d4d6-4f02-b737-2297e51fb48e';

qiwiApi.getBillInfo(billId).then( data => {
    //do with data
});
<?php

$billId = '4fa5cb2a-942e-4e67-b552-ff10c71d6f8d';

/** @var \Qiwi\Api\BillPayments $billPayments */
$response = $billPayments->getBillInfo($billId);

print_r($response);

?>
String billId = "fcb40a23-6733-4cf3-bacf-8e425fd1fc71";
BillResponse response = client.getBillInfo(billId);
client.GetBillInfo(
    billId: "fcb40a23-6733-4cf3-bacf-8e425fd1fc71"
);
curl --location \
  --request GET \
  'https://api.qiwi.com/partner/bill/v1/bills/cc961e8d-d4d6-4f02-b737-2297e51fb48e' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer <SECRET_KEY>'

Ответ

{
  "siteId": "270305",
  "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
  "amount": {
    "currency": "RUB",
    "value": "200.34"
  },
  "status": {
    "value": "WAITING",
    "changedDateTime": "2020-07-29T19:31:06.846+03:00"
  },
  "comment": "Text comment",
  "creationDateTime": "2020-07-28T19:31:06.846+03:00",
  "expirationDateTime": "2020-08-8T19:31:06.846+03:00",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=ee3ad91d-cfb8-4dbf-8449-b6859fdfec3c"
}
Array
(
    [siteId] => 270305
    [billId] => 4fa5cb2a-942e-4e67-b552-ff10c71d6f8d
    [amount] => Array
        (
            [currency] => RUB
            [value] => 200.34
        )

    [status] => Array
        (
            [value] => WAITING
            [changedDateTime] => 2018-07-12T10:31:06.846+03:00
        )

    [comment] => test
    [creationDateTime] => 2020-07-28T19:31:06.846+03:00
    [expirationDateTime] => 2020-08-28T19:31:06.846+03:00
    [payUrl] => https://oplata.qiwi.com/form/?invoice_uid=ee3ad91d-cfb8-4dbf-8449-b6859fdfec3c
)
{
  "siteId": "270304",
  "billId": "fcb40a23-6733-4cf3-bacf-8e425fd1fc71",
  "amount": {
    "value": "199.90",
    "currency": "RUB"
  },
  "status": {
    "value": "WAITING",
    "changedDateTime": "2020-07-28T16:03:09.062Z"
  },
  "comment": "Text comment",
  "customer": {
    "email": "example@mail.org",
    "account": "349d5978-bccc-4e10-be7e-3ca0808237b7",
    "phone": "79123456789"
  },
  "creationDateTime": "2020-07-28T16:03:09.062Z",
  "expirationDateTime": "2020-08-28T16:03:08.668Z",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=b77618b4-746c-485f-8bb8-fff43ddef114",
  "customFields": {
    "apiClient": "java_sdk",
    "apiClientVersion": "1.0.0"
  }
}
new BillResponse
{
    SiteId = "270304",
    BillId = "fcb40a23-6733-4cf3-bacf-8e425fd1fc71",
    Amount = new MoneyAmount
    {
        ValueString = "199.90",
        CurrencyString = "RUB"
    },
    Status = new ResponseStatus
    {
        ValueString: "WAITING",
        ChangedDateTime: BillPaymentsUtils.ParseDate("2020-07-28T16:03:09+03:00")
    },
    Comment = "test",
    Customer = new Customer
    {
        Email = "example@mail.org",
        Account = "349d5978-bccc-4e10-be7e-3ca0808237b7",
        Phone = "79123456789"
    },
    CreationDateTime = BillPaymentsUtils.ParseDate("2020-07-28T16:03:09+03:00"),
    ExpirationDateTime = BillPaymentsUtils.ParseDate("2020-08-28T16:03:08+03:00"),
    PayUrl = new Uri("https://oplata.qiwi.com/form/?invoice_uid=b77618b4-746c-485f-8bb8-fff43ddef114"),
    CustomFields = new CustomFields
    {
        ApiClient = "dotnet_sdk",
        ApiClientVersion = "0.1.0"
    }
};
{
    "siteId": "9hh4jb-00",
    "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
    "amount": {
        "currency": "RUB",
        "value": "1.00"
    },
    "status": {
        "value": "WAITING",
        "changedDateTime": "2021-01-18T14:22:56.672+03:00"
    },
    "customer": {
        "email": "test@tester.com",
        "phone": "78710009999",
        "account": "454678"
    },
    "customFields": {
        "paySourcesFilter": "qw",
        "themeCode": "Yvan-YKaSh",
        "yourParam1": "64728940",
        "yourParam2": "order 678"
    },
    "comment": "Text comment",
    "creationDateTime": "2021-01-18T14:22:56.672+03:00",
    "expirationDateTime": "2025-12-10T09:02:00+03:00",
    "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=aa0fa2bb-5452-47ca-9190-cd9c1a73718f"
}

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

Также данный метод можно использовать как самостоятельный, т.е. после выставления счета раз в какой-то промежуток времени опрашивать статус этого счета. Этот метод проще интеграции с сервисом уведомлений.

См. также документацию с примерами проверки статуса оплаты счета.

Реализуйте вызов метода getBillInfo. В параметрах необходимо передать идентификатор счета в вашей системе billId, в результате будет получен ответ со статусом счета.

Шаг 12. Бизнес-логика

Счет в своем жизненном цикле проходит следующие статусы оплаты:

Статус Описание Комментарий
WAITING Счет выставлен, ожидает оплаты Нефинальный, ожидание оплаты или истечения срока действия
PAID Счет оплачен Финальный (измениться не может)
REJECTED Счет отклонен Финальный (измениться не может)
EXPIRED Время жизни счета истекло. Счет не оплачен Финальный (измениться не может)

Опираясь на статус счета, полученный в уведомлении или при помощи поллинга статуса, доработайте бизнес-логику вашего сайта.

Например:

Поздравляем, интеграция с QIWI для получения платежей закончена!

Дополнительно. Шаг 13. Отмена неоплаченных счетов

Пример

const billId = '60418b7e-1e95-4ac0-936e-0b98d7a7fdae';

qiwiApi.cancelBill(billId).then( data => {
    //do with data
});
<?php

$billId = '60418b7e-1e95-4ac0-936e-0b98d7a7fdae';

/** @var \Qiwi\Api\BillPayments $billPayments */
$response = $billPayments->cancelBill($billId);

print_r($response);

?>
String billId = "fcb40a23-6733-4cf3-bacf-8e425fd1fc71";
BillResponse response = client.cancelBill(billId);
client.CancelBill(
    billId: "fcb40a23-6733-4cf3-bacf-8e425fd1fc71"
);
curl --location \
  --request POST \
  'https://api.qiwi.com/partner/bill/v1/bills/cc961e8d-d4d6-4f02-b737-2297e51fb48e/reject' \
  --header 'content-type: application/json' \
  --header 'accept: application/json' \
  --header 'Authorization: Bearer <SECRET_KEY>' \
  --data-raw ''

Ответ

{
  "siteId": "270305",
  "billId": "60418b7e-1e95-4ac0-936e-0b98d7a7fdae",
  "amount": {
    "currency": "RUB",
    "value": "200.34"
  },
  "status": {
    "value": "REJECTED",
    "changedDateTime": "2018-07-12T10:32:17.595+03:00"
  },
  "comment": "Text comment",
  "creationDateTime": "2018-07-12T10:32:17.481+03:00",
  "expirationDateTime": "2018-08-26T10:32:17.481+03:00",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=a3fe62b2-9962-4d9d-9025-0766fb492546"
}
Array
(
    [siteId] => 270305
    [billId] => 60418b7e-1e95-4ac0-936e-0b98d7a7fdae
    [amount] => Array
        (
            [currency] => RUB
            [value] => 200.34
        )

    [status] => Array
        (
            [value] => REJECTED
            [changedDateTime] => 2018-07-12T10:32:17.595+03:00
        )

    [comment] => test
    [creationDateTime] => 2018-07-12T10:32:17.481+03:00
    [expirationDateTime] => 2018-08-26T10:32:17.481+03:00
    [payUrl] => https://oplata.qiwi.com/form/?invoice_uid=a3fe62b2-9962-4d9d-9025-0766fb492546
)
{
  "siteId": "270304",
  "billId": "fcb40a23-6733-4cf3-bacf-8e425fd1fc71",
  "amount": {
    "value": "199.90",
    "currency": "RUB"
  },
  "status": {
    "value": "REJECTED",
    "changedDateTime": "2018-11-03T16:03:09.062Z"
  },
  "comment": "Text comment",
  "customer": {
    "email": "example@mail.org",
    "account": "349d5978-bccc-4e10-be7e-3ca0808237b7",
    "phone": "79123456789"
  },
  "creationDateTime": "2018-11-03T16:03:09.062Z",
  "expirationDateTime": "2018-12-18T16:03:08.668Z",
  "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=b77618b4-746c-485f-8bb8-fff43ddef114",
  "customFields": {
    "apiClient": "java_sdk",
    "apiClientVersion": "1.0.0"
  }
}
new BillResponse
{
    SiteId = "270304",
    BillId = "fcb40a23-6733-4cf3-bacf-8e425fd1fc71",
    Amount = new MoneyAmount
    {
        ValueString = "199.90",
        CurrencyString = "RUB"
    },
    Status = new ResponseStatus
    {
        ValueString: "REJECTED",
        ChangedDateTime: BillPaymentsUtils.ParseDate("2018-11-03T16:03:09+03:00")
    },
    Comment = "test",
    Customer = new Customer
    {
        Email = "example@mail.org",
        Account = "349d5978-bccc-4e10-be7e-3ca0808237b7",
        Phone = "79123456789"
    },
    CreationDateTime = BillPaymentsUtils.ParseDate("2018-11-03T16:03:09+03:00"),
    ExpirationDateTime = BillPaymentsUtils.ParseDate("2018-12-18T16:03:08+03:00"),
    PayUrl = new Uri("https://oplata.qiwi.com/form/?invoice_uid=b77618b4-746c-485f-8bb8-fff43ddef114"),
    CustomFields = new CustomFields
    {
        ApiClient = "dotnet_sdk",
        ApiClientVersion = "0.1.0"
    }
};
{
    "siteId": "9hh4jb-00",
    "billId": "cc961e8d-d4d6-4f02-b737-2297e51fb48e",
    "amount": {
        "currency": "RUB",
        "value": "1.00"
    },
    "status": {
        "value": "REJECTED",
        "changedDateTime": "2021-01-18T14:36:17.65+03:00"
    },
    "customer": {
        "email": "test@tester.com",
        "phone": "78710009999",
        "account": "454678"
    },
    "customFields": {
        "paySourcesFilter": "qw",
        "themeCode": "Yvan-YKaSh",
        "yourParam1": "64728940",
        "yourParam2": "order 678"
    },
    "comment": "Text comment",
    "creationDateTime": "2021-01-18T14:22:56.672+03:00",
    "expirationDateTime": "2025-12-10T09:02:00+03:00",
    "payUrl": "https://oplata.qiwi.com/form/?invoice_uid=aa0fa2bb-5452-47ca-9190-cd9c1a73718f"
}

Вы можете отменять неоплаченные счета самостоятельно, используя метод cancelBill.

См. также документацию с примерами запросов для отмены неоплаченных счетов.