Skip to main content
Polar is another hosted checkout provider supported by the repo. If you have never worked with payments before, the key idea is simple: users pay on Polar’s checkout page, then Polar tells your app what happened through a webhook.

What You Are Setting Up

To make Polar work with this repo, you need:
  1. products inside Polar
  2. checkout links that your users can click
  3. a webhook endpoint that Polar can call
  4. a way for the repo to know what each product means

Required Env Vars

NEXT_PUBLIC_PAYMENT_PROVIDER=polar
NEXT_PUBLIC_CHECKOUT_URL_TEMPLATE=https://...
POLAR_WEBHOOK_SECRET=...
Optional UI checkout URLs:
NEXT_PUBLIC_CHECKOUT_URL_PREMIUM=https://...
NEXT_PUBLIC_CHECKOUT_URL_ENTERPRISE=https://...
NEXT_PUBLIC_CHECKOUT_URL_AGENCY=https://...
NEXT_PUBLIC_CHECKOUT_URL_CREDITS_SMALL=https://...
NEXT_PUBLIC_CHECKOUT_URL_CREDITS_LARGE=https://...
Optional product map:
POLAR_PRODUCT_MAP='{"prod_123":"anotherwrapper-enterprise","prod_456":"credits-small"}'

Step 1: Create Products In Polar

Start by creating the products you want to sell in Polar. For a first setup, keep it simple:
  • one Enterprise product
  • one Small credits product
Each Polar product will eventually need to map to one of the repo purchase types such as anotherwrapper-enterprise or credits-small. Once your products are ready, create the hosted checkout links in Polar. Then add them to .env.local, for example:
NEXT_PUBLIC_CHECKOUT_URL_ENTERPRISE=https://polar.sh/checkout/...
NEXT_PUBLIC_CHECKOUT_URL_CREDITS_SMALL=https://polar.sh/checkout/...
These are the links the app will use for payment buttons.

Step 3: Tell The Repo What Each Polar Product Means

You have two ways to do that.

Option A: Put type In Metadata

If your Polar order or product metadata includes something like:
type=anotherwrapper-enterprise
the repo can read that directly. This is the cleanest beginner-friendly setup because the payment already says what it is.

Option B: Use POLAR_PRODUCT_MAP

If you prefer to keep the mapping in env, use:
POLAR_PRODUCT_MAP='{"prod_123":"anotherwrapper-enterprise","prod_456":"credits-small"}'
This tells the repo which internal purchase type belongs to each Polar product.

Step 4: Add The Webhook In Polar

In Polar, add this webhook endpoint:
https://yourdomain.com/api/payments/polar
Then copy the webhook secret into:
POLAR_WEBHOOK_SECRET=...
If the webhook is not configured, checkout may succeed in Polar but your app will never know about it. That means credits will not be added and purchases will not be stored.

What Happens After A Successful Polar Payment

When Polar sends a successful webhook:
  1. the repo verifies the webhook signature
  2. it reads the purchase type from metadata or POLAR_PRODUCT_MAP
  3. it stores the purchase in the purchases table
  4. it tries to match the purchase to a user
  5. it updates credits or purchase state
If Polar includes an external customer ID, the repo can also use that to help match the payment back to the correct user profile.

Simple Example

Imagine you sell one credits pack in Polar. You might set:
NEXT_PUBLIC_PAYMENT_PROVIDER=polar
NEXT_PUBLIC_CHECKOUT_URL_CREDITS_SMALL=https://polar.sh/checkout/...
POLAR_WEBHOOK_SECRET=...
POLAR_PRODUCT_MAP='{"prod_credits_small":"credits-small"}'
Now when a user buys that product:
  • the checkout button sends them to Polar
  • Polar charges them
  • Polar calls your webhook
  • the repo recognizes credits-small
  • the repo adds the correct number of credits

Verification Checklist

Your Polar setup is working if:
  • the app opens the Polar checkout page
  • Polar shows a successful webhook delivery
  • a row appears in purchases
  • a credits purchase increases the user’s credits
  • a plan purchase updates the user’s access state

Common Polar Mistakes

  • creating the product but not saving the checkout URL in env
  • configuring checkout but not configuring the webhook
  • forgetting to map the Polar product to a valid purchase type
  • changing env vars without restarting the app
  • testing with the wrong domain in the webhook URL

Payments Overview

Go back to the shared payment fundamentals and repo-wide setup.