Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/revokslab/shipfree/llms.txt

Use this file to discover all available pages before exploring further.

Polar is a payment platform built specifically for developers selling to developers. It offers GitHub integration, simple pricing, and a developer-friendly experience.

Prerequisites

  • A Polar account (sign up here)
  • Your ShipFree application running locally or deployed
  • (Optional) A GitHub repository for integration

Setup Instructions

Step 1: Get Your API Keys

  1. Log in to Polar
  2. Navigate to SettingsAPI
  3. Create a new Access Token
  4. Copy the access token (starts with polar_)
  5. Note your Organization ID

Step 2: Create Products

Polar uses a product-based pricing model.
  1. Go to Products in your Polar dashboard
  2. Click Create Product
  3. For each plan (Starter, Pro, Enterprise):
    • Set the product name
    • Set the description
    • Configure pricing:
      • Price: Amount in USD
      • Billing interval: Monthly or Yearly
      • Recurring: Yes for subscriptions
    • Set the product visibility
    • Save and copy the Product ID

Step 3: Configure Environment Variables

Add these variables to your .env file:
# Payment Provider Selection
PAYMENT_PROVIDER=polar

# Polar Access Token (server-side)
POLAR_ACCESS_TOKEN=polar_your_access_token_here

# Polar Webhook Secret (from Step 4)
POLAR_WEBHOOK_SECRET=your_webhook_secret_here

# Polar Organization ID
POLAR_ORGANIZATION_ID=your_org_id

# Environment (sandbox or production)
POLAR_ENVIRONMENT=sandbox  # Use 'production' for live

# Polar Product IDs (client-side, for display)
NEXT_PUBLIC_POLAR_PRODUCT_STARTER_MONTHLY=prod_starter_monthly_id
NEXT_PUBLIC_POLAR_PRODUCT_PRO_MONTHLY=prod_pro_monthly_id
NEXT_PUBLIC_POLAR_PRODUCT_ENTERPRISE_MONTHLY=prod_enterprise_monthly_id
Polar currently focuses on monthly billing. If you need yearly billing, create separate products for annual plans.

Step 4: Set Up Webhooks

Polar sends webhooks to notify your application about subscription and payment events.

For Local Development

