npm package: @startsimpli/billing
Description: Universal billing integration for StartSimpli Next.js apps
Latest version: 0.4.7

# @startsimpli/billing

Universal billing integration for StartSimpli Next.js apps. Products and pricing are configured in Django admin — frontend components auto-fetch and render.

## Backend Setup

The billing backend lives in `start-simpli-api/apps/billing/`. Models, admin, and API are already configured.

### Key Endpoints

| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| `/api/v1/billing/products/` | GET | Public | List public products with offers |
| `/api/v1/billing/products/{slug}/` | GET | Public | Get product by slug |
| `/api/v1/billing/offer-checkout/` | POST | Required | Create checkout session |
| `/api/v1/billing/offer-portal/` | POST | Required | Create portal session |
| `/api/v1/billing/subscription/current/` | GET | Required | Get current user's subscription |

### Admin Workflow

1. Add a `BillingProviderCredential` (Stripe secret key + webhook secret)
2. Create a `BillingProduct` (slug = identifier used by frontend)
3. Add `ProductOffer` inlines (pricing tiers)
4. Use "Sync to provider" admin action to push to Stripe

## Frontend Setup

### Installation

In your Next.js app's `package.json`:

```json
{
  "dependencies": {
    "@startsimpli/billing": "workspace:*"
  }
}
```

Add `transpilePackages: ['@startsimpli/billing']` to `next.config.js`.

### Usage

```tsx
import { BillingProvider, PricingPage, useCheckout, ManageSubscription } from '@startsimpli/billing'

// Wrap your app (or a subtree) with BillingProvider
<BillingProvider apiBaseUrl="/api/v1" authToken={accessToken}>
  <PricingPage productId="raise-simpli" onSelectOffer={handleSelect} />
</BillingProvider>

// Checkout hook
const { checkout, loading } = useCheckout()
await checkout({ offerId, successUrl, cancelUrl })

// Subscription management
<ManageSubscription returnUrl="/settings" buttonText="Manage Billing" />
```

### Components

| Component | Props | Description |
|-----------|-------|-------------|
| `BillingProvider` | `apiBaseUrl`, `authToken` | Context provider — required wrapper |
| `PricingPage` | `productId`, `onSelectOffer?` | Full pricing display with offer cards |
| `PricingSection` | `productId`, `onSelectOffer?` | Pricing section component |
| `PricingDetailPage` | `productId`, `onSelectOffer?` | Detailed pricing page |
| `UpgradeModal` | `productId`, `open`, `onClose`, `onSelectOffer?` | Modal pricing overlay |
| `ManageSubscription` | `returnUrl`, `buttonText?` | Portal redirect button |
| `SubscriptionManager` | `productId?` | Full subscription management interface |

### Hooks

| Hook | Returns | Description |
|------|---------|-------------|
| `useProduct(slug)` | `{ product, loading, error }` | Fetch product + offers |
| `useCheckout()` | `{ checkout, subscribeFree, loading, error }` | Create checkout session or free subscription |
| `usePortal()` | `{ openPortal, loading, error }` | Open customer portal |
| `useSubscription()` | `{ subscription, loading, error, refetch }` | Get current user's subscription |

## Architecture

- **Provider-agnostic**: `BaseBillingProvider` → `StripeBillingProvider` (extensible to Paddle, etc.)
- **BillingProviderFactory**: Resolves credentials per-team with global fallback
- **BillingService**: Orchestrates sync, checkout, and portal operations
- **ProductOffer**: Supports flat, per_seat, tiered, volume, and usage pricing models

## Integration with @startsimpli/auth

The billing package integrates seamlessly with `@startsimpli/auth`:

```tsx
import { BillingProvider } from '@startsimpli/billing'
import { useAuth } from '@startsimpli/auth'

function App() {
  const { tokens } = useAuth()

  return (
    <BillingProvider
      apiBaseUrl={process.env.NEXT_PUBLIC_API_URL + '/api/v1'}
      authToken={tokens?.access}
    >
      {/* Your app */}
    </BillingProvider>
  )
}
```

## Environment Variables

```env
NEXT_PUBLIC_API_URL=https://api.startsimpli.com
```

Backend requires:
```env
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
```

## Tests

```bash
# Frontend tests (39 tests)
cd packages/billing
npm test

# Backend tests (184 tests)
cd start-simpli-api
docker-compose -f docker-compose.local.yml exec -T django pytest apps/billing/tests/ -v
```

## Development

```bash
# Type checking
npm run type-check

# Watch mode for tests
npm run test:watch

# Coverage report
npm run test:coverage
```