refactor: move payment code from tasks.py to service/payments.py (#3800)
This commit is contained in:
@@ -13,13 +13,13 @@ from lnbits.core.crud.payments import get_daily_stats
|
|||||||
from lnbits.core.db import db
|
from lnbits.core.db import db
|
||||||
from lnbits.core.models import PaymentDailyStats, PaymentFilters
|
from lnbits.core.models import PaymentDailyStats, PaymentFilters
|
||||||
from lnbits.core.models.payments import CreateInvoice
|
from lnbits.core.models.payments import CreateInvoice
|
||||||
|
from lnbits.core.services.fiat_providers import handle_fiat_payment_confirmation
|
||||||
from lnbits.db import Connection, Filters
|
from lnbits.db import Connection, Filters
|
||||||
from lnbits.decorators import check_user_extension_access
|
from lnbits.decorators import check_user_extension_access
|
||||||
from lnbits.exceptions import InvoiceError, PaymentError, UnsupportedError
|
from lnbits.exceptions import InvoiceError, PaymentError, UnsupportedError
|
||||||
from lnbits.fiat import get_fiat_provider
|
from lnbits.fiat import get_fiat_provider
|
||||||
from lnbits.helpers import check_callback_url
|
from lnbits.helpers import check_callback_url
|
||||||
from lnbits.settings import settings
|
from lnbits.settings import settings
|
||||||
from lnbits.tasks import create_task, internal_invoice_queue_put
|
|
||||||
from lnbits.utils.crypto import fake_privkey, random_secret_and_hash, verify_preimage
|
from lnbits.utils.crypto import fake_privkey, random_secret_and_hash, verify_preimage
|
||||||
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis, satoshis_amount_as_fiat
|
from lnbits.utils.exchange_rates import fiat_amount_as_satoshis, satoshis_amount_as_fiat
|
||||||
from lnbits.wallets import fake_wallet, get_funding_source
|
from lnbits.wallets import fake_wallet, get_funding_source
|
||||||
@@ -509,6 +509,8 @@ async def update_wallet_balance(
|
|||||||
)
|
)
|
||||||
payment.status = PaymentState.SUCCESS
|
payment.status = PaymentState.SUCCESS
|
||||||
await update_payment(payment, conn=conn)
|
await update_payment(payment, conn=conn)
|
||||||
|
from lnbits.tasks import internal_invoice_queue_put
|
||||||
|
|
||||||
await internal_invoice_queue_put(payment.checking_id)
|
await internal_invoice_queue_put(payment.checking_id)
|
||||||
|
|
||||||
|
|
||||||
@@ -819,6 +821,8 @@ async def _pay_external_invoice(
|
|||||||
|
|
||||||
fee_reserve_msat = fee_reserve(amount_msat, internal=False)
|
fee_reserve_msat = fee_reserve(amount_msat, internal=False)
|
||||||
|
|
||||||
|
from lnbits.tasks import create_task
|
||||||
|
|
||||||
task = create_task(
|
task = create_task(
|
||||||
_fundingsource_pay_invoice(checking_id, payment.bolt11, fee_reserve_msat)
|
_fundingsource_pay_invoice(checking_id, payment.bolt11, fee_reserve_msat)
|
||||||
)
|
)
|
||||||
@@ -1068,3 +1072,30 @@ async def _send_payment_notification_in_background(
|
|||||||
if not wallet:
|
if not wallet:
|
||||||
raise PaymentError(f"Could not fetch wallet '{wallet_id}'.", status="failed")
|
raise PaymentError(f"Could not fetch wallet '{wallet_id}'.", status="failed")
|
||||||
send_payment_notification_in_background(wallet, payment)
|
send_payment_notification_in_background(wallet, payment)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_invoice_callback(checking_id: str) -> Payment | None:
|
||||||
|
"""
|
||||||
|
Takes a checking_id of an incoming payment, from either paid_invoices_stream()
|
||||||
|
or internal_invoice_queue. Checks its status, updates and returns it.
|
||||||
|
returns None if no payment was found or it not and incoming payment.
|
||||||
|
"""
|
||||||
|
payment = await get_standalone_payment(checking_id, incoming=True)
|
||||||
|
if not payment:
|
||||||
|
logger.warning(f"No payment found for '{checking_id}'.")
|
||||||
|
return None
|
||||||
|
if not payment.is_in:
|
||||||
|
logger.warning(f"Payment '{checking_id}' is not incoming, skipping.")
|
||||||
|
return None
|
||||||
|
|
||||||
|
status = await check_payment_status(
|
||||||
|
payment, skip_internal_payment_notifications=True
|
||||||
|
)
|
||||||
|
payment.fee = status.fee_msat or payment.fee
|
||||||
|
# only overwrite preimage if status.preimage provides it
|
||||||
|
payment.preimage = status.preimage or payment.preimage
|
||||||
|
payment.status = PaymentState.SUCCESS
|
||||||
|
await update_payment(payment)
|
||||||
|
if payment.fiat_provider:
|
||||||
|
await handle_fiat_payment_confirmation(payment)
|
||||||
|
return payment
|
||||||
|
|||||||
+11
-35
@@ -5,12 +5,8 @@ from collections.abc import Callable, Coroutine
|
|||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from lnbits.core.crud import (
|
from lnbits.core.models import Payment
|
||||||
get_standalone_payment,
|
from lnbits.core.services.payments import update_invoice_callback
|
||||||
update_payment,
|
|
||||||
)
|
|
||||||
from lnbits.core.models import Payment, PaymentState
|
|
||||||
from lnbits.core.services.fiat_providers import handle_fiat_payment_confirmation
|
|
||||||
from lnbits.settings import settings
|
from lnbits.settings import settings
|
||||||
from lnbits.wallets import get_funding_source
|
from lnbits.wallets import get_funding_source
|
||||||
|
|
||||||
@@ -116,7 +112,10 @@ async def internal_invoice_listener() -> None:
|
|||||||
while settings.lnbits_running:
|
while settings.lnbits_running:
|
||||||
checking_id = await internal_invoice_queue.get()
|
checking_id = await internal_invoice_queue.get()
|
||||||
logger.info(f"got an internal payment notification {checking_id}")
|
logger.info(f"got an internal payment notification {checking_id}")
|
||||||
await invoice_callback_dispatcher(checking_id, is_internal=True)
|
payment = await update_invoice_callback(checking_id)
|
||||||
|
if payment:
|
||||||
|
logger.success(f"internal invoice {checking_id} settled")
|
||||||
|
await invoice_callback_dispatcher(payment)
|
||||||
|
|
||||||
|
|
||||||
async def invoice_listener() -> None:
|
async def invoice_listener() -> None:
|
||||||
@@ -129,7 +128,10 @@ async def invoice_listener() -> None:
|
|||||||
funding_source = get_funding_source()
|
funding_source = get_funding_source()
|
||||||
async for checking_id in funding_source.paid_invoices_stream():
|
async for checking_id in funding_source.paid_invoices_stream():
|
||||||
logger.info(f"got a payment notification {checking_id}")
|
logger.info(f"got a payment notification {checking_id}")
|
||||||
await invoice_callback_dispatcher(checking_id)
|
payment = await update_invoice_callback(checking_id)
|
||||||
|
if payment:
|
||||||
|
logger.success(f"fundingsource invoice {checking_id} settled")
|
||||||
|
await invoice_callback_dispatcher(payment)
|
||||||
|
|
||||||
|
|
||||||
def wait_for_paid_invoices(
|
def wait_for_paid_invoices(
|
||||||
@@ -165,33 +167,7 @@ def run_interval(
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
async def invoice_callback_dispatcher(checking_id: str, is_internal: bool = False):
|
async def invoice_callback_dispatcher(payment: Payment):
|
||||||
"""
|
|
||||||
Takes an incoming payment, checks its status, and dispatches it to
|
|
||||||
invoice_listeners from core and extensions.
|
|
||||||
"""
|
|
||||||
payment = await get_standalone_payment(checking_id, incoming=True)
|
|
||||||
if not payment:
|
|
||||||
logger.warning(f"No payment found for '{checking_id}'.")
|
|
||||||
return
|
|
||||||
if not payment.is_in:
|
|
||||||
logger.warning(f"Payment '{checking_id}' is not incoming, skipping.")
|
|
||||||
return
|
|
||||||
|
|
||||||
from lnbits.core.services.payments import check_payment_status
|
|
||||||
|
|
||||||
status = await check_payment_status(
|
|
||||||
payment, skip_internal_payment_notifications=True
|
|
||||||
)
|
|
||||||
payment.fee = status.fee_msat or payment.fee
|
|
||||||
# only overwrite preimage if status.preimage provides it
|
|
||||||
payment.preimage = status.preimage or payment.preimage
|
|
||||||
payment.status = PaymentState.SUCCESS
|
|
||||||
await update_payment(payment)
|
|
||||||
if payment.fiat_provider:
|
|
||||||
await handle_fiat_payment_confirmation(payment)
|
|
||||||
internal = "internal" if is_internal else ""
|
|
||||||
logger.success(f"{internal} invoice {checking_id} settled")
|
|
||||||
for name, send_chan in invoice_listeners.items():
|
for name, send_chan in invoice_listeners.items():
|
||||||
logger.trace(f"invoice listeners: sending to `{name}`")
|
logger.trace(f"invoice listeners: sending to `{name}`")
|
||||||
await send_chan.put(payment)
|
await send_chan.put(payment)
|
||||||
|
|||||||
Reference in New Issue
Block a user