Polar Setup

Configure Polar as your billing provider

This guide walks you through setting up Polar as your billing provider. Polar is a developer-focused, merchant of record billing platform that provides a simple and easy-to-use API for managing subscriptions and payments.

Important: Organization Billing Limitations

Polar does not support true per-organization customers the way Stripe does. In Makerkit:

  • Organization billing UI can still be shown (via referenceId = organization.id)
  • But customer context is user-centric and organization “customerId” is not available
  • The customer portal is effectively user-level, not organization-level

If you need strict B2B billing with a dedicated customer per organization, use Stripe.

Prerequisites

  • A Polar account (sign up at polar.sh)
  • Access to your project's .env file

Step 1: Enable Polar Provider

Set Polar as your billing provider in .env:

NEXT_PUBLIC_BILLING_PROVIDER=polar

Also ensure you have:

# Used for server-side return URLs in billing actions
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Step 2: Get Your Access Token

  1. Log in to your Polar Dashboard
  2. Navigate to SettingsDevelopersPersonal Access Tokens
  3. Click Create Token
  4. Give it a name and select appropriate scopes
  5. Copy the generated access token

Add to your .env:

POLAR_ACCESS_TOKEN=polar_at_...your_access_token

We recommend enabling the following access scopes:

  • benefits:read
  • checkouts:read
  • checkout:write
  • customer_seats:read
  • customer_portal:read
  • customer_portal:write
  • customer_sessions:write
  • subscriptions:read
  • subscriptions:write
  • customers:read
  • customers:write
  • meters:read
  • meters:write

You may want to add additional access scopes depending on your needs. For example, if you need to read/write orders, you can add the orders:read and orders:write scopes.

Step 3: Configure Environment

Set the environment mode:

# For development/testing
POLAR_ENVIRONMENT=sandbox
# For production
POLAR_ENVIRONMENT=production

The default is sandbox if not specified.

Step 4: Create Products

Using Polar Dashboard

  1. Navigate to Products in your Polar dashboard
  2. Click Create Product
  3. Configure your product:
  • Name: Set the name and description
  • Pricing: Choose pricing (subscription or one-time)
  • Billing Interval: Set billing interval (monthly/yearly)
  • Trial Period: Set the trial period (optional)
  • Meters: Optionally, add metered usage:
    • Example: "requests": $0.10 per 1,000 requests
  • Benefits: Optionally, add benefits
    • Example: "core-features", "email-support", "priority-support"
  1. Copy each Product ID

Example Product Setup

Starter Product

  • Monthly: prod_starter_monthly ($9.99/month)
  • Yearly: prod_starter_yearly ($99.99/year)

Pro Product

  • Monthly: prod_pro_monthly ($19.99/month)
  • Yearly: prod_pro_yearly ($199.99/year)

Configure Product IDs

Add your Product IDs to .env:

POLAR_PRODUCT_STARTER_MONTHLY=prod_...
POLAR_PRODUCT_STARTER_YEARLY=prod_...
POLAR_PRODUCT_PRO_MONTHLY=prod_...
POLAR_PRODUCT_PRO_YEARLY=prod_...

Free Trial

In Polar, please specify the free trial during the product setup, not the configuration.

Step 5: Configure Billing Plans

Update your billing configuration to include the details of your products:

import { BillingConfig } from '@kit/billing';
export const billingConfig: BillingConfig = {
products: [
{
id: 'starter',
name: 'Starter',
description: 'For individuals and small teams',
currency: 'USD',
features: ['Core features', 'Email support'],
plans: [
{
name: 'starter-monthly',
planId: process.env.POLAR_PRODUCT_STARTER_MONTHLY!,
displayName: 'Starter Monthly',
interval: 'month',
cost: 9.99,
},
],
},
],
};

Step 6: Configure Webhooks

Webhooks are optional. Enable them if you want server-side lifecycle hooks (e.g. logging, analytics, provisioning) to run in response to Polar events.

