npm package: @growflowstudio/growflowbilling-client
Description: Node.js/TypeScript client for GrowFlow Billing API - subscription management, checkout, invoices
Author: GrowFlow
Latest version: 1.3.0

# @growflow/billing-client

Official Node.js/TypeScript client for the GrowFlow Billing API.

## Installation

```bash
npm install @growflow/billing-client
# or
yarn add @growflow/billing-client
# or
pnpm add @growflow/billing-client
```

## Quick Start

```typescript
import { GrowFlowBillingClient } from '@growflow/billing-client';

// Initialize with API key
const client = new GrowFlowBillingClient({
  apiKey: 'sk_live_your_api_key',
});

// Or use environment variable GROWFLOW_BILLING_API_KEY
const client = new GrowFlowBillingClient();

// Get available plans
const plans = await client.getPlans();
console.log(plans);

// Create a subscriber
const subscriber = await client.createSubscriber({
  externalId: 'user_123',
  email: 'customer@example.com',
  name: 'John Doe',
});

// Create checkout session
const session = await client.createCheckoutSession({
  customerExternalId: 'user_123',
  planSlug: 'pro',
  successUrl: 'https://app.example.com/success',
  cancelUrl: 'https://app.example.com/cancel',
});

// Redirect customer to Stripe Checkout
console.log('Redirect to:', session.url);
```

## Configuration

### Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `apiKey` | `string` | - | API key (required, or use env var) |
| `baseUrl` | `string` | `https://billing.growflow.studio/api/v1` | API base URL |
| `timeout` | `number` | `30000` | Request timeout in ms |
| `maxRetries` | `number` | `3` | Max retry attempts |
| `retryDelay` | `number` | `1000` | Initial retry delay in ms |

### Environment Variables

- `GROWFLOW_BILLING_API_KEY`: API key
- `GROWFLOW_BILLING_URL`: Custom base URL
- `GROWFLOW_BILLING_TIMEOUT`: Request timeout

## API Reference

### Plans

```typescript
// List all active plans
const plans = await client.getPlans();

// Get a specific plan
const plan = await client.getPlan('pro');

// Check plan properties
import { isPlanFree, isPlanEnterprise, getPlanPrice } from '@growflow/billing-client';

if (isPlanFree(plan)) {
  console.log('This is a free plan');
}

const monthlyPrice = getPlanPrice(plan, 'monthly');
const yearlyPrice = getPlanPrice(plan, 'yearly');
```

### Subscribers

```typescript
// Create a subscriber
const subscriber = await client.createSubscriber({
  externalId: 'user_123',
  email: 'customer@example.com',
  name: 'John Doe',
  companyName: 'Acme Inc',
  vatNumber: 'IT12345678901',
  billingAddress: {
    line1: 'Via Roma 1',
    city: 'Milan',
    postalCode: '20100',
    country: 'IT',
  },
});

// Get subscriber
const subscriber = await client.getSubscriber('user_123');

// Update subscriber
const updated = await client.updateSubscriber('user_123', {
  email: 'newemail@example.com',
  name: 'Jane Doe',
});
```

### Subscriptions

```typescript
// Get current subscription
const subscription = await client.getSubscription('user_123');

if (subscription) {
  console.log(`Plan: ${subscription.planName}`);
  console.log(`Status: ${subscription.status}`);
}

// List all subscriptions
const subscriptions = await client.listSubscriptions('user_123');

// Cancel subscription at period end
await client.cancelSubscription(subscription.id, {
  atPeriodEnd: true,
});

// Change plan
await client.changePlan(subscription.id, 'enterprise', {
  prorate: true,
});

// Check subscription helpers
import {
  isSubscriptionActive,
  isSubscriptionTrialing,
  getTrialDaysRemaining,
} from '@growflow/billing-client';

if (isSubscriptionTrialing(subscription)) {
  const daysLeft = getTrialDaysRemaining(subscription);
  console.log(`Trial ends in ${daysLeft} days`);
}
```

### Checkout Sessions

```typescript
// Create subscription checkout
const session = await client.createCheckoutSession({
  customerExternalId: 'user_123',
  planSlug: 'pro',
  billingCycle: 'yearly',
  successUrl: 'https://app.example.com/billing/success',
  cancelUrl: 'https://app.example.com/billing/cancel',
  email: 'customer@example.com', // Pre-fill
  couponCode: 'SAVE20',
});

// Redirect to Stripe Checkout
window.location.href = session.url;

// Create customer portal session
const portal = await client.createPortalSession({
  customerExternalId: 'user_123',
  returnUrl: 'https://app.example.com/settings/billing',
});

window.location.href = portal.url;
```

### Invoices

```typescript
// List invoices
const { items: invoices, hasMore } = await client.listInvoices('user_123', {
  status: 'paid',
  limit: 10,
});

for (const invoice of invoices) {
  console.log(`${invoice.number}: ${invoice.totalDecimal} ${invoice.currency}`);
}

// Get specific invoice
const invoice = await client.getInvoice('in_123');

// Get upcoming invoice (next charge preview)
const upcoming = await client.getUpcomingInvoice('user_123');

// Get invoice PDF URL
const pdfUrl = await client.getInvoicePdfUrl('in_123');
```

### Products (Add-ons)

```typescript
// List products
const products = await client.listProducts({ active: true });

// Get product details
const product = await client.getProduct('extra_conversations');

// Purchase a product
const session = await client.purchaseProduct({
  customerExternalId: 'user_123',
  priceId: 'price_123',
  quantity: 1,
  successUrl: 'https://app.example.com/purchase/success',
  cancelUrl: 'https://app.example.com/purchase/cancel',
});

// Get customer's purchased products
const purchases = await client.getCustomerProducts('user_123');
```

## Error Handling

```typescript
import {
  GrowFlowBillingError,
  AuthenticationError,
  NotFoundError,
  ConflictError,
  ValidationError,
  RateLimitError,
  ServerError,
} from '@growflow/billing-client';

try {
  const subscriber = await client.getSubscriber('unknown_id');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.log('Subscriber not found');
  } else if (error instanceof AuthenticationError) {
    console.log('Invalid API key');
  } else if (error instanceof RateLimitError) {
    console.log('Too many requests, try again later');
  } else if (error instanceof GrowFlowBillingError) {
    console.log(`API error: ${error.message}`);
  }
}
```

## TypeScript Support

This package is written in TypeScript and includes full type definitions.

```typescript
import type {
  Plan,
  Subscriber,
  Subscription,
  Invoice,
  CheckoutSession,
  SubscriptionStatus,
  BillingCycle,
} from '@growflow/billing-client';

// All types are exported and available
const subscription: Subscription = await client.getSubscription('user_123');

if (subscription.status === SubscriptionStatus.ACTIVE) {
  // ...
}
```

## License

MIT

## Related

- [growflow-billing-client](https://github.com/growflow/growflow-billing-client) - Python client
- [GrowFlow Billing API Documentation](https://docs.growflow.studio/billing)