> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paymint.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# React SDK

> Documentation for @paymint/react

# @paymint/react

React hooks for Paymint billing.

## Installation

```bash theme={null}
npm install @paymint/react
```

> **Note:** For Next.js apps, use `@paymint/nextjs` instead - it includes everything from this package plus server utilities.

## Quick Start

### 1. Set up Provider

```tsx theme={null}
import { PaymintProvider } from '@paymint/react';

function App() {
  return (
    <PaymintProvider 
      apiRoute="/api/billing"           // Your backend API route
      customerEmail="user@example.com"  // Current user's email
      onCheckoutComplete={(txnId) => {
        // Handle successful checkout
        window.location.href = `/success?txn=${txnId}`;
      }}
    >
      <YourApp />
    </PaymintProvider>
  );
}
```

### 2. Use Hooks

```tsx theme={null}
import { useBilling, useCheckout } from '@paymint/react';

function PricingPage() {
  const { products, subscription, loading, hasActiveSubscription } = useBilling();
  const { openCheckout, ready } = useCheckout();

  if (loading) return <div>Loading...</div>;

  if (hasActiveSubscription) {
    return <div>Current plan: {subscription.productName}</div>;
  }

  return (
    <div>
      {products.map(product => (
        <div key={product.id}>
          <h2>{product.name}</h2>
          {product.prices.map(price => (
            <button
              key={price.id}
              onClick={() => openCheckout(price.id)}
              disabled={!ready}
            >
              ${price.unitPrice.amount / 100}/{price.billingCycle.interval}
            </button>
          ))}
        </div>
      ))}
    </div>
  );
}
```

## Hooks

### `useBilling()`

Combined billing data (products + subscription).

```tsx theme={null}
const {
  products,              // Product[]
  subscription,          // Subscription | null
  loading,               // boolean
  error,                 // Error | null
  refresh,               // () => Promise<void>
  hasActiveSubscription, // boolean
  isOnTrial,             // boolean
} = useBilling();
```

### `useProducts()`

Available products only.

```tsx theme={null}
const {
  products,  // Product[]
  loading,   // boolean
  error,     // Error | null
  refresh,   // () => Promise<void>
} = useProducts();
```

### `useSubscription()`

Subscription management.

```tsx theme={null}
const {
  subscription,          // Subscription | null
  loading,               // boolean
  hasActiveSubscription, // boolean
  isOnTrial,             // boolean
  isPaused,              // boolean
  isCanceling,           // boolean
  cancel,                // (options?) => Promise<void>
  pause,                 // (options?) => Promise<void>
  resume,                // () => Promise<void>
  isMutating,            // boolean
} = useSubscription();

// Cancel at end of billing period
await cancel({ effectiveFrom: 'next_billing_period' });

// Pause subscription
await pause({ effectiveFrom: 'next_billing_period' });

// Resume paused subscription
await resume();
```

### `useCheckout()`

Paddle checkout integration.

```tsx theme={null}
const {
  ready,         // boolean - checkout is ready
  loading,       // boolean - initializing
  openCheckout,  // (priceId | options) => void
  closeCheckout, // () => void
  error,         // Error | null
} = useCheckout();

// Simple
openCheckout('pri_xxx');

// With options
openCheckout({
  items: [{ priceId: 'pri_xxx', quantity: 1 }],
  discountCode: 'SAVE20',
  settings: { 
    theme: 'dark',
    successUrl: '/checkout/success',
  },
});
```

## Provider Props

```tsx theme={null}
<PaymintProvider
  apiRoute="/api/billing"             // Required: your backend route
  customerEmail="user@example.com"    // Customer email
  autoLoadProducts={true}             // Auto-fetch products (default: true)
  autoLoadSubscription={true}         // Auto-fetch subscription (default: true)
  onCheckoutComplete={(txnId) => {}}  // Checkout success callback
  onCheckoutClose={() => {}}          // Checkout closed callback
>
```

## Post-Checkout Success Handling

### Option 1: `onCheckoutComplete` Callback

```tsx theme={null}
<PaymintProvider
  apiRoute="/api/billing"
  customerEmail={email}
  onCheckoutComplete={(transactionId) => {
    // Redirect to success page
    window.location.href = `/checkout/success?txn=${transactionId}`;
  }}
>
```

### Option 2: Paddle's `successUrl`

```tsx theme={null}
openCheckout({
  items: [{ priceId: 'pri_xxx' }],
  settings: { 
    successUrl: '/checkout/success',  // Paddle redirects here
  },
});
```

> **Note:** Subscriptions are created via webhooks. There may be a 1-5 second delay between payment and subscription appearing in the database.

## Backend Required

This package requires a backend API that proxies to Paymint. The provider calls:

```
GET  {apiRoute}/products        → List products
GET  {apiRoute}/subscriptions   → Get subscriptions  
POST {apiRoute}/initialize      → Initialize checkout
POST {apiRoute}/cancel/{id}     → Cancel subscription
POST {apiRoute}/pause/{id}      → Pause subscription
POST {apiRoute}/resume/{id}     → Resume subscription
```

Use `@paymint/server` or `@paymint/nextjs` to create these endpoints.

## Security

### Backend Developer Responsibilities

When creating your backend API route, ensure:

#### 1. Get Email from Auth Session (CRITICAL)

```typescript theme={null}
// ✅ CORRECT - Email from authenticated session
const email = session.user.email;  // From your auth system

// ❌ WRONG - Email from request body
const { email } = req.body;  // Attacker can impersonate any user!
```

#### 2. Keep API Key Server-Side

```typescript theme={null}
// ✅ CORRECT
const paymint = new PaymintServer({
  apiKey: process.env.PAYMINT_API_KEY,  // Server-side only
});

// ❌ WRONG
apiKey: process.env.NEXT_PUBLIC_API_KEY,  // Exposed to client!
```

### What Paymint Handles

* API key encryption
* Subscription ownership verification
* Paddle API security
* Webhook signature verification

### What Your Backend Must Handle

* Authenticate users before billing operations
* Get email from auth session (not request body)
* Keep API key server-side only

## License

MIT
