Skip to content

Stripe Payments

Accept credit and debit card payments alongside Lightning using Stripe Checkout - fully PCI-compliant, card details never touch your server.

Prerequisites

  • A Stripe account (free to create)
  • LNbits instance with Super User access
  • HTTPS enabled on your LNbits instance (required for webhooks)

Getting your Stripe keys

  1. Log in to the Stripe Dashboard
  2. Copy the Publishable key (pk_live_...) and Secret key (sk_live_...)
  3. For testing, toggle to Test mode and use the test keys (pk_test_... / sk_test_...)

TIP

Use test mode first. Stripe provides test card numbers like 4242 4242 4242 4242 so you can verify the full flow without real money.

Setup

Via Admin UI

  1. Log in as Super User
  2. Go to Admin > Server > Fiat Providers
  3. Enter your Stripe API keys (secret key + publishable key)
  4. Set the webhook signing secret (see Webhook setup below)
  5. Configure limits (optional)
  6. Click Save

Via environment variables

bash
LNBITS_FIAT_PROVIDER_STRIPE=true
STRIPE_SECRET_KEY=sk_live_...
STRIPE_PUBLISHABLE_KEY=pk_live_...
STRIPE_WEBHOOK_SIGNING_SECRET=whsec_...

Webhook setup

Stripe uses webhooks to notify LNbits when payments complete. Without a working webhook, payments will stay stuck on "pending".

  1. Go to Stripe Dashboard > Webhooks
  2. Click Add endpoint
  3. Set the endpoint URL to:
https://your-lnbits.com/api/v1/webhook/stripe
  1. Subscribe to these events:
EventPurpose
checkout.session.completedOne-time payment completed
payment_intent.succeededPayment intent fulfilled
customer.subscription.createdNew subscription started
customer.subscription.deletedSubscription cancelled
  1. After creating the endpoint, copy the Signing secret (whsec_...) and add it to your config

WARNING

The webhook URL must be publicly reachable over HTTPS. If you're behind a reverse proxy, make sure the /api/v1/webhook/stripe path is forwarded correctly.

Payment flows

One-time payments (Checkout Sessions)

The most common pattern. Users are redirected to a Stripe-hosted payment page:

User clicks "Pay with Card"
  → Redirected to Stripe Checkout
  → Enters card details
  → Payment processed
  → Redirected back to LNbits
  → Webhook confirms payment

Card details never touch your server - Stripe handles all PCI compliance.

Subscriptions

For recurring payments (e.g., paid extension access, premium features):

User subscribes via Stripe Checkout
  → Stripe creates a recurring subscription
  → Charges on the configured schedule
  → Webhooks notify LNbits of each payment
  → User can cancel anytime

Subscriptions require creating Price objects in your Stripe dashboard first.

Limits

Control who can use Stripe payments and how much they can pay:

VariableDefaultDescription
STRIPE_MIN_AMOUNT_SATS0Minimum payment amount in sats
STRIPE_MAX_AMOUNT_SATS0Maximum payment amount in sats (0 = unlimited)
STRIPE_MAX_SATS_FEE0Maximum fee cap in sats
STRIPE_PERCENT_FEE0Percentage fee on each payment
STRIPE_ALLOWED_USERS-Comma-separated user IDs (empty = everyone)
STRIPE_FAUCET_WALLET-Wallet ID to receive faucet funds

Environment variable reference

VariableRequiredDescription
LNBITS_FIAT_PROVIDER_STRIPEYesSet to true to enable Stripe
STRIPE_SECRET_KEYYesStripe secret key (sk_live_... or sk_test_...)
STRIPE_PUBLISHABLE_KEYYesStripe publishable key (pk_live_... or pk_test_...)
STRIPE_WEBHOOK_SIGNING_SECRETYesWebhook signing secret (whsec_...)
STRIPE_MIN_AMOUNT_SATSNoMinimum payment in sats
STRIPE_MAX_AMOUNT_SATSNoMaximum payment in sats
STRIPE_MAX_SATS_FEENoFee cap in sats
STRIPE_PERCENT_FEENoPercentage fee
STRIPE_ALLOWED_USERSNoRestrict access to specific users
STRIPE_FAUCET_WALLETNoWallet for faucet funds

Test mode vs Live mode

TestLive
Key prefixsk_test_... / pk_test_...sk_live_... / pk_live_...
Real moneyNoYes
Test cards4242 4242 4242 4242Real cards only
Webhook secretSeparate per modeSeparate per mode

Switch between modes in the Stripe Dashboard. Use separate webhook endpoints for test and live, each with their own signing secret.

Stripe ID prefixes

Useful when debugging - Stripe prefixes every object ID:

PrefixType
cs_Checkout session
pi_Payment intent
in_Invoice
sub_Subscription

Troubleshooting

IssueCauseFix
"Card payments not available"Stripe not enabledSuper User must enable Stripe in Admin UI or set LNBITS_FIAT_PROVIDER_STRIPE=true
Payments stuck on "pending"Webhook not reaching LNbitsVerify webhook URL and signing secret; check HTTPS, firewall, and reverse proxy config
"Not authorized for card payments"User not in allowed listAdd user ID to STRIPE_ALLOWED_USERS or leave empty for all users
Amount errorsOutside configured limitsCheck STRIPE_MIN_AMOUNT_SATS and STRIPE_MAX_AMOUNT_SATS
Webhook signature mismatchWrong signing secretEach webhook endpoint has its own secret; make sure you copied the right one

WARNING

Never expose your Stripe secret key. It should only be configured by the Super User via the Admin UI or environment variables. Extensions must never store, log, or display Stripe keys.

News · Shop · SaaS · Telegram · Released under the MIT License.