Stripe vs Polar vs LemonSqueezy
Payment Processing Is Not a Commodity Decision
Choosing your payment provider is one of the highest-leverage decisions in a SaaS boilerplate. It affects:
- Your take-home rate — fees vary from 2.9% to 9%+ depending on the provider
- Geographic reach — not all providers serve all countries
- Tax compliance — merchant of record services handle VAT/sales tax; Stripe does not
- Developer experience — webhook handling, SDK quality, documentation
- Boilerplate compatibility — most boilerplates support Stripe; fewer support others
TL;DR
- Stripe: Use for most SaaS products. Maximum boilerplate support, best API, requires tax compliance work.
- LemonSqueezy: Use for B2C products selling internationally. Merchant of record handles taxes. 8% fee.
- Polar.sh: Use for open-source projects and developer tools. Usage-based billing, GitHub integration, generous free tier.
- Paddle: Similar to LemonSqueezy for B2B international sales. Enterprise-focused.
Key Takeaways
- Stripe has 2.9% + $0.30 base fee — the lowest transaction cost
- LemonSqueezy is 8% per transaction — more expensive but handles all sales tax globally
- Polar.sh has a 4% fee (with Stripe's 2.9%) — better for developer tools needing GitHub integration
- Merchant of record (LemonSqueezy, Paddle, Polar) handle EU VAT, US sales tax, and global tax compliance — Stripe does not
- If you sell to EU customers as a small SaaS, a merchant of record saves significant compliance work
- All major boilerplates (ShipFast, OpenSaaS, Makerkit) support Stripe; fewer support the alternatives
Stripe: The Default
Stripe is the payment infrastructure standard in 2026. Every major SaaS boilerplate includes Stripe. The API is excellent, the documentation is best-in-class, and Stripe's ecosystem (Radar for fraud, Billing for subscriptions, Meters for usage-based billing) is unmatched.
Stripe Setup in Next.js
npm install stripe @stripe/stripe-js
// lib/stripe.ts
import Stripe from 'stripe';
export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2025-10-28.acacia',
});
// Create a checkout session:
export async function createCheckoutSession({
priceId,
customerId,
userId,
successUrl,
cancelUrl,
}: {
priceId: string;
customerId?: string;
userId: string;
successUrl: string;
cancelUrl: string;
}) {
return stripe.checkout.sessions.create({
mode: 'subscription',
payment_method_types: ['card'],
customer: customerId,
line_items: [{ price: priceId, quantity: 1 }],
success_url: successUrl,
cancel_url: cancelUrl,
metadata: { userId },
allow_promotion_codes: true,
subscription_data: {
metadata: { userId },
},
});
}
// Customer portal (manage subscription):
export async function createPortalSession(customerId: string, returnUrl: string) {
return stripe.billingPortal.sessions.create({
customer: customerId,
return_url: returnUrl,
});
}
// app/api/webhooks/stripe/route.ts
import { stripe } from '@/lib/stripe';
import { headers } from 'next/headers';
export async function POST(req: Request) {
const body = await req.text();
const signature = headers().get('stripe-signature')!;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!
);
} catch (err) {
return new Response('Invalid signature', { status: 400 });
}
switch (event.type) {
case 'checkout.session.completed': {
const session = event.data.object;
const userId = session.metadata?.userId;
await db.user.update({
where: { id: userId },
data: {
stripeCustomerId: session.customer as string,
stripeSubscriptionId: session.subscription as string,
plan: 'pro',
},
});
break;
}
case 'customer.subscription.deleted': {
const sub = event.data.object;
await db.user.update({
where: { stripeSubscriptionId: sub.id },
data: { plan: 'free' },
});
break;
}
}
return new Response('OK');
}
Stripe Downsides
- No merchant of record — you handle EU VAT, US sales tax yourself
- Tax compliance for EU: use Stripe Tax ($0.50 per transaction) or use TaxJar/Avalara
- Stripe Tax is available but an add-on cost
LemonSqueezy: Merchant of Record
LemonSqueezy is a merchant of record — they handle all sales tax, VAT, and compliance globally. You sell through LemonSqueezy; they remit taxes in 100+ countries.
Fee: 8% + $0.50 per transaction (significantly higher than Stripe's 2.9%)
The 8% is worth paying when:
- You sell to EU customers (VAT compliance is complex)
- You are in a country with complex tax requirements
- You want to minimize accounting overhead
npm install @lemonsqueezy/lemonsqueezy.js
// lib/lemonsqueezy.ts
import { lemonSqueezySetup, createCheckout } from '@lemonsqueezy/lemonsqueezy.js';
lemonSqueezySetup({ apiKey: process.env.LEMONSQUEEZY_API_KEY! });
export async function createLemonCheckout({
variantId,
userId,
successUrl,
}: {
variantId: string;
userId: string;
successUrl: string;
}) {
const checkout = await createCheckout(
process.env.LEMONSQUEEZY_STORE_ID!,
variantId,
{
checkoutOptions: { embed: false },
checkoutData: {
custom: { userId },
},
productOptions: { redirectUrl: successUrl },
}
);
return checkout.data?.data.attributes.url;
}
// Webhook handler:
export async function POST(req: Request) {
const body = await req.text();
const secret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET!;
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(body).digest('hex');
const signature = req.headers.get('x-signature');
if (digest !== signature) return new Response('Invalid', { status: 401 });
const event = JSON.parse(body);
if (event.meta.event_name === 'subscription_created') {
const userId = event.meta.custom_data.userId;
await db.user.update({
where: { id: userId },
data: { plan: 'pro', lemonSqueezyCustomerId: event.data.attributes.customer_id },
});
}
}
Polar.sh: Developer Tools Billing
Polar.sh is designed for open-source maintainers and developer tools:
npm install @polar-sh/sdk
// lib/polar.ts
import { Polar } from '@polar-sh/sdk';
export const polar = new Polar({
accessToken: process.env.POLAR_ACCESS_TOKEN!,
});
// Create checkout for Polar:
export async function createPolarCheckout({
productPriceId,
userId,
successUrl,
}: {
productPriceId: string;
userId: string;
successUrl: string;
}) {
const checkout = await polar.checkouts.create({
productPriceId,
successUrl,
metadata: { userId },
});
return checkout.url;
}
Polar.sh unique features:
- GitHub Issues integration — link subscriptions to GitHub repositories
- Benefit system — automatically grant benefits (Discord roles, GitHub access) on subscription
- Usage-based billing — meter API calls or usage
- Free for open source — lower fees for OSS projects
Fee: 4% (Polar) + 2.9% (Stripe pass-through) = ~7% total
Comparison Table
| Feature | Stripe | LemonSqueezy | Polar.sh |
|---|---|---|---|
| Transaction fee | 2.9% + $0.30 | 8% + $0.50 | ~4% + Stripe |
| Merchant of record | No | Yes | Yes |
| Tax handling | Manual (or Stripe Tax) | Automatic | Automatic |
| Boilerplate support | Universal | Many | Growing |
| Usage-based billing | Yes (Meters) | Limited | Yes |
| Developer focus | Neutral | Neutral | Strong |
| GitHub integration | No | No | Yes |
| EU VAT compliance | Manual | Included | Included |
| Subscriptions | Excellent | Good | Good |
| API quality | Excellent | Good | Good |
Which Boilerplates Support What?
| Boilerplate | Stripe | LemonSqueezy | Polar.sh |
|---|---|---|---|
| ShipFast | Yes | Yes | No |
| OpenSaaS | Yes | Yes | Yes |
| Makerkit | Yes | Yes | No |
| SaaSBold | Yes | Yes | Yes (Paddle) |
| Supastarter | Yes | Yes | No |
| T3 Stack | Manual | Manual | Manual |
Decision Framework
Choose Stripe if:
→ US-focused B2B SaaS (fewer tax complications)
→ Need maximum boilerplate compatibility
→ Want usage-based billing (Stripe Meters)
→ Lowest transaction cost matters
Choose LemonSqueezy if:
→ B2C with global customers
→ EU market (VAT compliance)
→ Digital products / content
→ Tax headaches outweigh the fee premium
Choose Polar.sh if:
→ Open-source project monetization
→ Developer tool with GitHub integration
→ Want GitHub Issues linked to subscriptions
→ Community/supporter model
Use both Stripe + LemonSqueezy if:
→ Some plans are B2B (Stripe), some B2C (LemonSqueezy)
→ Complex billing needs different tools
Methodology
Based on publicly available pricing and documentation from Stripe, LemonSqueezy, Polar.sh, and boilerplate documentation as of March 2026.
Choosing payment infrastructure for your SaaS? StarterPick helps you find boilerplates pre-configured with the right payment provider for your market.