Giter Site home page Giter Site logo

whiteapfel / pyqiwip2p Goto Github PK

View Code? Open in Web Editor NEW
55.0 4.0 12.0 606 KB

Simple wrapper for comfortable work with the API of payment system for individuals QiwiP2P

License: Mozilla Public License 2.0

Python 99.62% Dockerfile 0.38%
qiwi qiwip2p payments api api-wrapper asyncio

pyqiwip2p's Introduction

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

  • Появится лимит на вывод на карты и счета других банков – 1000 рублей в месяц
  • Не получится вывести деньги из кошелька через СБП
  • Не получится снимать наличные с QIWI Карт, даже в офисах QIWI и партнёров
  • Не получится сделать перевод из QIWI Кошелька через Contact
  • Не получится погасить кредит любого банка, кроме займов МФО

Со своей стороны могу предложить помощь в выводе денег на счёт в другой банк с комиссией 1.69% в течение 30 минут. Номер к счёту в банке должен быть привязан тот же, что и в Qiwi. На анонимные кошельки не распространяется.

pyQiwiP2P

CodeFactor

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

Есть более качественный инструмент, полностью покрывающий функции pyQiwiP2P: glQiwiApi

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

О библиотеке

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

Есть типа документация, но в ней есть и косячки, поэтому, если найдёте таковой, обязательно сообщите мне. Буду искренне рад. Правда. Спасибо.

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

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

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

⛔️ Способ из этого уведомления (временно) не работает [2023.07.22]

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

Инструкция:

  1. Переходим на https://qiwi.com/p2p-admin
  2. Авторизуемся в свой Qiwi аккаунт
  3. Открываем консоль браузера. Как?
  4. Вставляем код из первого блока и нажимаем enter
  5. Вставляем код из второго блока и нажимаем enter
  6. Если прошло успешно:
    • появится строка "Private Key: "
    • копируем ключ, и используем по назначению
  7. Если что-то пошло не так:
    • смириться, что накосячили
    • меня не тревожить
    • мне в личку не писать
    • кусаюсь и кидаю в чс
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));
}
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
  • Образ контейнера: 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, который обладает тремя инструментами: для выставления, проверки и закрытия платежа (счёта).

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

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")

А асинхронно могёте?

Могём. Причём примерно так же.

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

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

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

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)

И асинхронный сервер, наверное, у вас есть?

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

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

pyqiwip2p's People

Contributors

alteralt avatar fossabot avatar json1c avatar lionead avatar pyup-bot avatar sumer9999dev avatar whiteapfel avatar zen220 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pyqiwip2p's Issues

Initial Update

The bot created this issue to inform you that pyup.io has been set up on this repo.
Once you have closed it, the bot will open pull requests for updates as soon as they are available.

Заменить close на aclose; пофиксить закрытие клиента (добавив loop аргументом при инициализации)

  1. В модуле AioQiwip2p в функции __aexit__ вместо self.client.aclose() стоит self.client.close(), как будто клиент синхронный. Приводит к ошибке 'AsyncClient' object has no attribute 'close'. После замены я заметил другую ошибку:
  2. если у меня есть модуль, в котором происходит инициализация клиента p2p = AioQiwiP2P(auth_key=qiwi_key) и несколько async функций, внутри которых with, например:
async def bill(bill_id, amount, lifetime= bill_lifetime):
    async with p2p:
        new_bill = await p2p.bill(bill_id= bill_id, amount= amount, lifetime= lifetime, comment= bill_id)
        return new_bill.pay_url, new_bill.bill_id

async def close_bill(bill_id):
    async with p2p:
        return await p2p.reject(bill_id= bill_id)

То при обращении к первой соответсвенно срабатывает with и триггерится aexit после окончания код блока, и это вроде логично. Но тогда при обращении ко второй функции из другого модуля этот клиент уже закрывается: RuntimeError: Cannot send a request, as the client has been closed. Если написать аналогичный код на httpx или другой асинк либе, то инициализированный клиент, очевидно, не умрет. Фиксится добавлением аргумента loop при инициализации, чтобы узнать в каком мы цикле и не убивать сущность. Да и в целом создавать клиент каждый раз при новом обращении против мануалов httpx из-за неэффективности

возникает ошибка UnicodeEncodeError

когда на дедике запускаю бота то при создании счета возникает ошибка
UnicodeEncodeError: 'charmap' codec can't encode characters in position 83-90: character maps to <undefined>

полный трейсбек

