Adds background task for invoice processing

Implements a background task that listens for paid invoices
and automatically records them in the accounting system. This
ensures payments are captured even if the user closes their
browser before the client-side polling detects the payment.

Introduces a new `get_journal_entry_by_reference` function to
improve idempotency when recording payments.
This commit is contained in:
padreug 2025-11-02 01:40:40 +01:00
parent 4957826c49
commit cfa25cc61b
4 changed files with 142 additions and 2 deletions

View file

@ -591,7 +591,7 @@ async def api_generate_payment_invoice(
amount=data.amount,
memo=f"Payment from user {target_user_id[:8]} to Castle",
unit="sat",
extra={"user_id": target_user_id, "type": "castle_payment"},
extra={"tag": "castle", "user_id": target_user_id},
)
payment = await create_payment_request(castle_wallet_id, invoice_data)
@ -648,6 +648,18 @@ async def api_record_payment(
detail="Payment metadata missing user_id. Cannot determine which user to credit.",
)
# Check if payment already recorded (idempotency)
from .crud import get_journal_entry_by_reference
existing = await get_journal_entry_by_reference(data.payment_hash)
if existing:
# Payment already recorded, return existing entry
balance = await get_user_balance(target_user_id)
return {
"journal_entry_id": existing.id,
"new_balance": balance.balance,
"message": "Payment already recorded",
}
# Convert amount from millisatoshis to satoshis
amount_sats = payment.amount // 1000