payments · side by side
Stripe vs Polar for a Next.js app
Both fill the payments slot, so a generated repo carries one or the other, never both. Every line below is read out of the two manifests.
Short answer
Pick Stripe if
SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept.
Pick Polar if
Solo founders and small teams selling digital products or SaaS worldwide, by subscription or as a one-time lifetime deal. You skip registering for VAT, GST and US sales tax before your twentieth customer.
Side by side
Price, obligations, and the surface each one adds. No row is written by hand. This is manifest.yaml, rendered.
| From the manifest | Option AStripe | Option BPolar |
|---|---|---|
| In one line | Stripe Hosted Checkout, a customer portal you never build, and webhooks you test locally. | Polar Merchant of record for developers. Polar sells to your customer, so tax is its job. |
| Pricing | Stripe 2.9% + 30c per successful US card charge. No setup or monthly fee. Stripe Billing adds 0.7% of billing volume. Stripe Tax is extra, charged per transaction where you are registered to collect. | Polar Free Starter plan at 5% + 50c per transaction. Paid plans lower the rate: Pro is $20/month at 3.8% + 40c, and Growth and Scale go lower. Non-US cards add 1.5%. Tax calculation, filing and liability are included. Organisations created before May 27, 2026 can stay on the Early Member plan: 4% + 40c, plus 0.5% on subscriptions. |
| Best for | Stripe SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept. | Polar Solo founders and small teams selling digital products or SaaS worldwide, by subscription or as a one-time lifetime deal. You skip registering for VAT, GST and US sales tax before your twentieth customer. |
| Trade-offsVerbatim from the manifest | Stripe
| Polar
|
| Required companionsAdded for you, with a reason | Stripe
| Polar
|
| Recommended alongsideSuggested, never added for you | Stripe
| Polar
|
| Env vars you will manageEvery one documented in docs/onboard.md | Stripe 9 variables · 3 required
| Polar 9 variables · 3 required
|
| Dependencies added | Stripe
| Polar
|
| MCP serversWritten into .mcp.json | Stripe
| Polar
|
| Footprint in your repo | Stripe 10 files, plus 3 injections into shared stack files | Polar 12 files, plus 3 injections into shared stack files |
What changes in your repo
The paths each battery contributes, diffed. A path in the third list is written by both, so swapping rewrites that file rather than adding one.
Only with Stripe (5)
src/5 files
app/1 file
api/1 file
webhooks/1 file
stripe/1 file
- route.ts
lib/4 files
billing/4 files
- stripe-objects.test.ts
- stripe-objects.ts
- stripe-provider.test.ts
- stripe.ts
Only with Polar (7)
scripts/1 file
billing/1 file
- test-webhook.ts
src/6 files
app/1 file
api/1 file
webhooks/1 file
polar/1 file
- route.ts
lib/5 files
billing/5 files
- polar-objects.test.ts
- polar-objects.ts
- polar-webhooks.test.ts
- polar-webhooks.ts
- polar.ts
Same path, different implementation (5)
scripts/3 files
billing/3 files
- prune-events.ts
- reconcile.ts
- sync-plans.ts
src/1 file
lib/1 file
billing/1 file
- provider.ts
tests/1 file
e2e/1 file
- billing-webhook.spec.ts
Shared stack files Stripe injects into
- env-required
- legal-processors
- verify-checks
Shared stack files Polar injects into
- env-required
- legal-processors
- verify-checks
Stripe in your .env.local
# required
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_replace_me
STRIPE_SECRET_KEY=sk_test_replace_me
STRIPE_WEBHOOK_SECRET=whsec_replace_me
# optional
BILLING_PRICE_PRO_LIFETIME=
BILLING_PRICE_PRO_MONTHLY=
BILLING_PRICE_PRO_YEARLY=
BILLING_PRICE_TEAM_MONTHLY=
BILLING_PRICE_TEAM_YEARLY=
STRIPE_AUTOMATIC_TAX=false
Polar in your .env.local
# required
POLAR_ACCESS_TOKEN=polar_oat_replace_me
POLAR_ORGANIZATION_ID=00000000-0000-0000-0000-000000000000
POLAR_WEBHOOK_SECRET=whsec_replace_me
# optional
BILLING_PRICE_PRO_LIFETIME=
BILLING_PRICE_PRO_MONTHLY=
BILLING_PRICE_PRO_YEARLY=
BILLING_PRICE_TEAM_MONTHLY=
BILLING_PRICE_TEAM_YEARLY=
POLAR_ENVIRONMENT=sandbox
What changes for your agents
Each battery ships rules, skills, subagents and hooks that an agent loads before it touches the code that battery owns. Picking one is also picking how your agents behave in src/lib/billing/**.
Stripe
2
Skills
4
Rules
6
Solution docs
1
MCP servers
Rules (4)
Stripe translates, the shared billing core writes the store
src/lib/billing/** · scripts/billing/**
Plans live in pricing.ts, Stripe ids live in env, amounts never come from the client
src/lib/pricing.ts · src/lib/billing/** · scripts/billing/**
Stripe objects are server-only
src/lib/billing/** · src/app/api/webhooks/stripe/** · src/app/**
Verify every Stripe webhook, keep every handler idempotent
src/app/api/webhooks/stripe/** · src/lib/billing/provider.ts · src/lib/billing/webhook.ts
Skills (2)
/add-plan
Add or change a plan or price on Stripe (monthly, yearly or one-time lifetime). Edit src/lib/pricing.ts, create the Stripe price, wire its env var, and prove checkout and the webhook end to end.
/test-webhook
Exercise the Stripe webhook endpoint locally. Forward real events with the CLI, buy a subscription and a one-time price, refund one, assert idempotency, and debug signature failures.
Subagents and hooks
None of its own. The foundation agents and guard hooks still ship.
Polar
2
Skills
2
Rules
6
Solution docs
1
MCP servers
Rules (2)
Polar translates, the shared billing core writes the store
src/lib/pricing.ts · src/lib/billing/** · scripts/billing/**
Verify every Polar webhook, keep every handler idempotent
src/app/api/webhooks/polar/** · src/lib/billing/provider.ts · src/lib/billing/polar-webhooks.ts · src/lib/billing/webhook.ts
Skills (2)
/add-product
Add or change a plan or price on Polar (monthly, yearly or one-time lifetime). Edit src/lib/pricing.ts, create the Polar product, wire its env var, and prove checkout and the webhook end to end.
/test-webhook
Exercise the Polar webhook endpoint locally. Forward real sandbox events with the Polar CLI, or sign a one-time order yourself; buy both kinds of price, refund one, prove replays are no-ops, and debug signature failures.
Subagents and hooks
None of its own. The foundation agents and guard hooks still ship.
What each one already knows
Solution docs land in docs/solutions/ in your repo and are published here, so you can read the failure modes before you commit.
Polar (6)
- Merchant of record explained, what Polar takes on that Stripe leaves with youWith Stripe you are the seller and you owe VAT, GST and US sales tax yourself. Polar sells on your behalf and carries that liability. What actually changes, what it costs, and how little of it reaches your code.docs/solutions/polar/merchant-of-record-vs-stripe.md
- Moving from Stripe to Polar without breaking existing customersYou cannot transfer live Stripe subscriptions to Polar. Sell new customers on Polar, keep Stripe's webhook alive for the ones you have, move them at renewal, and let the provider-neutral billing rows carry access through the whole overlap.docs/solutions/polar/migrate-a-stripe-catalogue-to-polar.md
- One-time and subscription products on Polar, from lifetime deal to renewalPolar sells one price per product, so a plan sold monthly, yearly and for life is three products. How each kind checks out, which webhook proves it was paid, where it is stored, and how access resolves when a customer holds both.docs/solutions/polar/one-time-and-subscription-products-on-polar.md
- Refunds and disputes on Polar, and taking access back exactly onceA refund arrives as order.refunded with the whole order. A dispute arrives as nothing at all. How this repo revokes a lifetime deal in both cases, why partial refunds keep access, and why a late paid delivery cannot give it back.docs/solutions/polar/refunds-and-disputes-on-polar.md
- Polar sandbox to production, the checklist that stops launch-day silenceSandbox and production are separate Polar deployments with separate tokens, product ids and webhook secrets. Nothing carries over. Everything that has to be recreated, in order, and how to prove it worked.docs/solutions/polar/sandbox-to-production-checklist.md
- Polar webhooks arrive twice and sign two ways, make the handler survive bothAt-least-once delivery means duplicates and out-of-order events are normal traffic, and Polar changed its signing key format in September 2026. Verify with both keys, claim the webhook-id before any write, re-read subscriptions and let orders only move forward.docs/solutions/polar/webhook-idempotency.md
Stripe (6)
- Free trials in Stripe that do not leak accesstrialing is an entitled status and trial_will_end is not a payment. Where trials are configured, which events actually matter, and how to stop one person taking ten trials.docs/solutions/stripe/free-trials-that-do-not-leak.md
- Idempotent Stripe webhooks, or claim the event id before you do the workStripe delivers at least once, retries for three days and arrives out of order. An event ledger claimed before the handler runs is what stops double grants and lost updates.docs/solutions/stripe/idempotent-stripe-webhooks.md
- One-time payments with Stripe Checkout, from lifetime deal to refundA lifetime deal is a payment-mode Checkout Session, not a subscription. Which id to key it on, when it is really paid, how a receipt goes out, and how a refund or dispute takes the access back.docs/solutions/stripe/one-time-payments-with-stripe-checkout.md
- Proration when a customer changes plan, and why you should let the portal do itUpgrades, downgrades and seat changes each want different proration behaviour. What Stripe actually does, how to preview the amount, and when to build the flow yourself.docs/solutions/stripe/proration-when-plans-change.md
- Reconciling after a missed Stripe webhookA customer paid and the app does not know. How to find the gap, replay or re-sync the affected subscriptions and one-time purchases, and build a reconciliation job so the next outage is boring.docs/solutions/stripe/reconciling-a-missed-webhook.md
- Stripe Tax, and when you legally need to careWith Stripe you are the merchant of record, so sales tax and VAT are your liability. What Stripe Tax does and does not do, the thresholds that trigger obligations, and when a merchant of record is the better answer.docs/solutions/stripe/stripe-tax-and-when-you-need-it.md
Which one to pick
From meta.bestFor and meta.tradeoffs. If a claim is not in the manifest, it is not on this page.
Pick Stripe when
SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept.
And accept that(5)
- You are the merchant of record. You owe sales tax, VAT and GST yourself. Stripe Tax calculates and files, but the liability is yours. Merchant-of-record vendors (Polar, Dodo, Lemon Squeezy) take that liability, at a higher rate.
- Webhooks are mandatory. Every subscription change reaches you asynchronously, at least once and out of order. Skip idempotency and you will double-grant entitlements in production.
- Stripe is not available in every country, and some business types are not allowed. Check both before you build.
- The API is deeper than you need on day one. The failure mode is over-modelling billing before you have ten paying customers.
- The Stripe CLI's
stripe listenforwards real webhooks to localhost, so you test the full loop before you deploy.
Pick Polar when
Solo founders and small teams selling digital products or SaaS worldwide, by subscription or as a one-time lifetime deal. You skip registering for VAT, GST and US sales tax before your twentieth customer.
And accept that(6)
- Polar is the seller on the customer's statement and invoice. That is the point: the tax liability moves to Polar. It also means the descriptor is not your brand, and enterprise buyers sometimes ask why.
- Payouts arrive on Polar's schedule, after it has collected and remitted. Plan your runway on that, especially in the first month.
- The fee is higher than a direct card processor because tax is included. At high volume, compare it with a processor plus a tax vendor.
- One product is one price. A plan sold monthly, yearly and for life is three Polar products and three env ids.
billing:sync-planscreates them for you. - Sandbox and production are separate Polar deployments with separate tokens, products and webhook secrets. Launch day is a second setup, not a switch.
- Fewer billing knobs than Stripe. For a plain subscription or a lifetime deal that is often enough.
Questions people actually ask
- Should I choose Stripe or Polar?
- Stripe is best for SaaS selling to businesses and consumers in many countries. Best when you need real invoices, dunning, proration and a tax story your accountant will accept. Polar is best for solo founders and small teams selling digital products or SaaS worldwide, by subscription or as a one-time lifetime deal. You skip registering for VAT, GST and US sales tax before your twentieth customer. Both fill the payments slot, so a generated repo carries one or the other, never both.
- How much do Stripe and Polar cost?
- Stripe: 2.9% + 30c per successful US card charge. No setup or monthly fee. Stripe Billing adds 0.7% of billing volume. Stripe Tax is extra, charged per transaction where you are registered to collect. Polar: Free Starter plan at 5% + 50c per transaction. Paid plans lower the rate: Pro is $20/month at 3.8% + 40c, and Growth and Scale go lower. Non-US cards add 1.5%. Tax calculation, filing and liability are included. Organisations created before May 27, 2026 can stay on the Early Member plan: 4% + 40c, plus 0.5% on subscriptions.
- What changes in my repo if I switch from Stripe to Polar?
- Stripe writes 10 files, 9 environment variables and 2 dependencies, and installs 4 path-scoped rules, 2 skills and 6 solution docs. Polar writes 12 files, 9 environment variables and 2 dependencies, and installs 2 path-scoped rules, 2 skills and 6 solution docs.
Decide once, then build the repo that already knows the decision.
Either way you get that choice’s rules, skills and solution docs installed, plus the guard hooks, an onboarding doc for exactly these env vars, and the Compound Engineering loop. Free and MIT.