Consentful
Reference

Providers

Switch the auth, billing, and email providers without changing application code.

Each pluggable subsystem has multiple providers behind one shared interface. You select the active provider in packages/config/src/providers.ts and supply that provider's credentials via environment variables. No application code changes.

Auth

export const authProvider = 'better-auth'
ProviderNotes
better-auth (default)Full ownership of user data in your Postgres DB
clerkHosted auth via Clerk
kindeHosted auth via Kinde
neon-authNeon-native auth

To switch: change the value, then set the new provider's keys (e.g. Clerk's publishable/secret keys).

Billing

export const billingProvider = 'lemonsqueezy'
ProviderStatus
lemonsqueezy (default)Fully implemented
polarFully implemented
dodoFully implemented

Switch between the three by setting BILLING_PROVIDER (or editing billingProvider) — nothing else changes.

All providers use hosted checkout — the portal never touches raw card data. Every provider's webhook arrives at the single endpoint POST /webhooks/billing, where the signature is verified before processing.

Set the provider

Change billingProvider to your choice.

Add credentials

Set the provider's API key, store id, and webhook secret in the environment.

Register the webhook

Point the provider's webhook at {API_URL}/webhooks/billing.

Map plans

Plan → provider variant ids are stored per-plan in the database, seeded from your pricing config.

Email (automatic fallback chain)

Email is special: instead of one provider, you configure an ordered chain.

export const emailProviders = ['resend', 'plunk', 'loops', 'brevo', 'mailtrap', 'postmark', 'sendgrid']

Resend is the primary sender; the rest are free-tier fallbacks. The email layer tries providers[0] first; if it errors, hits its free-tier limit (HTTP 429 / quota), or is down, it automatically shifts to the next configured provider — a rate-limit / quota error skips retries and fails over immediately.

Only providers with credentials participate. With none configured, emails are logged to the console — handy for local development.

ProviderRequired env
resend (primary)RESEND_API_KEY
plunkPLUNK_API_KEY
loopsLOOPS_API_KEY + LOOPS_TRANSACTIONAL_ID
brevoBREVO_API_KEY
mailtrapMAILTRAP_API_TOKEN
postmarkPOSTMARK_SERVER_TOKEN
sendgridSENDGRID_API_KEY

Retry/backoff per provider is controlled by EMAIL_RETRY_ATTEMPTS and EMAIL_RETRY_BASE_MS.

Why this design

  • One switch, zero refactors — adapters share a stable interface.
  • No vendor lock-in — move providers by changing config + env.
  • Resilience — the email chain survives a single provider outage automatically.

On this page

Providers | Consentful