Production Webhooks

  1. In Polar Dashboard, navigate to SettingsWebhooks
  2. Click Add Webhook
  3. Set endpoint URL: https://yourdomain.com/api/auth/polar/webhook
  4. Select events to listen for:
    • subscription.created
    • subscription.updated
    • subscription.canceled
    • order.paid
  5. Copy the webhook signing secret

Add to your .env:

POLAR_WEBHOOK_SECRET=whsec_...

NB; for local development, you can use a tunneling service like ngrok to expose your local server to the internet and receive these events on your local machine.

Local Development

For local testing, use a tunneling service like ngrok or Localtunnel.

# Start ngrok
ngrok http 3000
# Copy the https URL and configure it in Polar webhook settings
# Example: https://abc123.ngrok.io/api/auth/polar/webhook

Once started the proxy to your local server will be available at a URL like https://abc123.ngrok.io, you must use this URL in the Polar webhook settings.

Step 7: Test the Integration

Test Checkout

  1. Run the development server: pnpm dev
  2. Navigate to /settings/billing
  3. Select a plan and proceed to checkout
  4. Complete the checkout flow on Polar

Verify Webhooks

Monitor your server logs to verify webhook events are being received and processed.

Environment Variables Reference

Complete .env configuration for Polar:

# Billing Provider
NEXT_PUBLIC_BILLING_PROVIDER=polar
# Polar Configuration
POLAR_ACCESS_TOKEN=polar_at_...
POLAR_ENVIRONMENT=sandbox # or 'production'
POLAR_WEBHOOK_SECRET=whsec_...
# Optional behavior toggle (default shown)
CREATE_CUSTOMER_ON_SIGN_UP=true
# Product IDs (from Polar Dashboard)
POLAR_PRODUCT_STARTER_MONTHLY=prod_...
POLAR_PRODUCT_STARTER_YEARLY=prod_...
POLAR_PRODUCT_PRO_MONTHLY=prod_...
POLAR_PRODUCT_PRO_YEARLY=prod_...
# Application URL (for redirects)
NEXT_PUBLIC_SITE_URL=http://localhost:3000

Provider Capabilities

Polar supports the following features:

FeatureSupportedNotes
CheckoutYesVia Better Auth API
Customer PortalYesCustomers manage subscriptions here
Cancel (API)NoUse portal for cancellation
Restore (API)NoUse portal for restoration
BenefitsYesProvider feature; not mapped to BillingClient entitlements in Makerkit
Usage MetersYesEvent-based metering
OrganizationsLimitedNo organization customer context; prefer Stripe for B2B billing

Cancel/Restore/Upgrade/Downgrade via Customer Portal

Customers can use the Polar customer portal to manage their subscriptions

Production Checklist

Before going live:

  • [ ] Switch POLAR_ENVIRONMENT to production
  • [ ] Configure production webhook endpoint
  • [ ] Test all webhook events in production
  • [ ] Verify product IDs are correct and match your billing configuration
  • [ ] Set up billing email notifications in Polar

Troubleshooting

Webhook Signature Verification Failed

Check that your POLAR_WEBHOOK_SECRET matches the webhook in Polar Dashboard.

Customer Not Created

Ensure the plugin is configured with createCustomerOnSignUp: true (default).

Product ID Not Found

Verify Product IDs exist in Polar Dashboard and match your billing configuration.

Environment Mismatch

Ensure POLAR_ENVIRONMENT matches your Polar account mode (sandbox vs production).

Lifecycle Hooks

Polar-specific hooks are available in packages/billing/polar/src/hooks/:

HookWhen it's called
onSubscriptionCreatedNew subscription created
onSubscriptionUpdatedSubscription changes
onSubscriptionCanceledSubscription canceled
onOrderPaidOrder payment completed
onCustomerCreatedCustomer record created
onCustomerStateChangedCustomer state changes

See Lifecycle Hooks for implementation details.

Next Steps

  • Configure your billing plans
  • Implement subscription management UI
  • Set up lifecycle hooks for subscription events