npm package: @refcampaign/sdk
Description: Official JavaScript SDK for RefCampaign - Track affiliate conversions with ease
Author: RefCampaign
Latest version: 1.0.1

# RefCampaign SDK

Official JavaScript SDK for RefCampaign affiliate tracking.

Track affiliate conversions seamlessly with automatic session ID capture and Stripe metadata injection.

## Installation

```bash
pnpm add @refcampaign/sdk
# or
npm install @refcampaign/sdk
# or
yarn add @refcampaign/sdk
```

## Quick Start

### Browser Usage (React, Vue, vanilla JS)

Capture affiliate session IDs automatically from cookies, URL parameters, or localStorage.

```typescript
import { RefCampaignBrowser } from '@refcampaign/sdk'

// Capture session ID (call once on page load)
const { sessionId, source } = RefCampaignBrowser.captureSession()
console.log(`Session captured from ${source}:`, sessionId)

// Get session ID later
const currentSession = RefCampaignBrowser.getSessionId()
```

### Server Usage (Node.js, Next.js API routes)

Inject RefCampaign session ID into Stripe checkouts automatically.

```typescript
import { RefCampaignServer } from '@refcampaign/sdk'
import Stripe from 'stripe'

const rc = new RefCampaignServer('sk_prod_xyz789')
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)

export async function POST(req: Request) {
  const { priceId } = await req.json()

  // Get session ID from request (e.g., from cookie or header)
  const sessionId = getSessionIdFromRequest(req)

  // Create Stripe checkout with RefCampaign metadata
  const checkout = await stripe.checkout.sessions.create({
    line_items: [{ price: priceId, quantity: 1 }],
    metadata: rc.getStripeMetadata(sessionId), // ← Automatic conversion tracking!
    mode: 'payment',
    success_url: 'https://yoursite.com/success',
    cancel_url: 'https://yoursite.com/cancel',
  })

  return Response.json({ url: checkout.url })
}
```

## Complete Examples

### Next.js App Router (Full Flow)

**1. Browser-side: Capture session ID**

```typescript
// app/layout.tsx
'use client'

import { useEffect } from 'react'
import { RefCampaignBrowser } from '@refcampaign/sdk'

export default function RootLayout({ children }) {
  useEffect(() => {
    // Capture session ID on page load
    const result = RefCampaignBrowser.captureSession()

    if (result.sessionId) {
      console.log('[RefCampaign] Session tracked:', result.sessionId)
    }
  }, [])

  return (
    <html>
      <body>{children}</body>
    </html>
  )
}
```

**2. Server-side: Create Stripe checkout**

```typescript
// app/api/checkout/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { RefCampaignServer } from '@refcampaign/sdk'
import Stripe from 'stripe'

const rc = new RefCampaignServer(process.env.REFCAMPAIGN_SECRET_KEY!)
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)

export async function POST(req: NextRequest) {
  try {
    // Get session ID from cookie
    const sessionId = req.cookies.get('_rc_sid')?.value

    // Get price from request
    const { priceId } = await req.json()

    // Create Stripe checkout
    const checkout = await stripe.checkout.sessions.create({
      line_items: [{ price: priceId, quantity: 1 }],

      // Inject RefCampaign session ID (CRITICAL!)
      metadata: rc.getStripeMetadata(sessionId),

      mode: 'subscription',
      success_url: `${process.env.NEXT_PUBLIC_APP_URL}/success`,
      cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing`,
    })

    return NextResponse.json({ url: checkout.url })
  } catch (error) {
    console.error('[Checkout] Error:', error)
    return NextResponse.json(
      { error: 'Failed to create checkout' },
      { status: 500 }
    )
  }
}
```

**3. Webhook: Automatic conversion tracking**

RefCampaign automatically tracks conversions via Stripe webhooks when it detects the `refcampaign_session` metadata. No additional code needed!

---

### React SPA + Express Backend

**Frontend (React)**

```typescript
// src/App.tsx
import { useEffect } from 'react'
import { RefCampaignBrowser } from '@refcampaign/sdk'

function App() {
  useEffect(() => {
    RefCampaignBrowser.captureSession()
  }, [])

  async function handleCheckout() {
    // Session ID is already captured and stored
    const sessionId = RefCampaignBrowser.getSessionId()

    // Send to backend
    const response = await fetch('/api/checkout', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        priceId: 'price_xxx',
        sessionId // Pass session ID explicitly
      }),
    })

    const { url } = await response.json()
    window.location.href = url
  }

  return <button onClick={handleCheckout}>Subscribe</button>
}
```

**Backend (Express)**

```typescript
// server.ts
import express from 'express'
import Stripe from 'stripe'
import { RefCampaignServer } from '@refcampaign/sdk'

