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
.envfile
Step 1: Enable Polar Provider
Set Polar as your billing provider in .env:
NEXT_PUBLIC_BILLING_PROVIDER=polarAlso ensure you have:
# Used for server-side return URLs in billing actionsNEXT_PUBLIC_SITE_URL=http://localhost:3000Step 2: Get Your Access Token
- Log in to your Polar Dashboard
- Navigate to Settings → Developers → Personal Access Tokens
- Click Create Token
- Give it a name and select appropriate scopes
- Copy the generated access token
Add to your .env:
POLAR_ACCESS_TOKEN=polar_at_...your_access_tokenWe recommend enabling the following access scopes:
benefits:readcheckouts:readcheckout:writecustomer_seats:readcustomer_portal:readcustomer_portal:writecustomer_sessions:writesubscriptions:readsubscriptions:writecustomers:readcustomers:writemeters:readmeters: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/testingPOLAR_ENVIRONMENT=sandbox# For productionPOLAR_ENVIRONMENT=productionThe default is sandbox if not specified.
Step 4: Create Products
Using Polar Dashboard
- Navigate to Products in your Polar dashboard
- Click Create Product
- 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"
- 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
- In Polar Dashboard, navigate to Settings → Webhooks
- Click Add Webhook
- Set endpoint URL:
https://yourdomain.com/api/auth/polar/webhook - Select events to listen for:
subscription.createdsubscription.updatedsubscription.canceledorder.paid
- 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 ngrokngrok http 3000# Copy the https URL and configure it in Polar webhook settings# Example: https://abc123.ngrok.io/api/auth/polar/webhookOnce 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
- Run the development server:
pnpm dev - Navigate to
/settings/billing - Select a plan and proceed to checkout
- 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 ProviderNEXT_PUBLIC_BILLING_PROVIDER=polar# Polar ConfigurationPOLAR_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:3000Provider Capabilities
Polar supports the following features:
| Feature | Supported | Notes |
|---|---|---|
| Checkout | Yes | Via Better Auth API |
| Customer Portal | Yes | Customers manage subscriptions here |
| Cancel (API) | No | Use portal for cancellation |
| Restore (API) | No | Use portal for restoration |
| Benefits | Yes | Provider feature; not mapped to BillingClient entitlements in Makerkit |
| Usage Meters | Yes | Event-based metering |
| Organizations | Limited | No 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_ENVIRONMENTtoproduction - [ ] 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/:
| Hook | When it's called |
|---|---|
onSubscriptionCreated | New subscription created |
onSubscriptionUpdated | Subscription changes |
onSubscriptionCanceled | Subscription canceled |
onOrderPaid | Order payment completed |
onCustomerCreated | Customer record created |
onCustomerStateChanged | Customer 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