Skip to main content

Stripe Webhooks

Webhooks allow Stripe to notify your app when events happen—like successful payments, subscription changes, or failed charges.

Supported Events

Launch handles these webhook events out of the box:
EventDescription
payment_intent.succeededPayment was successful
payment_intent.payment_failedPayment failed
customer.subscription.createdNew subscription started
customer.subscription.updatedSubscription changed (upgrade/downgrade)
customer.subscription.deletedSubscription cancelled
invoice.payment_succeededRecurring payment successful
invoice.payment_failedRecurring payment failed

How It Works

Stripe Event → Your API → Database Update → App Response
  1. Stripe sends event to your webhook endpoint
  2. API verifies signature to ensure authenticity
  3. Handler processes event and updates database
  4. User sees changes reflected in the app

Webhook Endpoint

Location: apps/api/src/routes/stripe-webhooks.ts
// Webhook endpoint: POST /webhooks/stripe
export async function handleStripeWebhook(req, res) {
  const sig = req.headers["stripe-signature"];
  const event = stripe.webhooks.constructEvent(
    req.body,
    sig,
    process.env.STRIPE_WEBHOOK_SECRET
  );

  switch (event.type) {
    case "payment_intent.succeeded":
      // Handle successful payment
      break;
    case "customer.subscription.created":
      // Handle new subscription
      break;
    // ... more handlers
  }
}

Local Development

For local testing, use ngrok to expose your API:
# Start ngrok tunnel
ngrok http 3001

# Your webhook URL will be:
# https://abc123.ngrok-free.app/webhooks/stripe
Remember to update your webhook URL in Stripe Dashboard whenever your ngrok URL changes.

Database Updates

When webhook events are received, the following tables are updated:
  • StripeCustomer - Customer information
  • Subscription - Subscription status and details
  • Payment - Payment history

Debugging

Check your API logs for webhook activity:
🔔 Stripe webhook received: payment_intent.succeeded
💳 Payment succeeded: pi_xxx - $19.99
💾 Payment saved to database for user: usr_xxx

Test Checklist

  • Webhook endpoint responds to Stripe test events
  • STRIPE_WEBHOOK_SECRET matches the dashboard
  • Subscription/payment records update in the database

Troubleshooting

If events are not received, verify ngrok URL and webhook configuration in Stripe Dashboard.

Remove / Disable

To disable payments while you configure Stripe, set: apps/mobile/features/feature-registry.tsxfeatureFlags.payments = false For production removal guidance, see Removing Features.

Next Steps