pyQiwiP2P


NamepyQiwiP2P JSON
Version 2.0.7 PyPI version JSON
download
home_pagehttps://github.com/WhiteApfel/pyQiwiP2P
SummarypyQiwiP2P
upload_time2023-06-11 13:42:39
maintainer
docs_urlNone
authorWhiteApfel
requires_python
licenseMozilla Public License 2.0
keywords qiwip2p api qiwi p2p payments bill tools sdk wrapper
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pyQiwiP2P

[![CodeFactor](https://www.codefactor.io/repository/github/whiteapfel/pyqiwip2p/badge)](https://www.codefactor.io/repository/github/whiteapfel/pyqiwip2p)

## Поддержка прекращена

Есть более качественный инструмент, полностью покрывающий функции pyQiwiP2P: [glQiwiApi](https://github.com/GLEF1X/glQiwiApi)

Возможно, здесь когда-нибудь будет гайд по миграции на него, но всё в руках сообщества

### О библиотеке

Штучка для удобной работы с кивишной апишкой платежей

Есть типа [документация](https://pyqiwip2p.readthedocs.io/ru/latest/), но в ней есть и косячки, поэтому, 
если найдёте таковой, обязательно сообщите мне. Буду искренне рад. Правда. Спасибо.

### Миграция с первой версии:

 1. Свойство ``Bill.actual`` было удалено из-за PEP8
 2. ``QiwiNotify`` по умолчанию выполняет только функцию по первому подошедшему хендлеру

### ⚠️ Важное уведомление [2023.04.05]

Выпуск ключей для приёма P2P платежей через сайт официально закрыт, 
но метод, заявленный в [документации QIWI](https://github.com/QIWI-API/qiwi-wallet-personal-docs/blob/94cf6b68a12dea916d99144b4f7a12ab810753d5/_payment_ru.html.md#выпуск-токена-p2p-p2p-token), 
продолжает работать, хоть и с несколько изменённой авторизацией. 

Инструкция:

1. Переходим на https://qiwi.com/p2p-admin
2. Авторизуемся в свой Qiwi аккаунт
3. Открываем консоль браузера. [Как?](https://duckduckgo.com/?q=Как+открыть+консоль+браузера)
4. Вставляем код из первого блока и нажимаем enter
5. Вставляем код из второго блока и нажимаем enter
6. Если прошло успешно:
   * появится строка "Private Key: <KEY>"
   * копируем ключ, и используем по назначению
7. Если что-то пошло не так:
   * смириться, что накосячили
   * меня не тревожить
   * мне в личку не писать
   * кусаюсь и кидаю в чс

```javascript
function createKeys(name, notification_url) {
    let p2pApiData = JSON.parse(localStorage.getItem("p2p-admin-checkout-oauth-token-head"))
    let token = btoa(p2pApiData["client_id"] + ":" + p2pApiData["access_token"]).replaceAll("=", "")

    let body = {
        keysPairName: name
    }

    if (notification_url) {
        body.serverNotificationsUrl = notification_url
    }

    fetch('https://edge.qiwi.com/widgets-api/api/p2p/protected/keys/create', {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': "TokenHeadV2 " + token
        },
        body: JSON.stringify(body),
        credentials: 'include',
    })
    .then(response => {
        console.log(response.status);
        return response.json();
    })
    .then(data => {
        console.log(data);
        console.log("Private Key: "+ data.result.secretKey)
    })
    .catch(error => console.error(error));
}
```
```javascript
createKeys("Tokens by WhiteApfel")
// or
createKeys("Tokens by WhiteApfel", "https://qiwi.example.com/any")
```

### ⚠️ Важное уведомление [2021.06.13]

С июня Qiwi начала блокировать кошельки, если пользователь открыл
страницу оплаты "напрямую", тем самым не передав заголовок referer.

**Это случается при открытии ссылки:**

 * из мессенджера
 * из смс
 * из письма
 * из адресной строки
 * из браузера с повышенным режимом приватности или расширениями для приватного просмотра

Для обхода всех проблем, кроме последней (она не решается), к объекту
``Bill`` был добавлен атрибут ``Bill.alt_url``, который предоставляет ссылку
для перенаправления на страницу оплаты через специальную
страницу-прокладу, добавляющую этот самый referer.

Страница предоставлена мною, но её можно поднять на своём сервере
с помощью docker-контейнера.

 * Исходники: [Github](https://github.com/WhiteApfel/pyQiwiP2P/tree/master/p2proxy)
 * Образ контейнера: ``ghcr.io/whiteapfel/pyqiwip2p:p2proxy``
 * Запуск: ``docker run -p 3600:3600 -e QP2P_DOMAIN='example.com' -d ghcr.io/whiteapfel/pyqiwip2p:p2proxy``
 * Свой домен в клиенте: ``p2p = AioQiwiP2P(PrivKey, alt="example.com")``


---
## А как пользоваться

### Что есть?
Есть сам класс QiwiP2P, который обладает тремя инструментами:
для выставления, проверки и закрытия платежа (счёта). 


Пример использования:

```python
from pyqiwip2p import QiwiP2P
from pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods

QIWI_PRIV_KEY = "abCdef...xYz"

p2p = QiwiP2P(auth_key=QIWI_PRIV_KEY)

# Выставим счет на сумму 228 рублей который будет работать 45 минут
new_bill = p2p.bill(bill_id=212332030, amount=228, lifetime=45)

print(new_bill.bill_id, new_bill.pay_url)

# Проверим статус выставленного счета
print(p2p.check(bill_id=new_bill.bill_id).status)

# Потеряли ссылку на оплату счета? Не проблема!
print(p2p.check(bill_id=245532).pay_url)

# Клиент отменил заказ? Тогда и счет надо закрыть
p2p.reject(bill_id=new_bill.bill_id)

# Если планируете выставлять счета с одинаковой суммой,
# можно воспользоваться параметром default_amount
p2p = QiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148)

# Теперь, если не указывать в методе p2p.bill() значение суммы заказа,
# будет применяться указанная базовая сумма
new_bill = p2p.bill(bill_id=6627358)

# А ещё можно не указывать bill_id, тогда значение сгенерируется автоматически.
# Его можно будет посмотреть в объекте ответа Bill
# В комбинации со стандартным значением суммы будет вот так
new_bill = p2p.bill()
print(new_bill.bill_id, new_bill.pay_url)

# Чтобы запретить приём платежей через какой-то метод оплаты, например, карты,
# необходимо передать paySourcesFilter в fields. Туда же можно передать themeCode

fields = {
    "paySourcesFilter": "qw,card",
    "themeCode": "MalchikGay",
}
p2p.bill(fields=fields)

# Либо же воспользоваться удобными полями

p2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card])
p2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code="MalchikGay")
```

### А асинхронно могёте?
Могём. Причём примерно так же.

```python
from pyqiwip2p import AioQiwiP2P
from pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods

QIWI_PRIV_KEY = "abCdef...xYz"

p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY)

# Если планируете выставлять счета с одинаковой суммой,
# можно воспользоваться параметром default_amount
p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148)

async def main():
    async with p2p:
        # Выставим счет на сумму 228 рублей который будет работать 45 минут
        new_bill = await p2p.bill(bill_id=212332030, amount=228, lifetime=45)
        
        print(new_bill.bill_id, new_bill.pay_url)
        
        # Проверим статус выставленного счета
        print((await p2p.check(bill_id=new_bill.bill_id)).status)
        
        # Потеряли ссылку на оплату счета? Не проблема!
        print((await p2p.check(bill_id=245532)).pay_url)
        
        # Клиент отменил заказ? Тогда и счет надо закрыть
        await p2p.reject(bill_id=new_bill.bill_id)
        
        # Если не указывать в методе p2p.bill() значение суммы заказа,
        # будет применяться указанная базовая сумма, которую вы установили
        new_bill = await p2p.bill(bill_id=6627358)
        
        # А ещё можно не указывать bill_id, тогда значение сгенерируется автоматически.
        # Его можно будет посмотреть в объекте ответа Bill
        # В комбинации со стандартным значением суммы будет вот так
        new_bill = await p2p.bill()
        print(new_bill.bill_id, new_bill.pay_url)
        
        # Чтобы запретить приём платежей через какой-то метод оплаты, например, карты,
        # необходимо передать paySourcesFilter в fields. Туда же можно передать themeCode
        
        fields = {
            "paySourcesFilter": "qw,card",
            "themeCode": "MalchikGay",
        }
        await p2p.bill(fields=fields)
        
        # Либо же воспользоваться удобными полями
        
        await p2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card])
        await p2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code="MalchikGay")

p2p.run(main())
# Аналог
# asyncio.run(main())
```

### И всё?
Нет, не всё. Ещё можно настроить кивишные уведомления на свой сервер, 
для этого придется немного пострадать, но лишь немного.

**Внимание!** Для работы будет необходим проксирующий сервер (например, Nginx) с доверенным SSL-сертификатом. 
Да. Подробнее про требования к проксирующему серверу в [документации Qiwi](https://developer.qiwi.com/ru/p2p-payments/?shell#notification "Почитай, это полезно")

А эта шайтан-машина нужна для захендлирования функций на события. Она не готова самостоятельно контактировать с внешним миром. Пожалей её.

Запросы сервер по умолчанию принимает на 8099 порту, его можно изменить, и только на `/qiwi_notify` - изменить нельзя.

```python
from pyqiwip2p.notify import QiwiNotify
from pyqiwip2p.p2p_types import Bill

QIWI_PRIV_KEY = "abCdef...xYz"

qiwi_notify = QiwiNotify(QIWI_PRIV_KEY)

#
# Хэндлер принимает в себя аргументом функцию,
# в которую передаст объект счёта - Bill
#

# Добавим хэндлер, который будет печатать billID для всех счетов
@qiwi_notify.handler(lambda bill: True)
def print_bill(bill: Bill):
	print(bill.bill_id)


# Создадим хэндлер, который будет печатать сумму оплаченных счетов
@qiwi_notify.handler(lambda bill: bill.status == "PAID")
def print_bill(bill: Bill):
	print(bill.amount)


# Теперь запустим сервер на 12345'ом порту
qiwi_notify.start(port=12345)
```

### И асинхронный сервер, наверное, у вас есть?
Да есть. Причём хендлить функции можно и асинхронные, и синхронные.

```python
from pyqiwip2p import QiwiP2P, AioQiwiP2P
from pyqiwip2p.p2p_types import Bill
from pyqiwip2p.notify import AioQiwiNotify
import asyncio

QIWI_PRIV_KEY = "abCdef...xYz"

qiwi_notify = AioQiwiNotify(QIWI_PRIV_KEY)
p2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY)


@qiwi_notify.handler(lambda bill: bill.status == "EXPIRED")
async def on_expired(bill: Bill):
	new_bill = await p2p.bill(amount=bill.amount, comment=bill.comment)
	print(new_bill.pay_url)


@qiwi_notify.handler(lambda bill: True)
def on_all(bill: Bill):
	print(bill.status)


async def main():
	p = asyncio.get_event_loop()
	server = p.create_task(qiwi_notify.a_start(port=12345))
	await server


loop = asyncio.get_event_loop()
loop.run_until_complete(main())
```

### Настройка проксирующего Nginx
Для порта 12345 (как в примерах выше) будет:
```
server {
    listen 443;
    server_name qiwinotify.domain.com;
    ssl_certificate      cert.crt;
    ssl_certificate_key  pkey.key;
    location /superSecretQiwiURI {
        proxy_pass http://0.0.0.0:12345/qiwi_notify;
    }
}
```
В таком случае при генерации ключей API на https://qiwi.com/p2p-admin/transfers/api
нужно будет указать `https://qiwinotify.domain.com/superSecretQiwiURI` в качестве URL для уведомлений

**P.S. за неприходящие от Qiwi запросы ответственность не несу, как и за приходящие, кстати, тоже.
Если запроса от Qiwi не было, то пишите им в поддержку [@qiwi_api_help_bot](https://t.me/qiwi_api_help_bot)**

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/WhiteApfel/pyQiwiP2P",
    "name": "pyQiwiP2P",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "qiwip2p api qiwi p2p payments bill tools sdk wrapper",
    "author": "WhiteApfel",
    "author_email": "white@pfel.ru",
    "download_url": "https://files.pythonhosted.org/packages/b6/ef/17c717b3d1ac7e8ff77a1c0e3e1135df0d2646d62f3fabf6acf0e9e5e810/pyQiwiP2P-2.0.7.tar.gz",
    "platform": null,
    "description": "# pyQiwiP2P\n\n[![CodeFactor](https://www.codefactor.io/repository/github/whiteapfel/pyqiwip2p/badge)](https://www.codefactor.io/repository/github/whiteapfel/pyqiwip2p)\n\n## \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0430\n\n\u0415\u0441\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 pyQiwiP2P: [glQiwiApi](https://github.com/GLEF1X/glQiwiApi)\n\n\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0437\u0434\u0435\u0441\u044c \u043a\u043e\u0433\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0431\u0443\u0434\u0435\u0442 \u0433\u0430\u0439\u0434 \u043f\u043e \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043d\u0435\u0433\u043e, \u043d\u043e \u0432\u0441\u0451 \u0432 \u0440\u0443\u043a\u0430\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430\n\n### \u041e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435\n\n\u0428\u0442\u0443\u0447\u043a\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u0438\u0432\u0438\u0448\u043d\u043e\u0439 \u0430\u043f\u0438\u0448\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439\n\n\u0415\u0441\u0442\u044c \u0442\u0438\u043f\u0430 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f](https://pyqiwip2p.readthedocs.io/ru/latest/), \u043d\u043e \u0432 \u043d\u0435\u0439 \u0435\u0441\u0442\u044c \u0438 \u043a\u043e\u0441\u044f\u0447\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \n\u0435\u0441\u043b\u0438 \u043d\u0430\u0439\u0434\u0451\u0442\u0435 \u0442\u0430\u043a\u043e\u0432\u043e\u0439, \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0431\u0449\u0438\u0442\u0435 \u043c\u043d\u0435. \u0411\u0443\u0434\u0443 \u0438\u0441\u043a\u0440\u0435\u043d\u043d\u0435 \u0440\u0430\u0434. \u041f\u0440\u0430\u0432\u0434\u0430. \u0421\u043f\u0430\u0441\u0438\u0431\u043e.\n\n### \u041c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438:\n\n 1. \u0421\u0432\u043e\u0439\u0441\u0442\u0432\u043e ``Bill.actual`` \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043e \u0438\u0437-\u0437\u0430 PEP8\n 2. ``QiwiNotify`` \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e \u043f\u0435\u0440\u0432\u043e\u043c\u0443 \u043f\u043e\u0434\u043e\u0448\u0435\u0434\u0448\u0435\u043c\u0443 \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0443\n\n### \u26a0\ufe0f \u0412\u0430\u0436\u043d\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 [2023.04.05]\n\n\u0412\u044b\u043f\u0443\u0441\u043a \u043a\u043b\u044e\u0447\u0435\u0439 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 P2P \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u0441\u0430\u0439\u0442 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u043a\u0440\u044b\u0442, \n\u043d\u043e \u043c\u0435\u0442\u043e\u0434, \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 QIWI](https://github.com/QIWI-API/qiwi-wallet-personal-docs/blob/94cf6b68a12dea916d99144b4f7a12ab810753d5/_payment_ru.html.md#\u0432\u044b\u043f\u0443\u0441\u043a-\u0442\u043e\u043a\u0435\u043d\u0430-p2p-p2p-token), \n\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0445\u043e\u0442\u044c \u0438 \u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439. \n\n\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f:\n\n1. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 https://qiwi.com/p2p-admin\n2. \u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u0432 \u0441\u0432\u043e\u0439 Qiwi \u0430\u043a\u043a\u0430\u0443\u043d\u0442\n3. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. [\u041a\u0430\u043a?](https://duckduckgo.com/?q=\u041a\u0430\u043a+\u043e\u0442\u043a\u0440\u044b\u0442\u044c+\u043a\u043e\u043d\u0441\u043e\u043b\u044c+\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430)\n4. \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u0434 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c enter\n5. \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u0434 \u0438\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c enter\n6. \u0415\u0441\u043b\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e:\n   * \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \"Private Key: <KEY>\"\n   * \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u043a\u043b\u044e\u0447, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e\n7. \u0415\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a:\n   * \u0441\u043c\u0438\u0440\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u043a\u043e\u0441\u044f\u0447\u0438\u043b\u0438\n   * \u043c\u0435\u043d\u044f \u043d\u0435 \u0442\u0440\u0435\u0432\u043e\u0436\u0438\u0442\u044c\n   * \u043c\u043d\u0435 \u0432 \u043b\u0438\u0447\u043a\u0443 \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c\n   * \u043a\u0443\u0441\u0430\u044e\u0441\u044c \u0438 \u043a\u0438\u0434\u0430\u044e \u0432 \u0447\u0441\n\n```javascript\nfunction createKeys(name, notification_url) {\n    let p2pApiData = JSON.parse(localStorage.getItem(\"p2p-admin-checkout-oauth-token-head\"))\n    let token = btoa(p2pApiData[\"client_id\"] + \":\" + p2pApiData[\"access_token\"]).replaceAll(\"=\", \"\")\n\n    let body = {\n        keysPairName: name\n    }\n\n    if (notification_url) {\n        body.serverNotificationsUrl = notification_url\n    }\n\n    fetch('https://edge.qiwi.com/widgets-api/api/p2p/protected/keys/create', {\n        method: 'POST',\n        headers: {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'Authorization': \"TokenHeadV2 \" + token\n        },\n        body: JSON.stringify(body),\n        credentials: 'include',\n    })\n    .then(response => {\n        console.log(response.status);\n        return response.json();\n    })\n    .then(data => {\n        console.log(data);\n        console.log(\"Private Key: \"+ data.result.secretKey)\n    })\n    .catch(error => console.error(error));\n}\n```\n```javascript\ncreateKeys(\"Tokens by WhiteApfel\")\n// or\ncreateKeys(\"Tokens by WhiteApfel\", \"https://qiwi.example.com/any\")\n```\n\n### \u26a0\ufe0f \u0412\u0430\u0436\u043d\u043e\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0435 [2021.06.13]\n\n\u0421 \u0438\u044e\u043d\u044f Qiwi \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0448\u0435\u043b\u044c\u043a\u0438, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043a\u0440\u044b\u043b\n\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u043f\u043b\u0430\u0442\u044b \"\u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e\", \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a referer.\n\n**\u042d\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0441\u044b\u043b\u043a\u0438:**\n\n * \u0438\u0437 \u043c\u0435\u0441\u0441\u0435\u043d\u0434\u0436\u0435\u0440\u0430\n * \u0438\u0437 \u0441\u043c\u0441\n * \u0438\u0437 \u043f\u0438\u0441\u044c\u043c\u0430\n * \u0438\u0437 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438\n * \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0436\u0438\u043c\u043e\u043c \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f\u043c\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430\n\n\u0414\u043b\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043a\u0440\u043e\u043c\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 (\u043e\u043d\u0430 \u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f), \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443\n``Bill`` \u0431\u044b\u043b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0430\u0442\u0440\u0438\u0431\u0443\u0442 ``Bill.alt_url``, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443\n\u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u043f\u043b\u0430\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e\n\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443-\u043f\u0440\u043e\u043a\u043b\u0430\u0434\u0443, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 referer.\n\n\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u043c\u043d\u043e\u044e, \u043d\u043e \u0435\u0451 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0451\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435\n\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430.\n\n * \u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438: [Github](https://github.com/WhiteApfel/pyQiwiP2P/tree/master/p2proxy)\n * \u041e\u0431\u0440\u0430\u0437 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430: ``ghcr.io/whiteapfel/pyqiwip2p:p2proxy``\n * \u0417\u0430\u043f\u0443\u0441\u043a: ``docker run -p 3600:3600 -e QP2P_DOMAIN='example.com' -d ghcr.io/whiteapfel/pyqiwip2p:p2proxy``\n * \u0421\u0432\u043e\u0439 \u0434\u043e\u043c\u0435\u043d \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435: ``p2p = AioQiwiP2P(PrivKey, alt=\"example.com\")``\n\n\n---\n## \u0410 \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f\n\n### \u0427\u0442\u043e \u0435\u0441\u0442\u044c?\n\u0415\u0441\u0442\u044c \u0441\u0430\u043c \u043a\u043b\u0430\u0441\u0441 QiwiP2P, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0442\u0440\u0435\u043c\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438:\n\u0434\u043b\u044f \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043f\u043b\u0430\u0442\u0435\u0436\u0430 (\u0441\u0447\u0451\u0442\u0430). \n\n\n\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:\n\n```python\nfrom pyqiwip2p import QiwiP2P\nfrom pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods\n\nQIWI_PRIV_KEY = \"abCdef...xYz\"\n\np2p = QiwiP2P(auth_key=QIWI_PRIV_KEY)\n\n# \u0412\u044b\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0447\u0435\u0442 \u043d\u0430 \u0441\u0443\u043c\u043c\u0443 228 \u0440\u0443\u0431\u043b\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c 45 \u043c\u0438\u043d\u0443\u0442\nnew_bill = p2p.bill(bill_id=212332030, amount=228, lifetime=45)\n\nprint(new_bill.bill_id, new_bill.pay_url)\n\n# \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0447\u0435\u0442\u0430\nprint(p2p.check(bill_id=new_bill.bill_id).status)\n\n# \u041f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443 \u0441\u0447\u0435\u0442\u0430? \u041d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430!\nprint(p2p.check(bill_id=245532).pay_url)\n\n# \u041a\u043b\u0438\u0435\u043d\u0442 \u043e\u0442\u043c\u0435\u043d\u0438\u043b \u0437\u0430\u043a\u0430\u0437? \u0422\u043e\u0433\u0434\u0430 \u0438 \u0441\u0447\u0435\u0442 \u043d\u0430\u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c\np2p.reject(bill_id=new_bill.bill_id)\n\n# \u0415\u0441\u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0447\u0435\u0442\u0430 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0441\u0443\u043c\u043c\u043e\u0439,\n# \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c default_amount\np2p = QiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148)\n\n# \u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 p2p.bill() \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0443\u043c\u043c\u044b \u0437\u0430\u043a\u0430\u0437\u0430,\n# \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0443\u043c\u043c\u0430\nnew_bill = p2p.bill(bill_id=6627358)\n\n# \u0410 \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c bill_id, \u0442\u043e\u0433\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\n# \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 Bill\n# \u0412 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0443\u043c\u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\nnew_bill = p2p.bill()\nprint(new_bill.bill_id, new_bill.pay_url)\n\n# \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u0451\u043c \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u043e\u043f\u043b\u0430\u0442\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u0440\u0442\u044b,\n# \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c paySourcesFilter \u0432 fields. \u0422\u0443\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c themeCode\n\nfields = {\n    \"paySourcesFilter\": \"qw,card\",\n    \"themeCode\": \"MalchikGay\",\n}\np2p.bill(fields=fields)\n\n# \u041b\u0438\u0431\u043e \u0436\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0434\u043e\u0431\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438\n\np2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card])\np2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code=\"MalchikGay\")\n```\n\n### \u0410 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u043c\u043e\u0433\u0451\u0442\u0435?\n\u041c\u043e\u0433\u0451\u043c. \u041f\u0440\u0438\u0447\u0451\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a \u0436\u0435.\n\n```python\nfrom pyqiwip2p import AioQiwiP2P\nfrom pyqiwip2p.p2p_types import QiwiCustomer, QiwiDatetime, PaymentMethods\n\nQIWI_PRIV_KEY = \"abCdef...xYz\"\n\np2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY)\n\n# \u0415\u0441\u043b\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0447\u0435\u0442\u0430 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0441\u0443\u043c\u043c\u043e\u0439,\n# \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c default_amount\np2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY, default_amount=148)\n\nasync def main():\n    async with p2p:\n        # \u0412\u044b\u0441\u0442\u0430\u0432\u0438\u043c \u0441\u0447\u0435\u0442 \u043d\u0430 \u0441\u0443\u043c\u043c\u0443 228 \u0440\u0443\u0431\u043b\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c 45 \u043c\u0438\u043d\u0443\u0442\n        new_bill = await p2p.bill(bill_id=212332030, amount=228, lifetime=45)\n        \n        print(new_bill.bill_id, new_bill.pay_url)\n        \n        # \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0447\u0435\u0442\u0430\n        print((await p2p.check(bill_id=new_bill.bill_id)).status)\n        \n        # \u041f\u043e\u0442\u0435\u0440\u044f\u043b\u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043e\u043f\u043b\u0430\u0442\u0443 \u0441\u0447\u0435\u0442\u0430? \u041d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430!\n        print((await p2p.check(bill_id=245532)).pay_url)\n        \n        # \u041a\u043b\u0438\u0435\u043d\u0442 \u043e\u0442\u043c\u0435\u043d\u0438\u043b \u0437\u0430\u043a\u0430\u0437? \u0422\u043e\u0433\u0434\u0430 \u0438 \u0441\u0447\u0435\u0442 \u043d\u0430\u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c\n        await p2p.reject(bill_id=new_bill.bill_id)\n        \n        # \u0415\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 p2p.bill() \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0443\u043c\u043c\u044b \u0437\u0430\u043a\u0430\u0437\u0430,\n        # \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0430\u044f \u0431\u0430\u0437\u043e\u0432\u0430\u044f \u0441\u0443\u043c\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\n        new_bill = await p2p.bill(bill_id=6627358)\n        \n        # \u0410 \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c bill_id, \u0442\u043e\u0433\u0434\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\n        # \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 Bill\n        # \u0412 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0443\u043c\u043c\u044b \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\n        new_bill = await p2p.bill()\n        print(new_bill.bill_id, new_bill.pay_url)\n        \n        # \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u043f\u0440\u0438\u0451\u043c \u043f\u043b\u0430\u0442\u0435\u0436\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u0435\u0442\u043e\u0434 \u043e\u043f\u043b\u0430\u0442\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u0440\u0442\u044b,\n        # \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c paySourcesFilter \u0432 fields. \u0422\u0443\u0434\u0430 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c themeCode\n        \n        fields = {\n            \"paySourcesFilter\": \"qw,card\",\n            \"themeCode\": \"MalchikGay\",\n        }\n        await p2p.bill(fields=fields)\n        \n        # \u041b\u0438\u0431\u043e \u0436\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0434\u043e\u0431\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438\n        \n        await p2p.bill(pay_sources=[PaymentMethods.qiwi, PaymentMethods.card])\n        await p2p.bill(pay_sources=[PaymentMethods.qiwi], theme_code=\"MalchikGay\")\n\np2p.run(main())\n# \u0410\u043d\u0430\u043b\u043e\u0433\n# asyncio.run(main())\n```\n\n### \u0418 \u0432\u0441\u0451?\n\u041d\u0435\u0442, \u043d\u0435 \u0432\u0441\u0451. \u0415\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0438\u0432\u0438\u0448\u043d\u044b\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \n\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0440\u0430\u0434\u0430\u0442\u044c, \u043d\u043e \u043b\u0438\u0448\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e.\n\n**\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435!** \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, Nginx) \u0441 \u0434\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u043c SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u043c. \n\u0414\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0432 [\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 Qiwi](https://developer.qiwi.com/ru/p2p-payments/?shell#notification \"\u041f\u043e\u0447\u0438\u0442\u0430\u0439, \u044d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\")\n\n\u0410 \u044d\u0442\u0430 \u0448\u0430\u0439\u0442\u0430\u043d-\u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0437\u0430\u0445\u0435\u043d\u0434\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u041e\u043d\u0430 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432\u0430 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u0432\u043d\u0435\u0448\u043d\u0438\u043c \u043c\u0438\u0440\u043e\u043c. \u041f\u043e\u0436\u0430\u043b\u0435\u0439 \u0435\u0451.\n\n\u0417\u0430\u043f\u0440\u043e\u0441\u044b \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 8099 \u043f\u043e\u0440\u0442\u0443, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 `/qiwi_notify` - \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f.\n\n```python\nfrom pyqiwip2p.notify import QiwiNotify\nfrom pyqiwip2p.p2p_types import Bill\n\nQIWI_PRIV_KEY = \"abCdef...xYz\"\n\nqiwi_notify = QiwiNotify(QIWI_PRIV_KEY)\n\n#\n# \u0425\u044d\u043d\u0434\u043b\u0435\u0440 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e,\n# \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0441\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0447\u0451\u0442\u0430 - Bill\n#\n\n# \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0445\u044d\u043d\u0434\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c billID \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0447\u0435\u0442\u043e\u0432\n@qiwi_notify.handler(lambda bill: True)\ndef print_bill(bill: Bill):\n\tprint(bill.bill_id)\n\n\n# \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0445\u044d\u043d\u0434\u043b\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0447\u0430\u0442\u0430\u0442\u044c \u0441\u0443\u043c\u043c\u0443 \u043e\u043f\u043b\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0441\u0447\u0435\u0442\u043e\u0432\n@qiwi_notify.handler(lambda bill: bill.status == \"PAID\")\ndef print_bill(bill: Bill):\n\tprint(bill.amount)\n\n\n# \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 12345'\u043e\u043c \u043f\u043e\u0440\u0442\u0443\nqiwi_notify.start(port=12345)\n```\n\n### \u0418 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c?\n\u0414\u0430 \u0435\u0441\u0442\u044c. \u041f\u0440\u0438\u0447\u0451\u043c \u0445\u0435\u043d\u0434\u043b\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0438 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435, \u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u044b\u0435.\n\n```python\nfrom pyqiwip2p import QiwiP2P, AioQiwiP2P\nfrom pyqiwip2p.p2p_types import Bill\nfrom pyqiwip2p.notify import AioQiwiNotify\nimport asyncio\n\nQIWI_PRIV_KEY = \"abCdef...xYz\"\n\nqiwi_notify = AioQiwiNotify(QIWI_PRIV_KEY)\np2p = AioQiwiP2P(auth_key=QIWI_PRIV_KEY)\n\n\n@qiwi_notify.handler(lambda bill: bill.status == \"EXPIRED\")\nasync def on_expired(bill: Bill):\n\tnew_bill = await p2p.bill(amount=bill.amount, comment=bill.comment)\n\tprint(new_bill.pay_url)\n\n\n@qiwi_notify.handler(lambda bill: True)\ndef on_all(bill: Bill):\n\tprint(bill.status)\n\n\nasync def main():\n\tp = asyncio.get_event_loop()\n\tserver = p.create_task(qiwi_notify.a_start(port=12345))\n\tawait server\n\n\nloop = asyncio.get_event_loop()\nloop.run_until_complete(main())\n```\n\n### \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e Nginx\n\u0414\u043b\u044f \u043f\u043e\u0440\u0442\u0430 12345 (\u043a\u0430\u043a \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0432\u044b\u0448\u0435) \u0431\u0443\u0434\u0435\u0442:\n```\nserver {\n    listen 443;\n    server_name qiwinotify.domain.com;\n    ssl_certificate      cert.crt;\n    ssl_certificate_key  pkey.key;\n    location /superSecretQiwiURI {\n        proxy_pass http://0.0.0.0:12345/qiwi_notify;\n    }\n}\n```\n\u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0435\u0439 API \u043d\u0430 https://qiwi.com/p2p-admin/transfers/api\n\u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u044c `https://qiwinotify.domain.com/superSecretQiwiURI` \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 URL \u0434\u043b\u044f \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u0439\n\n**P.S. \u0437\u0430 \u043d\u0435\u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043e\u0442 Qiwi \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u043d\u0435\u0441\u0443, \u043a\u0430\u043a \u0438 \u0437\u0430 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0449\u0438\u0435, \u043a\u0441\u0442\u0430\u0442\u0438, \u0442\u043e\u0436\u0435.\n\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0442 Qiwi \u043d\u0435 \u0431\u044b\u043b\u043e, \u0442\u043e \u043f\u0438\u0448\u0438\u0442\u0435 \u0438\u043c \u0432 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 [@qiwi_api_help_bot](https://t.me/qiwi_api_help_bot)**\n",
    "bugtrack_url": null,
    "license": "Mozilla Public License 2.0",
    "summary": "pyQiwiP2P",
    "version": "2.0.7",
    "project_urls": {
        "Homepage": "https://github.com/WhiteApfel/pyQiwiP2P",
        "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0447\u0442\u0438\u0432\u043e": "https://pyqiwip2p.readthedocs.io/ru/latest/",
        "\u0414\u043e\u043d\u0430\u0442\u0438\u043a": "https://pfel.cc/donate",
        "\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u0447\u043a\u0438": "https://github.com/WhiteApfel/pyQiwiP2P",
        "\u0422\u0435\u043b\u0435\u0436\u043a\u0430 \u0434\u043b\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432": "https://t.me/apfel"
    },
    "split_keywords": [
        "qiwip2p",
        "api",
        "qiwi",
        "p2p",
        "payments",
        "bill",
        "tools",
        "sdk",
        "wrapper"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2c86e8f65479a11a1e20664780c4ad340d811f6f82cbaa722b7bd415a600240a",
                "md5": "6f201eec9678d5a95bab7fd87cae2b47",
                "sha256": "99ffbaee2dc18fbffd2aacc6f2409bcd2438ff0dae9fb7b3ae747346d5634eda"
            },
            "downloads": -1,
            "filename": "pyQiwiP2P-2.0.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6f201eec9678d5a95bab7fd87cae2b47",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 28654,
            "upload_time": "2023-06-11T13:42:37",
            "upload_time_iso_8601": "2023-06-11T13:42:37.384527Z",
            "url": "https://files.pythonhosted.org/packages/2c/86/e8f65479a11a1e20664780c4ad340d811f6f82cbaa722b7bd415a600240a/pyQiwiP2P-2.0.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "b6ef17c717b3d1ac7e8ff77a1c0e3e1135df0d2646d62f3fabf6acf0e9e5e810",
                "md5": "310af9863a831939fb572c814b3de8a4",
                "sha256": "4932f5544a55beff0d0ed306c6b5b095dcbb5a19b35cdc8f9b13ad5caef5d72c"
            },
            "downloads": -1,
            "filename": "pyQiwiP2P-2.0.7.tar.gz",
            "has_sig": false,
            "md5_digest": "310af9863a831939fb572c814b3de8a4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 22101,
            "upload_time": "2023-06-11T13:42:39",
            "upload_time_iso_8601": "2023-06-11T13:42:39.399455Z",
            "url": "https://files.pythonhosted.org/packages/b6/ef/17c717b3d1ac7e8ff77a1c0e3e1135df0d2646d62f3fabf6acf0e9e5e810/pyQiwiP2P-2.0.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-06-11 13:42:39",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "WhiteApfel",
    "github_project": "pyQiwiP2P",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "pyqiwip2p"
}
        
Elapsed time: 0.08047s