Skip to main content

Payments Config

Pick your payment provider — Stripe, Lemon Squeezy, Paddle, or free-only — and toggle test mode in config/payments.config.ts.

File: config/payments.config.ts

This file decides who processes money. The pricing tiers themselves live in Plans Config; this file just routes them through a provider.

config/payments.config.ts
export const paymentsConfig: PaymentsConfig = {
  provider: 'stripe',   // 'stripe' | 'lemonsqueezy' | 'paddle' | 'none'
  testMode: false,
};
FieldTypeWhat it controls
provider'stripe' | 'lemonsqueezy' | 'paddle' | 'none'Which payment processor handles checkout and webhooks.
testModebooleanHint for the UI/provider that you're in a sandbox. Keep your test API keys in .env.local while this is true.

Choosing a provider

ProviderEnv vars it needs
stripe (default)STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_ID_PREMIUM (+ promo price IDs)
lemonsqueezyLEMON_API_KEY, LEMON_STORE_ID, LEMON_WEBHOOK_SECRET
paddlePADDLE_API_KEY, PADDLE_WEBHOOK_SECRET
none— (disables every paid flow)

See Payments for the full Stripe setup and Environment Variables for the keys.

Free-only directory

To run without payments, set the provider to nonedon't disable the promotions feature flag:

export const paymentsConfig: PaymentsConfig = {
  provider: 'none',
  testMode: false,
};

This hides every checkout button and short-circuits the payment APIs while leaving the rest of the directory intact.

Switching providers later

Each provider has its own price/product IDs and webhook signing secret. When you switch, create the equivalent products in the new provider, swap the env vars, and repoint the webhook endpoint. Past payments stay recorded in the payments table regardless.

See also