For local development, you need to forward Stripe webhooks from Stripe to your local machine.
-
Run the webhook forwarding script:
./stripe-webhook-forward.sh
-
That's it! The script will automatically:
- Prompt you to login to Stripe (opens browser on first run)
- Extract the webhook signing secret
- Update
STRIPE_WEBHOOK_SECRETin your.envfile - Restart the web container to apply the new secret
- Start forwarding webhooks to http://localhost:8000/api/stripe/webhook/
-
Test the flow:
- Visit http://localhost:8000/landing/signup/
- Complete a test checkout
- Webhooks will be forwarded to your local server
- Check logs:
docker compose logs -f web
If you prefer to run the Stripe CLI manually:
# Login to Stripe
stripe login
# Forward webhooks to your local server
stripe listen --forward-to http://localhost:8000/api/stripe/webhook/
# In a separate terminal, trigger test events
stripe trigger checkout.session.completedWhen a customer completes checkout, the webhook handler:
- Creates an Organization with the customer's name and email
- Creates an admin User with a random password
- Creates a UserProfile linking the user to the organization
- Creates a Subscription record with Stripe IDs and trial dates
- Sends a welcome email with login credentials
-
Go to Stripe Dashboard:
- Navigate to Developers → Webhooks
- Click "Add endpoint"
-
Configure the endpoint:
- URL:
https://yourdomain.com/api/stripe/webhook/ - Events to listen for:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_failed
- URL:
-
Get the signing secret:
- After creating the endpoint, click "Reveal" under "Signing secret"
- Copy the secret (starts with
whsec_) - Add it to your production environment variables
-
Update your
.env.productionfile:STRIPE_WEBHOOK_SECRET=whsec_your_production_secret_here
- Make sure
./stripe-webhook-forward.shis running - Check that Docker container is accessible at http://localhost:8000
- Verify logs:
docker compose logs -f web
- Ensure
STRIPE_WEBHOOK_SECRETin.envmatches the one from Stripe CLI - Restart container after updating
.env
- Check webhook handler logs:
docker compose logs web | grep "checkout.session.completed" - Verify Plans exist in database:
docker compose exec web python manage.py shell -c "from subscriptions.models import Plan; print(Plan.objects.all())" - Check for email sending errors in logs
- For local dev, check Mailpit at http://localhost:8025
- Verify SMTP settings in Organization admin panel
- Check logs for email sending errors
# Test successful checkout
stripe trigger checkout.session.completed
# Test subscription update
stripe trigger customer.subscription.updated
# Test subscription cancellation
stripe trigger customer.subscription.deleted
# Test payment failure
stripe trigger invoice.payment_failed# In Stripe Dashboard
Developers → Webhooks → [Your endpoint] → View logs
# Local logs
docker compose logs -f web