Codapult
PreisePluginsDoku
Codapult

Das SaaS-Boilerplate für Macher

Produkt

  • Preise
  • Plugins
  • Dokumentation

Unternehmen

  • Kontakt
  • GitHub

Rechtliches

  • Datenschutzrichtlinie
  • Nutzungsbedingungen

© 2026 Codapult. Alle Rechte vorbehalten.

Alle Artikel

Getting Started

  • Introduction
  • Quick Start
  • Project Structure

Configuration

  • Environment Variables
  • App Configuration

Authentication

  • Authentication
  • OAuth Providers
  • Two-Factor & Passwordless
  • Enterprise SSO (SAML)

Database

  • Database
  • Migrations

Teams

  • Teams & Organizations
  • Permissions & RBAC

Payments

  • Payments & Billing
  • Stripe Setup
  • LemonSqueezy Setup
  • Polar Setup
  • Payment Webhooks

Api

  • API Layer
  • tRPC
  • GraphQL

Ai

  • AI Features

Email

  • Email
  • Email Templates

Infrastructure

  • Infrastructure
  • File Storage
  • Background Jobs

Ui

  • UI & Theming

I18n

  • Internationalization

Content Management

  • Content Management

Admin

  • Admin Panel

Security

  • Security

Monitoring

  • Analytics & Monitoring

Modules

  • Module Architecture

Plugins

  • Plugin System
  • AI Kit Plugin
  • CRM Plugin
  • Helpdesk Plugin
  • Email Marketing Plugin

Deployment

  • Deployment
  • Troubleshooting

Upgrading

  • Upgrading Codapult

Developer Tools

  • MCP Server
  • Testing
Payments

Payments & Billing

Configure subscription plans, add-ons, and payment providers for your SaaS.

Overview

Codapult uses the adapter pattern for payments — switch between Stripe, LemonSqueezy, and Polar by changing a single environment variable. No code changes required.

# .env.local
PAYMENT_PROVIDER="stripe"        # default
# PAYMENT_PROVIDER="lemonsqueezy"  # alternative
# PAYMENT_PROVIDER="polar"        # Merchant of Record with GitHub integration
ComponentLocation
Payment adaptersrc/lib/payments/
Plan definitionssrc/lib/payments/plans.ts
Pricing displaysrc/config/marketing.ts
Server actionssrc/lib/actions/billing.ts
Stripe webhookPOST /api/webhooks/stripe
LS webhookPOST /api/webhooks/lemonsqueezy
Polar webhookPOST /api/webhooks/polar

Subscription Management

Your end users manage subscriptions from Dashboard → Billing:

  • View current plan and usage
  • Upgrade or downgrade plans
  • Switch between monthly and yearly billing
  • Add or remove add-ons
  • Cancel subscription
  • Access the billing portal (Stripe Customer Portal / LemonSqueezy / Polar)
  • Download invoices

Plan Configuration

Plans are defined in src/lib/payments/plans.ts. Each plan specifies a name, price, interval, features, and limits:

export const plans = [
  {
    id: 'free',
    name: 'Free',
    price: { monthly: 0, yearly: 0 },
    features: ['1 project', '100 AI messages/month', 'Community support'],
  },
  {
    id: 'pro',
    name: 'Pro',
    price: { monthly: 19, yearly: 190 },
    features: ['Unlimited projects', '5k AI messages', 'Priority support'],
  },
  {
    id: 'enterprise',
    name: 'Enterprise',
    price: { monthly: 49, yearly: 490 },
    features: ['Everything in Pro', 'Unlimited AI', 'SSO', 'SLA', 'Custom domain'],
  },
] as const;

Update the pricing display for your marketing pages in src/config/marketing.ts.

Add-Ons

Add-ons are optional extras that extend a subscription. They are combined with the base plan in a single multi-line checkout session:

Add-OnDescription
Extra StorageAdditional storage per block
Priority SupportDedicated support channel
Custom DomainUse your own domain
White LabelRemove platform branding

Users select add-ons during checkout or add them later from the billing dashboard.

Seat-Based Pricing

Plans support per-seat pricing. Seats are automatically synced with organization members — when a new member joins, the seat count updates. Admins can set a max seat cap to control costs.

