# 💳 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<string | null>(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
<img :src="qrDataUrl" alt="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<PaymentResult> {
  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<PaymentResult>

// Handle payment with automatic fallback
handlePayment(
  paymentRequest: string,
  requiredAmountSats?: number,
  options?: PaymentOptions
): Promise<PaymentResult | null>

// 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<string>

// Generate custom data QR code
generateCustomQRCode(
  data: string,
  options?: QRCodeOptions
): Promise<string>
```

#### **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
<script setup>
import { injectService, SERVICE_TOKENS } from '@/core/di-container'

const paymentService = injectService(SERVICE_TOKENS.PAYMENT_SERVICE)

// Reactive state
const { isProcessingPayment, paymentError, totalBalance } = paymentService

// Payment method
const sendPayment = async (invoice: string) => {
  try {
    const result = await paymentService.payWithWallet(invoice, undefined, {
      successMessage: 'Payment sent successfully!'
    })
    console.log('Payment completed:', result.payment_hash)
  } catch (error) {
    console.error('Payment failed:', error.message)
  }
}

// Formatted balance for display
const balanceDisplay = computed(() => {
  return `${Math.round(totalBalance / 1000)} sats`
})
</script>

<template>
  <div class="payment-interface">
    <div class="balance">Balance: {{ balanceDisplay }}</div>

    <button
      @click="sendPayment(invoice)"
      :disabled="isProcessingPayment || !hasBalance"
    >
      {{ isProcessingPayment ? 'Processing...' : 'Send Payment' }}
    </button>

    <div v-if="paymentError" class="error">
      {{ paymentError }}
    </div>
  </div>
</template>
```

## 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