# NakaPay React Components

React components for integrating Bitcoin Lightning payments with NakaPay.

⚠️ **SECURITY WARNING**: The NakaPay API key must ONLY be used on your backend server. Never expose API keys in client-side code, environment variables with `NEXT_PUBLIC_` prefix, or frontend applications.

## Installation

```bash
npm install nakapay-react
# or
yarn add nakapay-react
```

## Quick Start

### 1. Set up your backend (REQUIRED)

**CRITICAL**: API keys must only be used server-side. Set up backend endpoints to handle payments securely:

```javascript
// Backend example (Express.js) - SERVER SIDE ONLY
const express = require('express');
const { NakaPay } = require('nakapay-sdk');

const app = express();
// SECURE: API key from server environment variable only
const nakaPay = new NakaPay(process.env.NAKAPAY_API_KEY); // NOT NEXT_PUBLIC_

app.post('/api/create-payment', async (req, res) => {
  try {
    // Add input validation
    const { amount, description, metadata } = req.body;
    
    if (!amount || amount <= 0) {
      return res.status(400).json({ error: 'Invalid amount' });
    }
    
    if (!description || description.trim().length === 0) {
      return res.status(400).json({ error: 'Description required' });
    }
    
    const payment = await nakaPay.createPaymentRequest(req.body);
    res.json(payment);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.get('/api/payment-status/:id', async (req, res) => {
  try {
    const { id } = req.params;
    
    if (!id || id.trim().length === 0) {
      return res.status(400).json({ error: 'Payment ID required' });
    }
    
    const status = await nakaPay.getPaymentStatus(id);
    res.json(status);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
```

### 2. Use React components

```tsx
import React from 'react';
import { NakaPayButton } from 'nakapay-react';

function CheckoutPage() {
  return (
    <div>
      <h2>Complete Your Purchase</h2>
      <NakaPayButton
        amount={50000} // Amount in satoshis
        description="Product purchase"
        onPaymentSuccess={(payment) => {
          console.log('Payment successful!', payment);
          // Redirect to success page or update UI
        }}
        onPaymentError={(error) => {
          console.error('Payment failed:', error);
          // Handle error
        }}
      />
    </div>
  );
}
```

## Components

### NakaPayButton

A complete payment button that handles the entire payment flow.

**Props:**
- `amount` (number, required): Payment amount in satoshis
- `description` (string, required): Payment description
- `metadata?` (object): Additional metadata for the payment
- `text?` (string): Custom button text (defaults to "Pay {amount} sats")
- `className?` (string): Additional CSS classes
- `style?` (CSSProperties): Custom styles
- `disabled?` (boolean): Disable the button
- `apiEndpoint?` (string): Backend endpoint for creating payments (default: '/api/create-payment')
- `onPaymentCreated?` (function): Called when payment is created
- `onPaymentSuccess?` (function): Called when payment is successful
- `onPaymentError?` (function): Called when payment fails

**Real-time Payment Notifications:**
- `useAbly?` (boolean): Use Ably for real-time updates (recommended)
- `ablyApiKey?` (string): Ably API key for real-time connection
- `useWebhooks?` (boolean): Use WebSocket connection for real-time updates
- `webhookUrl?` (string): WebSocket server URL for webhook-based updates
- `useSSE?` (boolean): Use Server-Sent Events for real-time updates
- `pollInterval?` (number): Polling interval in ms when real-time methods unavailable (default: 2000)
- `statusEndpoint?` (string): Backend endpoint for status polling (default: '/api/payment-status')

### NakaPayModal

A payment modal component for custom implementations.

**Props:**
- `payment` (Payment, required): Payment object from your backend
- `onClose` (function, required): Called when modal is closed
- `onPaymentSuccess?` (function): Called when payment is successful
- `onPaymentError?` (function): Called when payment fails
- `useAbly?` (boolean): Use Ably for real-time updates
- `ablyApiKey?` (string): Ably API key for real-time connection
- `useWebhooks?` (boolean): Use WebSocket connection for updates
- `webhookUrl?` (string): WebSocket server URL
- `useSSE?` (boolean): Use Server-Sent Events for updates
- `pollInterval?` (number): Status polling interval in ms (default: 2000)
- `statusEndpoint?` (string): Backend endpoint for checking status (default: '/api/payment-status')

