Billing (Polar)
Polar integration, subscriptions, and billing flows. This is the pack-billing-polar pack, one of the three variants in
the billing family. Like Lemon Squeezy, Polar is a merchant of record and handles tax for you, and it ships a full
sandbox environment for development.
The product shape is the same as Billing (Stripe): a billing page with plan cards, a hosted checkout, a customer portal, signature-verified webhooks, and the admin revenue widgets.
What you need
- A Polar organization. Sign up at polar.sh, and use sandbox.polar.sh while developing.
- Two subscription products (Pro and Premier in the pack's schema).
- Postgres and Valkey (subscription status is cached in Valkey, keyed by organization).
- Optionally Resend for receipt emails.
Credentials
From the Polar dashboard, grab:
- An organization access token (
POLAR_ACCESS_TOKEN) from Settings > Developers. - The product ids of the two plans (
POLAR_PRODUCT_PRO,POLAR_PRODUCT_PREMIER). - A webhook secret (
POLAR_WEBHOOK_SECRET), generated when you add the endpoint below.
Sandbox and production are separate organizations with separate tokens and product ids. Set POLAR_SERVER=sandbox
locally and leave it unset in production.
Webhook endpoint
The pack exposes the receiver at:
POST /checkout/webhookIn Settings > Webhooks, add an endpoint pointing at https://your-api-origin/checkout/webhook and subscribe to the
subscription.* and order.* events (created, updated, active, past due, canceled, uncanceled, revoked, and order
paid). Copy the generated secret into POLAR_WEBHOOK_SECRET.
For development, expose your backend through a tunnel and register that URL on the sandbox organization.
Environment variables
| Variable | Purpose |
|---|---|
POLAR_ACCESS_TOKEN | Organization access token |
POLAR_WEBHOOK_SECRET | Secret for the webhook endpoint |
POLAR_SERVER | Optional. sandbox to talk to sandbox.polar.sh |
POLAR_PRODUCT_PRO | Product id for Pro |
POLAR_PRODUCT_PREMIER | Product id for Premier |
RESEND_API_KEY | Optional. Enables receipt emails |
In the admin
On top of a starter, this pack adds a revenue row to the admin app dashboard, a
billing card and revenue card on the organization details page, and /admin/billing API routes.
Switching providers
Billing is a family slot. compose --packs pack-billing-stripe swaps this pack for Stripe: shared files are replaced,
Polar-only files are removed, your own code is left alone. Existing customers need to be re-subscribed on the new
provider.
Related
- Billing (Stripe) for the shared checkout and portal flow
- Organizations for the tenant boundary billing attaches to
- Going to production for the webhook checklist
Every purchase and sponsorship funds my 8+ years of work on open source given freely to the community. It keeps the lights on, funds new packs, and keeps the ecosystem alive. Even a small tier means a lot. Thank you!
