Docus Logo
Charcoles Payments

Providers

Configure your payment provider credentials for Stripe or LemonSqueezy.

Stripe Configuration

Get Your Credentials

  1. Go to dashboard.stripe.com/apikeys
  2. You'll see two sets of keys: Test (prefixed sk_test_) and Live (prefixed sk_live_)
  3. Start with test keys while developing
  4. Copy your secret key and webhook secret

Find Your Webhook Secret

  1. Go to dashboard.stripe.com/webhooks
  2. Create a new endpoint or click your existing one
  3. Your webhook endpoint should be: https://your-domain.com/payments/webhook
  4. Copy the Signing secret (starts with whsec_)

Environment Variables

Add these to your .env:

PAYMENT_PROVIDER=stripe
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PUBLISHABLE_KEY=pk_test_...

How Stripe Payment Flow Works

  1. Frontend calls POST /payments/create-intent with amount and currency
  2. Server responds with clientSecret
  3. Frontend uses clientSecret with Stripe.js to confirm payment
  4. User completes payment form on Stripe's hosted page
  5. Stripe fires payment_intent.succeeded webhook to your server
  6. Your server receives webhook and fulfills the order

The STRIPE_PUBLISHABLE_KEY is safe to expose in frontend code. It's never used server-side. Include it in .env for reference, but the server only reads the secret key.


LemonSqueezy Configuration

Get Your Credentials

  1. API Key: Go to app.lemonsqueezy.com/settings/api and generate an API key
  2. Store ID: Find your store ID in the URL. Go to app.lemonsqueezy.com/stores — it's the numeric ID in the URL
    • Example: app.lemonsqueezy.com/stores/12345 → Store ID is 12345
  3. Webhook Secret: Create a webhook in your store settings and copy the signing secret

Environment Variables

Add these to your .env:

PAYMENT_PROVIDER=lemonsqueezy
LEMONSQUEEZY_API_KEY=your_api_key
LEMONSQUEEZY_WEBHOOK_SECRET=your_webhook_secret
LEMONSQUEEZY_STORE_ID=12345

The Variant ID Requirement

LemonSqueezy uses product variants, not raw amounts. You cannot charge an arbitrary amount like $29.99 — you must have a product in your LemonSqueezy store first.For variable-amount payments (custom invoices, tips, or metered billing), create a "Pay What You Want" product in LemonSqueezy and use that variant's ID.When calling POST /payments/create-intent, pass variantId in the metadata:
{
  "amount": 2999,
  "currency": "usd",
  "metadata": {
    "variantId": "78901"
  }
}
The variantId is required for LemonSqueezy. Stripe ignores it.

How LemonSqueezy Payment Flow Works

  1. Frontend calls POST /payments/create-intent with variantId in metadata
  2. Server responds with checkoutUrl
  3. Frontend redirects user to checkoutUrl
  4. User pays on LemonSqueezy's hosted checkout page
  5. LemonSqueezy fires order_created webhook to your server
  6. Your server receives webhook and fulfills the order

LemonSqueezy is a merchant of record — you don't see raw payment method data. LemonSqueezy handles the transaction and deposits funds to your account.


Switching Providers

Changing providers is simple — no code changes needed.

  1. Update PAYMENT_PROVIDER in .env to stripe or lemonsqueezy
  2. Add the required env vars for your new provider
  3. Restart your server

The adapter is instantiated once on startup based on the PAYMENT_PROVIDER value. That's it.


Test vs Live Keys

Development (Test Keys)

Use test keys while building:

  • Stripe test key (starts with sk_test_)
  • LemonSqueezy test mode (check the API key source)

Test keys never charge real payment methods. They're safe to keep in version control during development (though you should still use .env).

Production (Live Keys)

When you go live:

  • Switch to live keys (sk_live_ for Stripe)
  • Update webhooks to your production URL
  • Double-check PAYMENT_PROVIDER is set correctly
  • Verify webhook secrets are production secrets, not test secrets

What Comes Next