npm package: @holdmysub/nextjs
Description: ⚠️ DEPRECATED: Package renamed to @billgojs/nextjs. Please install @billgojs/nextjs instead.
Author: HoldMySub
Latest version: 1.0.10
Deprecated: Package renamed to @billgojs/nextjs. Please migrate to the new package.

# ⚠️ DEPRECATED: @holdmysub/nextjs

> **This package has been renamed to [@billgojs/nextjs](https://www.npmjs.com/package/@billgojs/nextjs)**
>
> Please migrate to the new package. See [Migration Guide](#migration-guide) below.

---

## Migration Guide

This package has been rebranded from `@holdmysub/nextjs` to `@billgojs/nextjs`. To migrate:

### 1. Install the new package

```bash
npm uninstall @holdmysub/nextjs
npm install @billgojs/nextjs
```

### 2. Update your imports

```diff
- import { HoldMySubProvider, PaywallButton } from '@holdmysub/nextjs';
+ import { BillgoProvider, PaywallButton } from '@billgojs/nextjs';

- import { holdmysub } from '@holdmysub/nextjs/server';
+ import { billgo } from '@billgojs/nextjs/server';
```

### 3. Update component names

```diff
- <HoldMySubProvider>
+ <BillgoProvider>
    {children}
- </HoldMySubProvider>
+ </BillgoProvider>
```

### 4. Update environment variables

```diff
- NEXT_PUBLIC_HOLDMYSUB_PUBLIC_KEY=...
+ NEXT_PUBLIC_BILLGO_PUBLIC_KEY=...

- HOLDMYSUB_SECRET_KEY=...
+ BILLGO_SECRET_KEY=...

- HOLDMYSUB_BASE_URL=...
+ BILLGO_BASE_URL=...
```

### 5. Update hooks (if using)

```diff
- import { useHoldMySub } from '@holdmysub/nextjs';
+ import { useBillgo } from '@billgojs/nextjs';

- const context = useHoldMySub();
+ const context = useBillgo();
```

All functionality remains the same - only the names have changed!

---

## Old Documentation (for reference)

Next.js components and utilities for HoldMySub paywall integration with
automatic environment variable detection.

## Features

✅ **Zero Configuration** - Auto-detects API keys from environment variables ✅
**Next.js Optimized** - Built specifically for Next.js 13+ with App Router
support ✅ **TypeScript First** - Full type safety and IntelliSense support ✅
**Server-Side Support** - Payment verification in API routes and server
components ✅ **Beautiful Components** - Pre-built, customizable UI components
✅ **Flexible Hooks** - Programmatic access to payment functionality

## Installation

```bash
npm install @holdmysub/nextjs
```

## Quick Start

### 1. Environment Setup

Add your API keys to `.env.local`:

```env
NEXT_PUBLIC_HOLDMYSUB_PUBLIC_KEY=pk_test_cHJldHR5LXNsdWctOTAuY2xlcmsuYWNjb3VudHMuZGV2JA
HOLDMYSUB_SECRET_KEY=sk_test_cHJldHR5LXNsdWctOTAuY2xlcmsuYWNjb3VudHMuZGV2JA
```

Get your keys from
[https://holdmysub.com/dashboard](https://holdmysub.com/dashboard)

### 2. Provider Setup

Wrap your app with the HoldMySubProvider:

```tsx
// app/layout.tsx
import { HoldMySubProvider } from '@holdmysub/nextjs';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <HoldMySubProvider>{children}</HoldMySubProvider>
      </body>
    </html>
  );
}
```

### 3. Add Payment Components

```tsx
// app/premium/page.tsx
import { PaywallButton, PremiumContent } from '@holdmysub/nextjs';

export default function PremiumPage() {
  return (
    <div>
      <h1>Premium Features</h1>

      <PremiumContent
        productId="premium_plan"
        fallback={
          <PaywallButton
            productId="premium_plan"
            customerEmail="user@example.com"
          >
            🚀 Upgrade to Premium - $9.99
          </PaywallButton>
        }
      >
        <h2>🎉 Welcome to Premium!</h2>
        <p>This content is only visible to paying customers.</p>
      </PremiumContent>
    </div>
  );
}
```

### 4. Server-Side Protection

```tsx
// app/api/premium-data/route.ts
import { holdmysub } from '@holdmysub/nextjs/server';

export async function GET(request: Request) {
  const customerEmail = 'customer@example.com'; // Get from your auth system

  const verification = await holdmysub.verifyPayment(
    customerEmail,
    'premium_plan'
  );

  if (!verification.hasAccess) {
    return new Response('Payment required', { status: 402 });
  }

  return Response.json({
    data: 'This is premium data!',
    paidAt: verification.paidAt,
  });
}
```

## Components

### PaywallButton

A button that creates a checkout session and redirects to payment.

```tsx
import { PaywallButton } from '@holdmysub/nextjs';

<PaywallButton
  productId="premium_plan"
  customerEmail="user@example.com"
  variant="primary"
  size="lg"
  onSuccess={(info) => console.log('Payment successful!', info)}
  onError={(error) => console.error('Payment failed:', error)}
>
  Unlock Premium Features - $9.99
</PaywallButton>;
```

**Props:**

- `productId` (string) - Your product ID from the dashboard
- `customerEmail` (string, optional) - Customer email (can be set in provider)
- `variant` (string) - Button style: `primary`, `secondary`, `success`,
  `danger`, `outline`
- `size` (string) - Button size: `sm`, `md`, `lg`
- `onSuccess` (function) - Called when payment succeeds
- `onError` (function) - Called when payment fails
- `children` (ReactNode) - Button content
- `className` (string) - Additional CSS classes
- `style` (CSSProperties) - Inline styles

### PremiumContent

A wrapper that shows content only after payment verification.

```tsx
import { PremiumContent, PaywallButton } from '@holdmysub/nextjs';

<PremiumContent
  productId="premium_plan"
  customerEmail="customer@example.com"
  fallback={
    <PaywallButton productId="premium_plan">Unlock Content</PaywallButton>
  }
>
  <h2>Premium Content Here!</h2>
  <p>Only paying customers see this.</p>
</PremiumContent>;
```

**Props:**

- `productId` (string) - Product ID required for access
- `customerEmail` (string, optional) - Customer email (can be set in provider)
- `fallback` (ReactNode) - Content to show when access denied
- `children` (ReactNode) - Premium content to show after verification
- `onAccessGranted` (function) - Called when access is verified
- `onAccessDenied` (function) - Called when access is denied

## Hooks

### usePaywall

Hook for programmatic checkout creation.

```tsx
import { usePaywall } from '@holdmysub/nextjs';

function CustomButton() {
  const { createCheckout, loading, error } = usePaywall();

  const handleClick = async () => {
    await createCheckout({
      productId: 'premium_plan',
      customerEmail: 'user@example.com',
    });
  };

  return (
    <button onClick={handleClick} disabled={loading}>
      {loading ? 'Processing...' : 'Pay Now'}
    </button>
  );
}
```

### usePremiumContent

Hook for checking premium content access.

```tsx
import { usePremiumContent } from '@holdmysub/nextjs';

function CustomPremiumContent() {
  const { hasAccess, loading, error, retry } = usePremiumContent({
    productId: 'premium_plan',
    customerEmail: 'customer@example.com',
  });

  if (loading) return <div>Checking access...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!hasAccess) return <PaywallButton productId="premium_plan" />;

  return <div>Premium content here!</div>;
}
```

## Server-Side Usage

### Payment Verification

```tsx
import { holdmysub } from '@holdmysub/nextjs/server';

// In API routes or server components
const verification = await holdmysub.verifyPayment(
  'customer@example.com',
  'premium_plan'
);

if (verification.hasAccess) {
  console.log('User has access!');
  console.log('Paid at:', verification.paidAt);
  console.log('Amount:', verification.formattedAmount);
}
```

### Auth Middleware

```tsx
import { holdmysub } from '@holdmysub/nextjs/server';

// Create protected API route
export const GET = holdmysub.createAuthMiddleware('premium_plan')(async (
  request: Request
) => {
  // This only runs if user has paid for premium_plan
  return Response.json({ data: 'Protected data' });
});
```

### Payment History

```tsx
import { holdmysub } from '@holdmysub/nextjs/server';

const history = await holdmysub.getPaymentHistory();
console.log(`Total payments: ${history.total}`);
```

## Configuration

### Environment Variables

- `NEXT_PUBLIC_HOLDMYSUB_PUBLIC_KEY` - Public key (client-side accessible)
- `HOLDMYSUB_SECRET_KEY` - Secret key (server-side only)
- `HOLDMYSUB_BASE_URL` - Custom API base URL (optional)

### Provider Props

```tsx
<HoldMySubProvider
  userEmail="user@example.com" // Default user email
  customerEmail="customer@example.com" // Default customer email
  debug={true} // Enable debug logging
>
  {children}
</HoldMySubProvider>
```

## TypeScript Support

Full TypeScript support with comprehensive type definitions:

```tsx
import type {
  PaywallButtonProps,
  PremiumContentProps,
  PaymentSuccessInfo,
  ServerPaymentVerification,
} from '@holdmysub/nextjs';
```

## Examples

### Custom Styles

```tsx
<PaywallButton
  productId="premium_plan"
  style={{
    background: 'linear-gradient(45deg, #ff6b6b, #4ecdc4)',
    borderRadius: '12px',
    fontSize: '18px',
    padding: '16px 32px',
  }}
>
  🌟 Premium Upgrade
</PaywallButton>
```

### With User Authentication

```tsx
// With NextAuth.js
import { useSession } from 'next-auth/react';

function AuthenticatedPaywall() {
  const { data: session } = useSession();

  return (
    <PremiumContent
      productId="premium_plan"
      customerEmail={session?.user?.email}
    >
      <PremiumFeatures />
    </PremiumContent>
  );
}
```

### Multiple Products

```tsx
<div>
  <PremiumContent productId="basic_plan">
    <BasicFeatures />
  </PremiumContent>

  <PremiumContent productId="pro_plan">
    <ProFeatures />
  </PremiumContent>
</div>
```

## Support

- 📖 [Documentation](https://holdmysub.com/docs)
- 💬 [Discord Community](https://discord.gg/holdmysub)
- 📧 [Email Support](mailto:support@holdmysub.com)

## License

MIT © [HoldMySub](https://holdmysub.com)