Enables balance payments via invoice

Adds functionality for users to pay their Castle balance by generating and paying a Lightning invoice.
This includes:
- Adding API endpoints for invoice generation and payment recording.
- Updating the frontend to allow users to initiate the invoice payment process.
- Passing the wallet's `inkey` to the frontend for payment status checks.
This commit is contained in:
padreug 2025-10-22 16:48:13 +02:00
parent ef3e2d9e0d
commit 854164614f
3 changed files with 35 additions and 9 deletions

View file

@ -34,8 +34,10 @@ from .models import (
CreateEntryLine,
CreateJournalEntry,
ExpenseEntry,
GeneratePaymentInvoice,
JournalEntry,
ReceivableEntry,
RecordPayment,
RevenueEntry,
UserBalance,
UserWalletSettings,
@ -446,13 +448,14 @@ async def api_get_all_balances(
@castle_api_router.post("/api/v1/generate-payment-invoice")
async def api_generate_payment_invoice(
amount: int,
data: GeneratePaymentInvoice,
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> dict:
"""
Generate an invoice on the Castle wallet for user to pay their balance.
User can then pay this invoice to settle their debt.
"""
from lnbits.core.crud.wallets import get_wallet
from lnbits.core.models import CreateInvoice
from lnbits.core.services import create_payment_request
@ -462,7 +465,7 @@ async def api_generate_payment_invoice(
# Create invoice on castle wallet
invoice_data = CreateInvoice(
out=False,
amount=amount,
amount=data.amount,
memo=f"Payment from user {wallet.wallet.user[:8]} to Castle",
unit="sat",
extra={"user_id": wallet.wallet.user, "type": "castle_payment"},
@ -470,17 +473,25 @@ async def api_generate_payment_invoice(
payment = await create_payment_request(castle_wallet_id, invoice_data)
# Get castle wallet to return its inkey for payment checking
castle_wallet = await get_wallet(castle_wallet_id)
if not castle_wallet:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Castle wallet not found"
)
return {
"payment_hash": payment.payment_hash,
"payment_request": payment.bolt11,
"amount": amount,
"amount": data.amount,
"memo": invoice_data.memo,
"check_wallet_key": castle_wallet.inkey, # Key to check payment status
}
@castle_api_router.post("/api/v1/record-payment")
async def api_record_payment(
payment_hash: str,
data: RecordPayment,
wallet: WalletTypeInfo = Depends(require_invoice_key),
) -> dict:
"""
@ -490,7 +501,7 @@ async def api_record_payment(
from lnbits.core.crud.payments import get_standalone_payment
# Get the payment details
payment = await get_standalone_payment(payment_hash)
payment = await get_standalone_payment(data.payment_hash)
if not payment:
raise HTTPException(
status_code=HTTPStatus.NOT_FOUND, detail="Payment not found"
@ -518,7 +529,7 @@ async def api_record_payment(
# This reduces what the user owes
entry_data = CreateJournalEntry(
description=f"Lightning payment from user {wallet.wallet.user[:8]}",
reference=payment_hash,
reference=data.payment_hash,
lines=[
CreateEntryLine(
account_id=lightning_account.id,