ERROR:asyncio:Task exception was never retrieved
future: <Task finished name='Task-27' coro=<Dispatcher._process_polling_updates() done, defined at C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\dispatcher.py:407> exception=UnicodeEncodeError('charmap', '{"serviceName":"payin-invoicing-api","errorCode":"validation.error","description":"Неверные параметры, измените запрос согласно документации API; Cause: unknown","userMessage":"Неверные параметры, измените запрос согласно документации API; Cause: unknown","dateTime":"2022-07-18T23:37:44.061+03:00","traceId":"1ef2ed275a8597e1","cause":{"expirationDateTime":["должно содержать дату, которая еще не наступила"]}}\r\n', 83, 91, 'character maps to <undefined>')>
Traceback (most recent call last):
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\dispatcher.py", line 415, in _process_polling_updates
    for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\dispatcher.py", line 235, in process_updates
    return await asyncio.gather(*tasks)
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\handler.py", line 116, in notify
    response = await handler_obj.handler(*args, **partial_data)
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\dispatcher.py", line 283, in process_update
    return await self.callback_query_handlers.notify(update.callback_query)
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\aiogram\dispatcher\handler.py", line 116, in notify
    response = await handler_obj.handler(*args, **partial_data)
  File "C:\Users\admin\Desktop\bot\main.py", line 252, in gen_payment
    bill = p2p.bill(amount=amount, comment='Пополнение баланса')
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\pyqiwip2p\Qiwip2p.py", line 225, in bill
    qiwi_response = Bill(qiwi_raw_response, self.alt)
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\pyqiwip2p\p2p_types\responses.py", line 73, in __init__
    Reporter(response).save(fn)
  File "C:\Users\admin\AppData\Roaming\Python\Python39\site-packages\response_report\reporter.py", line 79, in save
    rf.writelines(self.lines)
  File "C:\Program Files\Python39\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 83-90: character maps to <undefined>

сделал все согласно документации, ничего не менял кроме комментария

Ошибка ImportError: cannot import name 'QiwiDatetime' from partially initialized module 'pyqiwip2p.p2p_types'

ImportError: cannot import name 'QiwiDatetime' from partially initialized module 'pyqiwip2p.p2p_types' (most likely due to a circular import) (C:\Users\Vladimir\AppData\Local\Programs\Python\Python38\lib\site-packages\pyqiwip2p\p2p_types_init_.py)

Решил путем изменение файла p2p_types_init_.py
на это.
from pyqiwip2p.p2p_types.qiwi_datetime import *
from pyqiwip2p.p2p_types.custom_fields import *
from pyqiwip2p.p2p_types.customer import *
from pyqiwip2p.p2p_types.errors import *
from pyqiwip2p.p2p_types.responses import *

Отключить предупреждения в консоле

При вызове асинхронных функций выдаёт подобное в консоль:

C:\Python37\lib\site-packages\httpx\_client.py:1979: UserWarning: Unclosed <httpx.AsyncClient object at 0x000001D871BE06C8>. See https://www.python-httpx.org/async/#opening-and-closing-clients for details.
  f"Unclosed {self!r}. "

Выдает ошибку, хотя сделал все как в документации

from pyqiwip2p import QiwiP2P
from pyqiwip2p.types import QiwiCustomer, QiwiDatetime

QIWI_PRIV_KEY = "eyJ2(специально убрал)ifX0"


p2p = QiwiP2P(auth_key = QIWI_PRIV_KEY)

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

Вот мой элементарный код для выставления счета, ничего более... Выдает вот такую ошибку:

