# πŸ’³ Payment Service > **Centralized Lightning payment processing** with wallet management, QR code generation, and real-time balance tracking integrated with LNbits. ## Table of Contents - [[#Overview]] - [[#Architecture]] - [[#Payment Processing]] - [[#Wallet Management]] - [[#Balance Management]] - [[#QR Code Generation]] - [[#Error Handling]] - [[#Integration with WebSocket]] - [[#API Reference]] ## Overview The PaymentService is a core infrastructure service that centralizes all Lightning Network payment operations in the Ario application. It provides a clean abstraction layer over LNbits operations and manages wallet state across all modules. ### **Key Responsibilities** - **Payment Processing** - Handle Lightning invoices, external wallets, and payment validation - **Wallet Management** - Multi-wallet support with consistent wallet selection - **Balance Tracking** - Real-time balance updates from WebSocket integration - **QR Code Generation** - Payment request and custom data QR codes - **Error Handling** - Consistent payment error handling and user feedback ### **Service Integration** ``` β”Œβ”€ UI Components ─┐ β”Œβ”€ PaymentService ─┐ β”Œβ”€ External Services ─┐ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β€’ Send Dialog │───▢│ β€’ Payment Logic │───▢│ β€’ LNbits API β”‚ β”‚ β€’ Balance Displayβ”‚ β”‚ β€’ Wallet Mgmt β”‚ β”‚ β€’ External Wallets β”‚ β”‚ β€’ QR Generator β”‚ β”‚ β€’ Balance State β”‚ β”‚ β€’ QR Library β”‚ β”‚ β”‚ β”‚ β€’ Error Handling β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β–Ό β”Œβ”€ AuthService ─────┐ β”‚ β”‚ β”‚ β€’ User Wallets β”‚ β”‚ β€’ Authentication β”‚ β”‚ β€’ Wallet Keys β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## Architecture ### **Service Structure** ```typescript export class PaymentService extends BaseService { // Service metadata protected readonly metadata = { name: 'PaymentService', version: '1.0.0', dependencies: ['AuthService'] } // Reactive state private _isProcessingPayment = ref(false) private _paymentError = ref(null) // Public computed state public readonly isProcessingPayment = computed(() => this._isProcessingPayment.value) public readonly paymentError = computed(() => this._paymentError.value) } ``` ### **Dependencies** - **AuthService** - User authentication and wallet access - **BaseService** - Service lifecycle and error handling - **Vue Reactivity** - Reactive state management ### **External Integrations** - **LNbits API** - Lightning wallet backend - **QRCode Library** - QR code generation - **External Wallets** - Lightning wallet applications - **Browser APIs** - Clipboard, window.open for external wallets ## Payment Processing ### **Payment Types Supported** #### **Lightning Invoices (BOLT11)** Process Lightning payment requests directly: ```typescript await paymentService.payWithWallet( 'lnbc1000n1p3xh4v...', // Lightning invoice undefined, // Amount already in invoice { successMessage: 'Payment sent successfully!', showToast: true } ) ``` #### **External Wallet Fallback** Automatically fall back to external wallets when user wallet lacks balance: ```typescript // Automatic payment handling with fallback const result = await paymentService.handlePayment( paymentRequest, requiredAmount, { successMessage: 'Payment completed!' } ) // Returns PaymentResult for wallet payments, null for external wallet if (result) { console.log('Paid with user wallet:', result.payment_hash) } else { console.log('Opened external wallet') } ``` ### **Payment Flow** ``` 1. Payment Request Validation β”œβ”€β”€ Check payment request format β”œβ”€β”€ Extract amount if present └── Validate against available balance 2. Wallet Selection β”œβ”€β”€ Get preferred wallet β”œβ”€β”€ Check sufficient balance └── Retrieve wallet credentials 3. Payment Execution β”œβ”€β”€ Call LNbits payment API β”œβ”€β”€ Handle response/errors └── Update UI state 4. Completion Handling β”œβ”€β”€ Show success/error notifications β”œβ”€β”€ Reset payment state └── Emit completion events ``` ### **Payment Options** ```typescript interface PaymentOptions { successMessage?: string // Custom success message errorMessage?: string // Custom error message showToast?: boolean // Show toast notifications (default: true) } ``` ## Wallet Management ### **Multi-Wallet Support** PaymentService provides consistent wallet selection across all modules: ```typescript // Preferred wallet selection (always first wallet) const wallet = paymentService.getPreferredWallet() // Returns: wallets[0] or null if no wallets // Wallet with sufficient balance const wallet = paymentService.getWalletWithBalance(1000) // 1000 sats // Returns: first wallet with >= 1000 sats or null // Wallet credentials access const adminKey = paymentService.getPreferredWalletAdminKey() const invoiceKey = paymentService.getPreferredWalletInvoiceKey() ``` ### **Wallet Selection Logic** The service follows a consistent wallet selection strategy: 1. **Preferred Wallet**: Always use `wallets[0]` for consistency 2. **Balance Checking**: Check if preferred wallet has sufficient balance 3. **Fallback Strategy**: No automatic fallback - use external wallet instead 4. **Credential Access**: Provide admin/invoice keys for API operations ### **Balance Access** ```typescript // Total balance across all wallets (in millisats) const totalBalance = paymentService.totalBalance // Check if any wallet has balance const hasBalance = paymentService.hasWalletWithBalance // Balance formatted for display const balanceSats = Math.round(totalBalance / 1000) ``` ## Balance Management ### **Real-Time Balance Updates** PaymentService receives balance updates from WalletWebSocketService: ```typescript // Called by WebSocket service when balance changes paymentService.updateWalletBalance(balanceMsat, walletId) ``` ### **Balance Update Logic** ```typescript updateWalletBalance(balanceMsat: number, walletId?: string): void { // Determine target wallet let walletToUpdate if (walletId) { walletToUpdate = this.authService.user.value.wallets.find(w => w.id === walletId) } else { walletToUpdate = this.getPreferredWallet() // Default to first wallet } if (walletToUpdate) { const oldBalance = walletToUpdate.balance_msat walletToUpdate.balance_msat = balanceMsat // Trigger Vue reactivity this.authService.user.value = { ...this.authService.user.value } console.log(`Wallet ${walletToUpdate.id} balance: ${oldBalance} β†’ ${balanceMsat} msat`) } } ``` ### **Balance State Management** - **Storage**: Balances stored in AuthService user object - **Reactivity**: Vue reactivity ensures UI updates automatically - **Consistency**: Single source of truth for wallet balances - **Persistence**: Balances persist across app sessions via AuthService ## QR Code Generation ### **Payment Request QR Codes** Generate QR codes for Lightning payment requests: ```typescript // Standard payment QR code const qrDataUrl = await paymentService.generateQRCode( 'lnbc1000n1p3xh4v...', // Payment request { width: 256, // QR code size margin: 2, // Border margin darkColor: '#000000', // QR code color lightColor: '#FFFFFF' // Background color } ) // Use in components Payment QR Code ``` ### **Custom Data QR Codes** Generate QR codes for tickets, links, or other data: ```typescript // Ticket QR code const ticketQR = await paymentService.generateCustomQRCode( JSON.stringify({ eventId: 'event123', ticketId: 'ticket456', timestamp: Date.now() }), { width: 128 } // Smaller size for tickets ) ``` ### **QR Code Options** ```typescript interface QRCodeOptions { width?: number // QR code width in pixels (default: 256) margin?: number // Border margin (default: 2) darkColor?: string // QR code color (default: #000000) lightColor?: string // Background color (default: #FFFFFF) } ``` ## Error Handling ### **Payment Error Types** ```typescript // Common payment errors enum PaymentErrorType { INSUFFICIENT_BALANCE = 'Insufficient wallet balance', INVALID_INVOICE = 'Invalid payment request', NETWORK_ERROR = 'Network connection failed', TIMEOUT = 'Payment timeout', ROUTING_FAILED = 'Lightning routing failed', WALLET_LOCKED = 'Wallet is locked', UNKNOWN = 'Unknown payment error' } ``` ### **Error Handling Pattern** ```typescript async payWithWallet(paymentRequest: string): Promise { try { this._isProcessingPayment.value = true this._paymentError.value = null // Payment processing logic const result = await this.processPayment(paymentRequest) // Success notification toast.success('Payment successful!') return result } catch (error) { // Error handling const errorMessage = this.parsePaymentError(error) this._paymentError.value = errorMessage // User notification toast.error('Payment failed', { description: errorMessage }) throw error } finally { this._isProcessingPayment.value = false } } ``` ### **Error Recovery** ```typescript // Clear error state paymentService.clearPaymentError() // Force reset payment state (for debugging) paymentService.forceResetPaymentState() // Retry payment after error await paymentService.payWithWallet(paymentRequest, amount, { errorMessage: 'Retry failed - please try again' }) ``` ## Integration with WebSocket ### **WebSocket Collaboration** PaymentService works closely with WalletWebSocketService: ``` β”Œβ”€ WalletWebSocketService ─┐ β”Œβ”€ PaymentService ─┐ β”‚ β”‚ β”‚ β”‚ β”‚ 1. Receive WS Message β”‚ β”‚ β”‚ β”‚ 2. Parse Balance Update │───▢│ 4. Update Balanceβ”‚ β”‚ 3. Convert Satsβ†’MSats β”‚ β”‚ 5. Trigger UI β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### **Balance Update Flow** 1. **WebSocket Message**: WalletWebSocketService receives balance update 2. **Unit Conversion**: Convert sats to millisats for internal consistency 3. **Balance Update**: Call `PaymentService.updateWalletBalance()` 4. **State Update**: PaymentService updates wallet balance in AuthService 5. **UI Reactivity**: Vue reactivity updates all UI components ### **Payment Notifications** ```typescript // WebSocket triggers payment notification eventBus.on('payment:received', (data) => { // PaymentService can listen and handle accordingly paymentService.handlePaymentNotification(data) }) ``` ## API Reference ### **Public Methods** #### **Payment Operations** ```typescript // Process Lightning payment with user wallet payWithWallet( paymentRequest: string, requiredAmountSats?: number, options?: PaymentOptions ): Promise // Handle payment with automatic fallback handlePayment( paymentRequest: string, requiredAmountSats?: number, options?: PaymentOptions ): Promise // Open external Lightning wallet openExternalWallet(paymentRequest: string): void ``` #### **Wallet Management** ```typescript // Get preferred wallet (first wallet) getPreferredWallet(): Wallet | null // Get wallet with sufficient balance getWalletWithBalance(requiredAmountSats?: number): Wallet | null // Get wallet credentials getPreferredWalletAdminKey(): string | null getPreferredWalletInvoiceKey(): string | null // Update wallet balance (called by WebSocket) updateWalletBalance(balanceMsat: number, walletId?: string): void ``` #### **QR Code Generation** ```typescript // Generate payment QR code generateQRCode( paymentRequest: string, options?: QRCodeOptions ): Promise // Generate custom data QR code generateCustomQRCode( data: string, options?: QRCodeOptions ): Promise ``` #### **State Management** ```typescript // Clear payment error clearPaymentError(): void // Reset payment state resetPaymentState(): void // Force reset (for debugging) forceResetPaymentState(): void ``` ### **Reactive State** ```typescript // Access reactive state const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE) // Payment processing state const isProcessing = paymentService.isProcessingPayment const error = paymentService.paymentError // Wallet information const totalBalance = paymentService.totalBalance const hasBalance = paymentService.hasWalletWithBalance ``` ### **Integration Example** ```vue ``` ## See Also ### Related Documentation - **[[../02-modules/wallet-module/index|πŸ’° Wallet Module]]** - Wallet UI and WebSocket integration - **[[../02-modules/wallet-module/websocket-integration|⚑ WebSocket Integration]]** - Real-time balance updates - **[[authentication|πŸ” Authentication Service]]** - User wallets and credentials ### API References - **[[../05-api-reference/lnbits-api|⚑ LNbits API]]** - Backend Lightning wallet API - **[[../05-api-reference/lightning-payments|πŸ’° Lightning Payments]]** - Payment protocol details ### Development Guides - **[[../04-development/testing|πŸ§ͺ Testing Guide]]** - Testing payment functionality - **[[../04-development/debugging|πŸ› Debugging]]** - Payment troubleshooting --- **Tags:** #payment #lightning #service #wallet #qr-code #lnbits **Last Updated:** 2025-09-18 **Author:** Development Team