const app = express()
const rc = new RefCampaignServer(process.env.REFCAMPAIGN_SECRET_KEY)
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)

app.post('/api/checkout', async (req, res) => {
  const { priceId, sessionId } = req.body

  const checkout = await stripe.checkout.sessions.create({
    line_items: [{ price: priceId, quantity: 1 }],
    metadata: rc.getStripeMetadata(sessionId),
    mode: 'subscription',
    success_url: 'https://yoursite.com/success',
    cancel_url: 'https://yoursite.com/cancel',
  })

  res.json({ url: checkout.url })
})

app.listen(3000)
```

---

## Manual Conversion Tracking

For non-Stripe conversions (PayPal, bank transfer, etc.), use manual tracking:

```typescript
import { RefCampaignServer } from '@refcampaign/sdk'

const rc = new RefCampaignServer('sk_prod_xyz789')

async function handlePayPalPayment(sessionId: string, amount: number) {
  // Track conversion manually
  const result = await rc.trackConversion({
    sessionId,
    amount: 4999, // Amount in cents (€49.99)
    currency: 'EUR',
    metadata: {
      payment_method: 'paypal',
      plan: 'pro',
    },
  })

  if (result.success) {
    console.log('Conversion tracked:', result.conversionId)
  } else {
    console.error('Failed to track conversion:', result.error)
  }
}
```

---

## API Reference

### `RefCampaignBrowser`

Browser-side API for capturing session IDs.

#### Methods

##### `captureSession(): SessionCaptureResult`

Capture session ID from URL, cookie, or localStorage.

Priority order:
1. URL parameter (`?_rcid=xxx`)
2. Cookie (`_rc_sid`)
3. localStorage (`_rc_sid`)

```typescript
const { sessionId, source } = RefCampaignBrowser.captureSession()
console.log(`Captured from ${source}:`, sessionId)
```

##### `getSessionId(): string | null`

Get current session ID from localStorage.

```typescript
const sessionId = RefCampaignBrowser.getSessionId()
```

---

### `RefCampaignServer`

Server-side API for Stripe metadata injection and conversion tracking.

#### Constructor

```typescript
new RefCampaignServer(secretKey: string, config?: {
  apiUrl?: string // Default: 'https://app.refcampaign.com'
  debug?: boolean // Default: false
})
```

#### Methods

##### `getStripeMetadata(sessionId?: string): StripeMetadata`

Get Stripe metadata with RefCampaign session ID.

```typescript
const metadata = rc.getStripeMetadata('abc123')
// Returns: { refcampaign_session: 'abc123' }
```

##### `trackConversion(data: ConversionData): Promise<TrackConversionResponse>`

Track conversion manually (for non-Stripe payments).

```typescript
const result = await rc.trackConversion({
  sessionId: 'abc123',
  amount: 4999, // cents
  currency: 'EUR',
  metadata: { plan: 'pro' } // optional
})
```

---

## TypeScript Types

```typescript

interface RefCampaignServerConfig {
  secretKey: string // Starts with 'sk_'
  apiUrl?: string
  debug?: boolean
}

interface SessionCaptureResult {
  sessionId: string | null
  source: 'url' | 'cookie' | 'localStorage' | 'none'
}

interface ConversionData {
  sessionId?: string
  amount: number // Amount in cents (integer)
  currency: string // ISO 4217 code (e.g., 'EUR', 'USD')
  metadata?: Record<string, any>
}

interface StripeMetadata {
  refcampaign_session?: string
}
```

---

## How It Works

1. **User clicks affiliate link**: `https://track.refcampaign.com/AFFILIATE_CODE`
2. **Tracking worker sets cookie**: `_rc_sid` with 90-day expiration
3. **User lands on your site**: SDK captures session ID
4. **User subscribes**: Stripe metadata includes `refcampaign_session`
5. **Webhook triggers**: RefCampaign tracks conversion automatically
6. **Commission calculated**: Affiliate earns commission

---

## Environment Variables

```bash
# Secret key (server-side only, NEVER expose in browser)
REFCAMPAIGN_SECRET_KEY=sk_prod_xyz789
```

---

## License

MIT

---

## Support

Need help? Contact us at support@refcampaign.com