Traceback (most recent call last):
  File "G:\codes\qiwi.py", line 10, in <module>
    new_bill = p2p.bill(bill_id=212332030, amount=228, lifetime=45)
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\site-packages\pyqiwip2p\Qiwip2p.py", line 77, in bill
    qiwi_response = Bill(requests.put(f"https://api.qiwi.com/partner/bill/v1/bills/{bill_id}",
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\site-packages\pyqiwip2p\types\Responses.py", line 47, in init
    self.r_json = response.json() if type(response) is Response else response
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\site-packages\requests\models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\json\__init__.py", line 346, in loads
    return _default_decoder.decode(s)
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\Odekulles\AppData\Local\Programs\Python\Python39\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

QiwiDatetime Parser Error

File "bot.py", line 236, in callback_inline
bill = wallet.check(bill_id=bill_id)
File "/usr/local/lib/python3.8/dist-packages/pyqiwip2p/Qiwip2p.py", line 118, in check
qiwi_response = Bill(qiwi_raw_response, self)
File "/usr/local/lib/python3.8/dist-packages/pyqiwip2p/p2p_types/Responses.py", line 67, in init
raise QiwiError(self.r_json)
File "/usr/local/lib/python3.8/dist-packages/pyqiwip2p/p2p_types/Errors.py", line 34, in init
self.datetime = QiwiDatetime(response_json["dateTime"])
File "/usr/local/lib/python3.8/dist-packages/pyqiwip2p/p2p_types/QiwiDatetime.py", line 40, in init
raise TypeError("The string does not match the format 'ГГГГ-ММ-ДДTчч:мм:сс+-чч:мм'")

В readme очепятка

image
ответсвенность
спасибо за либу, будут проблемы с юзом - отпишу)

bill.alt_url работает некорректно!!!

Написал код, кошелек банили. Прочитал, написано поставить вместо pay_url, alt_url, при первом случае, выдается правильная ссылка на оплату, по при alt_url выдается ссылка, которая не работает, и имеет какой то странный вид ссылки. Помогите пожалуйста!

KeyError: 'email'

Код:
bill = await p2p.check(bill_id=bill_id)

Traceback:

  File "/home/the_best_bot_in_the_world_yes/bot/handlers/payments.py", line 156, in check_invoice
    bill = await p2p.check(bill_id=bill_id)
  File "/usr/local/lib/python3.10/dist-packages/pyqiwip2p/AioQiwip2p.py", line 259, in check
    qiwi_response = Bill(qiwi_raw_response, self.alt)
  File "/usr/local/lib/python3.10/dist-packages/pyqiwip2p/p2p_types/responses.py", line 87, in __init__
    QiwiCustomer(json_data=self.r_json["customer"])
  File "/usr/local/lib/python3.10/dist-packages/pyqiwip2p/p2p_types/customer.py", line 50, in __init__
    self.email = json_data["email"]
KeyError: 'email'

В чём заключается суть проблемы и как её воспроизвести:

Создаём счёт через метод AioQiwiP2P.bill, оплачиваем, и вызываем метод AioQiwiP2P.check, естественно с bill_id, которое вернул нам первый метод. После чего ловим такую ошибку. При неоплаченном счёте никаких ошибок нет, но если он оплачен, то собственно видим то, что я описал. Похоже, киви что-то изменил в своём API, нужно обновить библиотеку под это.

Не удаётся использовать bill.alt_url

Прочитал в документации, что киви банят, если не стоит реферер. было написано что можно заюзать bill.alt_url вместо bill.pay_url. Но ваш хост не работает( попробовал свой захостить, но так до конца и не понял, как настроить редирект с 80 и 443 порта домена на сервер с редиректом

Нарушение нотации типов данных.

@router.route("/{bill_uid}", "GET")
в качестве методов указывается строка, хотя в используемой библиотеке starlette https://github.com/encode/starlette/blob/5ee04ef9b1bc11dc14d299e6c855c9a3f7d5ff16/starlette/routing.py#L650 сказано что ожидается список из строк. Предположительно приводит к ошибке Method Not Allowed при работе.

Не тот объект

async def ref_redirect_vk(bill_uid: str):

в bill_uid принимаемом в функцию хранится объект запроса, при этом нотация типов вводит в заблуждение говоря что там строка bill_uid, хотя саму строку можно взять в path_params у объекта запроса.

В файле __init__ на pypi нет AioQiwiP2P

Добрый день, я скачал установил из pypi библиотеку и там не было в init файле from pyqiwip2p.AioQiwip2p import AioQiwiP2P . В гитхабе всё нормально

Создаётся ошибка при проверке статуса.

Полный код ошибки:

Traceback (most recent call last):
  File "C:\Users\SuperUser\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
    self.run()
  File "C:\Users\SuperUser\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "C:/Users/SuperUser/PycharmProjects/bot/main.py", line 117, in bill
    if p2p.check(bill_id=new_bill.bill_id).status == "PAID":
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\Qiwip2p.py", line 114, in check
    qiwi_response = Bill(qiwi_raw_response, self)
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\p2p_types\Responses.py", line 67, in __init__
    raise QiwiError(self.r_json)
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\p2p_types\Errors.py", line 34, in __init__
    self.datetime = QiwiDatetime(response_json["dateTime"])
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\p2p_types\QiwiDatetime.py", line 38, in __init__
    self.set_from_qiwi(moment)
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\p2p_types\QiwiDatetime.py", line 78, in set_from_qiwi
    self.datetime = self.qiwi_datetime(dt)
  File "C:\Users\SuperUser\PycharmProjects\bot\venv\lib\site-packages\pyqiwip2p\p2p_types\QiwiDatetime.py", line 70, in qiwi_datetime
    return datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S.%f%z")
  File "C:\Users\SuperUser\AppData\Local\Programs\Python\Python36-32\lib\_strptime.py", line 565, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "C:\Users\SuperUser\AppData\Local\Programs\Python\Python36-32\lib\_strptime.py", line 362, in _strptime
    (data_string, format))
ValueError: time data '2022-08-12T12:44:52.586+03:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'

Строка, в которой создается ошибка:
if p2p.check(bill_id=new_bill.bill_id).status == "PAID":

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.