npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@refcampaign/sdk

v1.0.1

Published

Official JavaScript SDK for RefCampaign - Track affiliate conversions with ease

Readme

RefCampaign SDK

Official JavaScript SDK for RefCampaign affiliate tracking.

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

Installation

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.

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.

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

// 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

// 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)

// 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)

// 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:

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)
const { sessionId, source } = RefCampaignBrowser.captureSession()
console.log(`Captured from ${source}:`, sessionId)
getSessionId(): string | null

Get current session ID from localStorage.

const sessionId = RefCampaignBrowser.getSessionId()

RefCampaignServer

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

Constructor

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.

const metadata = rc.getStripeMetadata('abc123')
// Returns: { refcampaign_session: 'abc123' }
trackConversion(data: ConversionData): Promise<TrackConversionResponse>

Track conversion manually (for non-Stripe payments).

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

TypeScript Types


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

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

License

MIT


Support

Need help? Contact us at [email protected]