Stripe Integration Setup
Choose the setup guide that matches how you're using Event Schedule.
Overview
Event Schedule supports Stripe for payment processing, but the setup varies depending on how you're using the platform. This guide is organized by user type to help you find exactly what you need.
Recommended: Use Invoice Ninja with Stripe
For the best ticket selling experience, we recommend using Invoice Ninja alongside Stripe. Invoice Ninja provides additional features like professional invoicing, payment reminders, and detailed financial reporting that complement Stripe's payment processing.
Choose Your Setup
Find your setup type and follow the corresponding guide:
| You are... | Money flows to... | Follow this guide |
|---|---|---|
| Running your own Event Schedule instance for your organization | Your single Stripe account | Selfhosted Users |
| Running a white-label SaaS platform | Your customers' Stripe accounts + your account for subscriptions | SaaS Operators |
Decision Tree
Q: Will multiple people create events and need their own payment accounts?
→ Yes: SaaS Operators
→ No: Selfhosted Users
For Selfhosted Users
If you're running your own Event Schedule instance for your organization, venue, or community, all ticket payments go to a single Stripe account that you control.
This guide is for you if...
You want all ticket revenue from all events on your instance to go to one Stripe account. Event creators don't need their own Stripe accounts.
1. Get Your Stripe API Keys
- Go to the Stripe Dashboard
- Navigate to Developers → API keys
- Note your Publishable key and Secret key
2. Configure Environment Variables
Add these to your .env file:
# Stripe Direct Payments (selfhosted)
STRIPE_PLATFORM_KEY=pk_live_your_publishable_key
STRIPE_PLATFORM_SECRET=sk_live_your_secret_key
STRIPE_PLATFORM_WEBHOOK_SECRET=whsec_your_webhook_secret
STRIPE_PLATFORM_KEY: Your publishable key (starts withpk_live_orpk_test_)STRIPE_PLATFORM_SECRET: Your secret key (starts withsk_live_orsk_test_)STRIPE_PLATFORM_WEBHOOK_SECRET: Webhook signing secret (next step)
3. Set Up Webhooks
- In Stripe Dashboard, go to Developers → Webhooks
- Click Add endpoint
- Set URL to:
https://yourdomain.com/stripe/webhook - Select event:
checkout.session.completed - Save and copy the Signing secret to
STRIPE_PLATFORM_WEBHOOK_SECRET
Important: Webhook Event
Make sure to select checkout.session.completed—this is different from SaaS setups which use payment_intent.succeeded.
4. Enable Stripe for Events
Once configured, event creators can select "Stripe" as the payment method when creating events with tickets. All payments automatically use your platform Stripe account.
How Checkout Works
- Customer selects tickets and fills out the checkout form
- Event Schedule creates a Stripe Checkout Session
- Customer completes payment on Stripe's hosted page
- Webhook confirms payment and marks the sale as paid
- Customer receives their tickets
For SaaS Operators
If you're running your own white-label SaaS platform (like eventschedule.com but with your own branding), you need two Stripe integrations:
Stripe Connect
So your event creator customers can connect their Stripe accounts and receive ticket payments directly.
Laravel Cashier
To charge your customers for Pro subscriptions (the money you make as the platform operator).
Part A: Stripe Connect (Ticket Sales)
Allow your event creators to receive payments for their ticket sales
1. Enable Stripe Connect
- Go to the Stripe Dashboard
- Navigate to Settings → Connect → Settings
- Enable Connect for your platform
- Configure your branding and platform profile
- Get your API keys from Developers → API keys
2. Environment Configuration
# Stripe Connect (for event creators to receive ticket payments)
STRIPE_KEY=sk_live_your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=whsec_your_connect_webhook_secret
STRIPE_KEY: Your platform's Stripe secret keySTRIPE_WEBHOOK_SECRET: Webhook secret for Connect events
3. Webhook Configuration
- Go to Developers → Webhooks
- Click Add endpoint
- Set URL to:
https://yourdomain.com/stripe/webhook - Select event:
payment_intent.succeeded - Save and copy the signing secret to
STRIPE_WEBHOOK_SECRET
User Onboarding Flow
Your event creators will:
- Go to Profile → Payment Methods
- Click "Connect Stripe Account"
- Complete Stripe's onboarding
- Return to your platform ready to sell tickets
Connect API Endpoints
| Endpoint | Description |
|---|---|
GET /stripe/link |
Start Stripe Connect onboarding |
GET /stripe/complete |
Complete onboarding callback |
GET /stripe/unlink |
Disconnect Stripe account |
POST /stripe/webhook |
Handle payment_intent.succeeded |
Part B: Laravel Cashier (Subscription Billing)
Charge your customers for Pro plan subscriptions
1. Create Subscription Products
- In Stripe Dashboard, go to Products → Add product
- Create a "Pro Plan" product with:
- Monthly price (e.g., $9.99/month, recurring)
- Yearly price (e.g., $99.99/year, recurring)
- Note the Price IDs (starts with
price_)
2. Environment Configuration
# Laravel Cashier (for subscription billing)
STRIPE_PLATFORM_KEY=pk_live_your_publishable_key
STRIPE_PLATFORM_SECRET=sk_live_your_secret_key
STRIPE_PLATFORM_WEBHOOK_SECRET=whsec_your_subscription_webhook_secret
STRIPE_PRICE_MONTHLY=price_monthly_price_id
STRIPE_PRICE_YEARLY=price_yearly_price_id
STRIPE_PLATFORM_KEY: Publishable key for your platformSTRIPE_PLATFORM_SECRET: Secret key for your platformSTRIPE_PLATFORM_WEBHOOK_SECRET: Webhook secret for subscription eventsSTRIPE_PRICE_MONTHLY: Price ID for monthly subscriptionSTRIPE_PRICE_YEARLY: Price ID for yearly subscription
3. Subscription Webhook
- Go to Developers → Webhooks
- Click Add endpoint (this is a second webhook, separate from Connect)
- Set URL to:
https://yourdomain.com/stripe/subscription-webhook - Select events:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcustomer.subscription.trial_will_endinvoice.payment_succeededinvoice.payment_failed
- Save and copy signing secret to
STRIPE_PLATFORM_WEBHOOK_SECRET
4. Customer Portal Setup
- Go to Settings → Billing → Customer portal
- Enable subscription management features:
- Subscription cancellation
- Plan switching
- Payment method updates
- Customize branding to match your platform
Subscription API Endpoints
| Endpoint | Description |
|---|---|
GET /{subdomain}/subscribe |
Show subscription page |
POST /{subdomain}/subscribe |
Create new subscription |
GET /{subdomain}/subscription/portal |
Redirect to Stripe Customer Portal |
POST /{subdomain}/subscription/cancel |
Cancel subscription |
POST /{subdomain}/subscription/resume |
Resume cancelled subscription |
POST /{subdomain}/subscription/swap |
Switch between monthly/yearly |
POST /stripe/subscription-webhook |
Handle subscription events |
Architecture Note
Laravel Cashier uses the Role model (schedule/calendar) as the billable entity, not User. This means each schedule has its own subscription, and users can have multiple schedules with different plans.
Testing
Test Mode Setup
For development and testing:
- Toggle to "Test mode" in the Stripe Dashboard
- Use test API keys (starting with
pk_test_andsk_test_) - Create test webhook endpoints pointing to your development environment
Test Card Numbers
| Card Number | Result |
|---|---|
4242 4242 4242 4242 |
Successful payment |
4000 0000 0000 3220 |
3D Secure required |
4000 0000 0000 9995 |
Declined (insufficient funds) |
4000 0000 0000 0002 |
Declined (generic) |
Use any future expiration date and any 3-digit CVC.
Testing Webhooks Locally
Use the Stripe CLI to forward webhooks:
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to your Stripe account
stripe login
# Forward webhooks (selfhosted or Connect)
stripe listen --forward-to localhost:8000/stripe/webhook
# For SaaS: Forward subscription webhooks (separate terminal)
stripe listen --forward-to localhost:8000/stripe/subscription-webhook
The CLI displays a webhook signing secret to use in your .env file.
Trigger Test Events
# Test checkout completion (selfhosted)
stripe trigger checkout.session.completed
# Test payment success (Connect)
stripe trigger payment_intent.succeeded
# Test subscription creation
stripe trigger customer.subscription.created
Troubleshooting
Common Issues
"Stripe account not connected" error
Applies to: SaaS operators (Connect)
- User needs to complete Stripe Connect onboarding
- Check if
stripe_account_idandstripe_completed_atare set on the user
"Invalid signature" webhook error
Applies to: All setups
- Verify the webhook secret matches the one in Stripe Dashboard
- Make sure you're using the correct secret for each endpoint:
STRIPE_WEBHOOK_SECRETfor Connect webhooksSTRIPE_PLATFORM_WEBHOOK_SECRETfor selfhosted/subscription webhooks
Payments not being recorded
Applies to: Selfhosted users, SaaS operators
- Check webhook logs in Stripe Dashboard → Webhooks → View logs
- Verify the webhook endpoint is accessible (not blocked by firewall)
- Check
storage/logs/laravel.logfor errors
Subscription not updating after payment
Applies to: SaaS operators
- Verify webhook events are being received
- Check that all required subscription events are selected in Stripe
- Review
storage/logs/laravel.logfor errors
"No such price" error
Applies to: SaaS operators
- Verify
STRIPE_PRICE_MONTHLYandSTRIPE_PRICE_YEARLYcontain valid Price IDs - Ensure the prices exist in the same Stripe mode (test vs live)
Debugging Logs
- Application:
storage/logs/laravel.log - Stripe API: Dashboard → Developers → Logs
- Webhooks: Dashboard → Developers → Webhooks → Select endpoint → View logs
Security
- API Key Security: Never expose secret keys in client-side code or version control. Use environment variables.
- Webhook Verification: Always verify webhook signatures—Event Schedule does this automatically.
- HTTPS Required: Stripe requires HTTPS for webhook endpoints in production.
- PCI Compliance: Using Stripe Checkout and Elements keeps you out of PCI scope—card data never touches your server.