## Real-time Payment Updates

NakaPay React components support multiple methods for real-time payment status updates, with automatic fallbacks:

### 1. Ably (Recommended)

Ably provides the most reliable real-time updates using cloud infrastructure:

```tsx
<NakaPayButton
  amount={50000}
  description="Product purchase"
  useAbly={true}
  ablyApiKey="your-ably-api-key"
  onPaymentSuccess={(payment) => console.log('Success!', payment)}
/>
```

**Setup:**
1. Sign up for [Ably](https://ably.com)
2. Get your API key
3. Configure webhooks in your NakaPay dashboard to publish to Ably

### 2. WebSocket Connection

Direct WebSocket connection to your webhook server:

```tsx
<NakaPayButton
  amount={50000}
  description="Product purchase"
  useWebhooks={true}
  webhookUrl="ws://localhost:3002"
  onPaymentSuccess={(payment) => console.log('Success!', payment)}
/>
```

**Setup:**
1. Run a WebSocket server (e.g., using Socket.IO)
2. Configure NakaPay webhooks to notify your server
3. Have your server emit WebSocket events to connected clients

### 3. Server-Sent Events (SSE)

HTTP streaming for real-time updates:

```tsx
<NakaPayButton
  amount={50000}
  description="Product purchase"
  useSSE={true}
  onPaymentSuccess={(payment) => console.log('Success!', payment)}
/>
```

**Setup:**
1. Implement `/api/payments/stream` endpoint that streams SSE
2. Configure NakaPay webhooks to trigger SSE updates

### 4. Polling (Automatic Fallback)

If no real-time method is configured, components automatically fall back to polling:

```tsx
<NakaPayButton
  amount={50000}
  description="Product purchase"
  pollInterval={3000} // Check every 3 seconds
  statusEndpoint="/api/payment-status"
  onPaymentSuccess={(payment) => console.log('Success!', payment)}
/>
```

### Priority Order

The components try real-time methods in this order:
1. **Ably** (if `useAbly={true}`)
2. **WebSocket** (if `useWebhooks={true}`)
3. **Server-Sent Events** (if `useSSE={true}`)
4. **Polling** (automatic fallback)

## Advanced Usage

### Custom Payment Flow

```tsx
import React, { useState } from 'react';
import { NakaPayModal, Payment } from 'nakapay-react';

function CustomCheckout() {
  const [showModal, setShowModal] = useState(false);
  const [payment, setPayment] = useState<Payment | null>(null);

  const handleCustomPayment = async () => {
    try {
      const response = await fetch('/api/create-payment', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          amount: 25000,
          description: 'Custom payment',
          metadata: { orderId: '12345' }
        })
      });
      
      const paymentData = await response.json();
      setPayment(paymentData);
      setShowModal(true);
    } catch (error) {
      console.error('Failed to create payment:', error);
    }
  };

  return (
    <div>
      <button onClick={handleCustomPayment}>
        Custom Pay Button
      </button>
      
      {showModal && payment && (
        <NakaPayModal
          payment={payment}
          onClose={() => setShowModal(false)}
          onPaymentSuccess={(payment) => {
            console.log('Success!', payment);
            setShowModal(false);
          }}
        />
      )}
    </div>
  );
}
```

## Styling

Import the default styles:

```tsx
import 'nakapay-react/dist/styles.css';
```

Or provide your own custom styles using the provided CSS classes:
- `.nakapay-button` - Button component
- `.nakapay-modal-overlay` - Modal overlay
- `.nakapay-modal` - Modal content

## TypeScript Support

This package includes TypeScript definitions. All components are fully typed.

## License

MIT