Use a tool like ngrok to expose your local server:
  1. Install ngrok:
    # macOS
    brew install ngrok/ngrok/ngrok
    
    # Or download from https://ngrok.com/download
    
  2. Start your development server:
    bun dev
    
  3. In another terminal, start ngrok:
    ngrok http 3000
    
  4. Copy the HTTPS forwarding URL (e.g., https://abc123.ngrok.io)
  5. In Polar dashboard, go to SettingsWebhooks
  6. Add webhook endpoint:
    • URL: https://abc123.ngrok.io/api/webhooks/payments
    • Events: Select all subscription and payment events
  7. Save the webhook secret to your .env

For Production

  1. Go to SettingsWebhooks in Polar dashboard
  2. Click Add Endpoint
  3. Set the endpoint URL: https://yourdomain.com/api/webhooks/payments
  4. Select events to listen for:
    • subscription.created
    • subscription.updated
    • subscription.canceled
    • order.paid
    • customer.created
    • customer.updated
  5. Click Create
  6. Copy the Webhook Secret and add it to your production environment variables

Testing in Development

Sandbox Mode

Polar provides a sandbox environment for testing. Set POLAR_ENVIRONMENT=sandbox in your .env.

Test Checkout Flow

  1. Start your development server and ngrok:
    bun dev
    # In another terminal:
    ngrok http 3000
    
  2. Configure webhook URL in Polar dashboard with your ngrok URL
  3. Navigate to your pricing page
  4. Click on a plan to create a checkout session
  5. Complete the checkout in sandbox mode
  6. Verify webhook events are received in your application logs

Testing Subscriptions

Polar provides test mode for subscriptions:
import { getPaymentAdapter } from '@/lib/payments/service'

const adapter = getPaymentAdapter()

// Create a checkout session
const checkout = await adapter.createCheckout({
  plan: 'pro',
  userId: 'user_123',
  email: 'test@example.com',
  successUrl: 'http://localhost:3000/dashboard?checkout=success',
  cancelUrl: 'http://localhost:3000/pricing',
})

// Redirect to checkout.url
console.log('Checkout URL:', checkout.url)

Polar Implementation Details

The Polar adapter is implemented in src/lib/payments/providers/polar.ts.

Key Features

Checkout Sessions

Creates Polar checkout sessions with:
  • Product-based pricing
  • Customer metadata (userId, plan)
  • Trial periods (if configured)
  • Custom success URLs
async createCheckout(options: CheckoutOptions): Promise<CheckoutResult> {
  const checkout = await this.polar.checkouts.create({
    products: [price.productId],
    successUrl: successUrl || paymentConfig.providers.successUrl,
    customerEmail: email,
    customerMetadata: {
      userId,
      plan,
      provider: 'polar',
    },
    ...(trialDays && trialDays > 0 && price.type === 'recurring' && {
      subscriptionTrialDays: trialDays,
    }),
  })

  return {
    url: checkout.url,
    sessionId: checkout.id,
  }
}

Customer Management

Polar creates customers automatically during checkout. The adapter handles:
  • Customer creation during checkout flow
  • Linking customers to user records
  • Storing customer metadata
Unlike Stripe, Polar doesn’t require explicit customer creation before checkout. Customers are created automatically when they complete a purchase.

Subscription Handling

The adapter provides:
  • Subscription retrieval by ID
  • Status mapping to unified status format
  • Support for cancellation at period end
async getSubscription(providerSubscriptionId: string): Promise<SubscriptionData | null> {
  const subscription = await this.polar.subscriptions.get({
    id: providerSubscriptionId,
  })

  return {
    id: `polar_${subscription.id}`,
    providerSubscriptionId: subscription.id,
    status: this.mapPolarStatus(subscription.status),
    plan: this.mapProductToPlan(subscription.productId),
    interval: subscription.recurringInterval === 'month' ? 'month' : 'year',
    // ...
  }
}

Webhook Processing

The adapter processes these Polar webhook events:
  • customer.created, customer.updated
  • subscription.created, subscription.updated, subscription.canceled
  • order.paid
Webhook validation:
async validateWebhook(rawBody: string, signature: string): Promise<boolean> {
  if (!env.POLAR_WEBHOOK_SECRET) {
    throw new Error('POLAR_WEBHOOK_SECRET is required')
  }
  // Polar webhook signature validation
  // Implementation depends on Polar's signature format
  return true
}

Customer Portal

Polar provides a customer portal for managing subscriptions:
const portal = await adapter.createPortal(
  'polar_customer_id',
  'https://yourdomain.com/dashboard'
)
// Redirect to portal.url
Polar’s customer portal is different from Stripe’s. It’s hosted at polar.sh/customer/{customerId} and provides basic subscription management.

GitHub Integration

One of Polar’s unique features is GitHub integration. You can:
  1. Link products to GitHub repositories
  2. Grant repository access based on subscription
  3. Use GitHub Sponsors integration
  4. Display products on your GitHub README
To set up GitHub integration:
  1. Go to SettingsGitHub in Polar dashboard
  2. Connect your GitHub account
  3. Link repositories to products
  4. Configure access permissions

Going Live

Pre-Launch Checklist

  • Set POLAR_ENVIRONMENT=production
  • Update POLAR_ACCESS_TOKEN with production token
  • Create live products in Polar dashboard
  • Update environment variables with live product IDs
  • Configure production webhook endpoint
  • Set up webhook secret for production
  • Test complete checkout flow
  • Verify GitHub integration (if applicable)

Security Best Practices

  1. Protect access tokens: Keep POLAR_ACCESS_TOKEN server-side only
  2. Validate webhooks: Always verify webhook signatures
  3. Use HTTPS: Polar requires HTTPS for production webhooks
  4. Handle errors: Don’t expose API errors to users
  5. Monitor webhooks: Check webhook logs regularly

Troubleshooting

Webhook Not Received

  1. Verify ngrok is running (for local dev)
  2. Check webhook endpoint is accessible (test with curl)
  3. Review webhook logs in Polar dashboard
  4. Ensure POLAR_WEBHOOK_SECRET matches dashboard
  5. Check application logs for errors

Checkout Session Fails

  1. Verify POLAR_ACCESS_TOKEN is set correctly
  2. Check that product IDs exist in Polar dashboard
  3. Ensure products are active and published
  4. Review error logs for specific error messages
  5. Check network tab in browser dev tools

Subscription Not Found

  1. Ensure subscription was created successfully
  2. Verify subscription ID format
  3. Check that webhook was processed
  4. Review database for subscription records

GitHub Integration Issues

  1. Verify GitHub account is connected in Polar
  2. Check repository access permissions
  3. Ensure product is linked to correct repository
  4. Review GitHub app installation logs

Polar vs Other Providers

When to Choose Polar

Choose Polar if you:
  • Are selling developer tools or APIs
  • Want GitHub integration
  • Prefer a developer-first experience
  • Are building open-source monetization
  • Want simpler setup than Stripe
Avoid Polar if you:
  • Need extensive payment methods (credit cards, wallets, etc.)
  • Require advanced billing features (metered usage, complex pricing)
  • Need a merchant of record
  • Want maximum payment customization

Feature Comparison

FeaturePolarStripeLemon Squeezy
GitHub Integration
Developer Focus⚠️⚠️
Setup ComplexityLowHighMedium
FeesCompetitive2.9% + $0.305% + processing
Payment MethodsBasicExtensiveGood
Customer PortalBasicAdvancedGood
Tax HandlingManualManualAutomatic (MoR)

Additional Resources

Support

For Polar-specific issues: For ShipFree integration issues:
  • Check the source code in src/lib/payments/providers/polar.ts
  • Review webhook handling in src/app/api/webhooks/payments/route.ts

Build docs developers (and LLMs) love