Usage-Based Billing

Plans can include tiered usage pricing for metered features like AI messages or API calls. When users exceed their plan's included quota, overage is billed at the configured rate.

The usage estimator on the pricing page helps your end users predict monthly costs based on expected usage.

Usage Credits

Set a default monthly credit allowance with the DEFAULT_MONTHLY_CREDITS environment variable (accessed as env.defaultMonthlyCredits in server code). Credits reset automatically via a built-in cron job at the start of each billing cycle.

Stripe Connect

Codapult includes Stripe Connect support for marketplace features. Your platform can collect an application fee on transactions processed through connected accounts.

NEXT_PUBLIC_STRIPE_CONNECT_FEE_PERCENT=10  # 10% platform fee (overrides appConfig.payments.stripeConnectFeePercent)

You can also set the display value in src/config/app.ts under appConfig.payments.stripeConnectFeePercent. The server-side fee used in src/lib/payments/connect.ts is read from the env var via env.stripeConnectFeePercent.

Marketing / Showcase Checkout

When running in showcase mode (AUTH_PROVIDER=none) you can offer checkout without user authentication. There are two approaches — pick one per product or mix them:

Option 1: Direct checkout URL

Set CHECKOUT_URL_* env vars to link CTA buttons directly to an external checkout page (LemonSqueezy store, Gumroad, etc.):

CHECKOUT_URL_STARTER="https://your-store.lemonsqueezy.com/buy/starter"
CHECKOUT_URL_PRO="https://your-store.lemonsqueezy.com/buy/pro"

Option 2: API checkout (provider-agnostic)

Set CHECKOUT_VARIANT_* env vars with provider-specific variant/price IDs. CTA buttons will point to /api/checkout?product=<key>, which creates a checkout session via the active PAYMENT_PROVIDER adapter and redirects the visitor to the provider-hosted payment page:

PAYMENT_PROVIDER="stripe"
CHECKOUT_VARIANT_STARTER="price_abc123"
CHECKOUT_VARIANT_PRO="price_def456"

This approach uses the createMarketingCheckout adapter method — Stripe, LemonSqueezy, and Polar are all supported. Switching providers only requires changing PAYMENT_PROVIDER and the variant IDs.

Priority chain

The checkoutHref() helper in src/config/marketing.ts resolves the CTA link with this priority:

  1. Direct URL (CHECKOUT_URL_*) — highest priority
  2. API checkout (CHECKOUT_VARIANT_*) → /api/checkout?product=<key>
  3. Fallback — /sign-up for tiers, /#plugins for plugins

Available product keys: starter, pro, enterprise, plugin-ai-kit, plugin-crm, plugin-helpdesk, plugin-email-marketing, plugin-bundle.

Webhooks

Payment providers notify your app of subscription events via webhooks. See the dedicated Payment Webhooks page for event handling, extending handlers, and local testing.

Server Actions

Billing mutations are handled by server actions in src/lib/actions/billing.ts:

createCheckout

Creates a payment checkout session and redirects the user to the provider's payment page.

// Used as a form action
<form action={createCheckout}>
  <input type="hidden" name="planId" value="pro" />
  <input type="hidden" name="interval" value="monthly" />
  <input type="hidden" name="seats" value="5" />
  <button type="submit">Subscribe</button>
</form>

openCustomerPortal

Redirects the user to the provider's billing portal where they can update payment methods, view invoices, and manage their subscription.

<form action={openCustomerPortal}>
  <button type="submit">Manage Billing</button>
</form>

Provider Setup

See the dedicated setup guide for your chosen provider:

  • Stripe Setup — API keys, test mode, Stripe Connect, going-live checklist
  • LemonSqueezy Setup — API key, store ID, differences from Stripe
  • Polar Setup — access token, webhook setup, Merchant of Record with GitHub integration

Module Removal

The payments module is independently removable. See the Modules documentation for step-by-step removal instructions.

Next Steps

  • Payment Webhooks — event handling, extending, local testing
  • Teams & Organizations — seat-based billing tied to team members
  • Database — schema conventions for billing tables
Permissions & RBACStripe Setup