Skip to content

Payment Webhooks

LaunchKit Pro ingests billing webhooks from Stripe and Lemon Squeezy when BILLING_PROVIDER is set to the matching provider. Mock billing uses POST /billing/webhooks/mock for development only.

HTTPS required in production

Provider dashboards must call your public API URL over HTTPS. Local testing typically uses Stripe CLI or Lemon Squeezy forwarding tools.

Endpoints

ProviderMethodPath
StripePOST/billing/webhooks/stripe
Lemon SqueezyPOST/billing/webhooks/lemon-squeezy
Mock (dev)POST/billing/webhooks/mock

Full URLs (production example):

https://api.yourdomain.com/billing/webhooks/stripe
https://api.yourdomain.com/billing/webhooks/lemon-squeezy

Stripe

Env: STRIPE_WEBHOOK_SECRET (signing secret from Stripe Dashboard or CLI)

Verification: Raw request body + Stripe-Signature header

Handled events (foundation):

  • checkout.session.completed
  • invoice.payment_succeeded
  • invoice.payment_failed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted

Stored provider IDs: stripeCustomerId, stripeSubscriptionId, stripeCheckoutSessionId, stripeInvoiceId

Metadata synced: userId, workspaceId, editionKey, app=launchkit-pro

Invalid signatures are rejected. Duplicate events are ignored via unique provider event IDs.

Local testing (Stripe CLI)

bash
stripe listen --forward-to localhost:4000/billing/webhooks/stripe
# Copy whsec_... into STRIPE_WEBHOOK_SECRET for local dev

Lemon Squeezy

Env: LEMON_SQUEEZY_WEBHOOK_SECRET

Verification: Raw request body + X-Signature header; event name from X-Event-Name

Handled events (foundation):

  • order_created
  • subscription_created
  • subscription_updated
  • subscription_cancelled
  • subscription_expired
  • subscription_payment_success
  • subscription_payment_failed

Stored provider IDs: lemonCustomerId, lemonOrderId, lemonSubscriptionId, lemonVariantId, lemonProductId

Custom data synced: userId, workspaceId, editionKey, app=launchkit-pro

Receipt or order URLs are stored when the provider payload includes them.

Idempotency and sync

  • Webhook events are recorded in BillingWebhookEvent with unique (provider, providerEventId) constraints
  • Payment rows use unique (provider, providerPaymentId) where applicable
  • Subscription status, period dates, and workspace current edition update from webhook payloads
  • API returns 2xx only after safe processing

After redirect checkout, the dashboard may show "Payment status will update after webhook confirmation." until the provider webhook arrives.

Developer webhooks (separate)

Workspace Developer Tools webhooks are outbound webhooks sent from LaunchKit Pro to customer endpoints. They are unrelated to payment provider webhooks.

Developer webhooks send signed JSON POST requests for these event types:

  • workspace.created
  • workspace.updated
  • user.created
  • billing.checkout_completed
  • billing.subscription_updated
  • license.activated
  • ai.generation_created
  • file.uploaded

Each request includes X-LaunchKit-Event, X-LaunchKit-Delivery, X-LaunchKit-Timestamp, and X-LaunchKit-Signature. The signature is HMAC-SHA256(timestamp + "." + rawJsonPayload) using the endpoint secret shown once when the webhook is created.

Delivery can be disabled with WEBHOOK_DELIVERY_ENABLED=false. Demo delivery is blocked by default with WEBHOOK_DEMO_DELIVERY_DISABLED=true. See Developer Tools for API key usage, outbound webhook delivery logs, retries, and signature verification examples.

LaunchKit Pro by LaunchKit Labs — buyer documentation. No secrets in this site.