Lightning Python
Executable
Jan 31, 2026
Create Lightning Invoices with LNbits
Generate BOLT11 invoices for receiving Lightning payments via LNbits API
#lnbits
#invoice
#bolt11
#api
Overview
Create Lightning invoices to receive payments using the LNbits API. LNbits provides a simple REST API that works with any Lightning backend.
The Code
"""
Lightning Invoice Creator
Generate BOLT11 invoices via LNbits API
Requirements:
- requests (pip install requests)
- LNbits instance with Invoice/Read key
Environment variables:
- LNBITS_URL: Your LNbits instance URL
- LNBITS_INVOICE_KEY: Invoice/Read API key
"""
import os
import requests
from typing import Optional
from dataclasses import dataclass
# Configuration
LNBITS_URL = os.getenv("LNBITS_URL", "https://legend.lnbits.com")
LNBITS_INVOICE_KEY = os.getenv("LNBITS_INVOICE_KEY", "")
@dataclass
class Invoice:
"""Lightning invoice data."""
payment_hash: str
payment_request: str # BOLT11 string
amount_sats: int
memo: str
checking_id: str
def create_invoice(
amount_sats: int,
memo: str = "",
expiry: int = 3600,
webhook: Optional[str] = None
) -> Invoice:
"""
Create a Lightning invoice.
Args:
amount_sats: Amount in satoshis
memo: Invoice description
expiry: Expiry time in seconds (default 1 hour)
webhook: Optional webhook URL for payment notification
Returns:
Invoice object with BOLT11 string
Raises:
ValueError: If API key not configured
requests.RequestException: On API error
"""
if not LNBITS_INVOICE_KEY:
raise ValueError("LNBITS_INVOICE_KEY not set")
headers = {
"X-Api-Key": LNBITS_INVOICE_KEY,
"Content-Type": "application/json"
}
payload = {
"out": False, # False = incoming invoice
"amount": amount_sats,
"memo": memo,
"expiry": expiry
}
if webhook:
payload["webhook"] = webhook
response = requests.post(
f"{LNBITS_URL}/api/v1/payments",
headers=headers,
json=payload,
timeout=30
)
response.raise_for_status()
data = response.json()
return Invoice(
payment_hash=data["payment_hash"],
payment_request=data["payment_request"],
amount_sats=amount_sats,
memo=memo,
checking_id=data.get("checking_id", data["payment_hash"])
)
def check_invoice_status(payment_hash: str) -> dict:
"""
Check if an invoice has been paid.
Args:
payment_hash: The payment hash from invoice creation
Returns:
dict with paid status and details
"""
if not LNBITS_INVOICE_KEY:
raise ValueError("LNBITS_INVOICE_KEY not set")
headers = {"X-Api-Key": LNBITS_INVOICE_KEY}
response = requests.get(
f"{LNBITS_URL}/api/v1/payments/{payment_hash}",
headers=headers,
timeout=10
)
response.raise_for_status()
data = response.json()
return {
"paid": data.get("paid", False),
"pending": data.get("pending", True),
"amount_sats": abs(data.get("amount", 0)) // 1000, # msat to sat
"fee_msat": data.get("fee", 0),
"preimage": data.get("preimage"),
"time": data.get("time")
}
def wait_for_payment(payment_hash: str, timeout: int = 60) -> bool:
"""
Wait for an invoice to be paid.
Args:
payment_hash: The payment hash to monitor
timeout: Maximum seconds to wait
Returns:
True if paid, False if timeout
"""
import time
start = time.time()
while time.time() - start < timeout:
status = check_invoice_status(payment_hash)
if status["paid"]:
return True
time.sleep(2)
return False
def format_invoice_qr_data(bolt11: str) -> str:
"""
Format invoice for QR code generation.
Args:
bolt11: BOLT11 invoice string
Returns:
Uppercase BOLT11 (better for QR codes)
"""
return bolt11.upper()
# Example usage
if __name__ == "__main__":
# Set your API key
if not LNBITS_INVOICE_KEY:
print("Set LNBITS_INVOICE_KEY environment variable")
print("Example: export LNBITS_INVOICE_KEY='your-invoice-key'")
exit(1)
try:
# Create a 1000 sat invoice
invoice = create_invoice(
amount_sats=1000,
memo="Test payment from agent",
expiry=3600
)
print("=== Invoice Created ===")
print(f"Amount: {invoice.amount_sats} sats")
print(f"Memo: {invoice.memo}")
print(f"Payment hash: {invoice.payment_hash}")
print(f"\nBOLT11:")
print(invoice.payment_request)
print("\n=== QR Code Data ===")
print(format_invoice_qr_data(invoice.payment_request))
print("\n=== Waiting for payment (60s) ===")
if wait_for_payment(invoice.payment_hash, timeout=60):
print("Payment received!")
status = check_invoice_status(invoice.payment_hash)
print(f"Preimage: {status['preimage']}")
else:
print("Timeout - no payment received")
except requests.RequestException as e:
print(f"API error: {e}")
except ValueError as e:
print(f"Configuration error: {e}")
Usage
# Set environment variables
export LNBITS_URL="https://your-lnbits.com"
export LNBITS_INVOICE_KEY="your-invoice-read-key"
# Install and run
pip install requests
python create_invoice.py
Example Output
=== Invoice Created ===
Amount: 1000 sats
Memo: Test payment from agent
Payment hash: abc123def456...
BOLT11:
lnbc10u1pjq2ywdpp5...
=== QR Code Data ===
LNBC10U1PJQ2YWDPP5...
=== Waiting for payment (60s) ===
Payment received!
Preimage: 789xyz...
Agent Notes
Key types in LNbits:
- Invoice/Read key: Can create invoices and check balances (safe to expose)
- Admin key: Can also spend funds (keep secret!)
Best practices for agents:
- Always set a meaningful
memofor tracking - Use webhooks for async payment notifications
- Store
payment_hashto verify payments later - Set reasonable expiry (1 hour default, shorter for time-sensitive)
Zero-amount invoices: Omit amount to let the payer choose the amount. Useful for donations.