Subscription & Payments
Stripe integration, plan tiers, webhooks, and feature gating
Subscription & Payments
What's Included
- Three plan tiers (Free, Starter, Pro) with configurable features
- Stripe Checkout for both recurring and one-time payments
- Webhook handling for 5 Stripe events
- Feature gating via
FeatureAccessChecker - Guest and authenticated checkout support
Plan Tiers
| Plan | Features |
|---|---|
| Free | BasicAccess |
| Starter | BasicAccess, AdvancedReports, ApiAccess |
| Pro | BasicAccess, AdvancedReports, ApiAccess, PrioritySupport, CustomIntegrations |
Every user starts on the Free plan. Paid plans are activated after Stripe checkout completion.
Feature Access
Use FeatureAccessChecker to gate features in your code:
// Check if user has a feature
$checker->hasFeature($userId, Feature::AdvancedReports);
// Throw if feature not available
$checker->requireFeature($userId, Feature::ApiAccess);
// Get the user's effective plan
$checker->getEffectivePlanType($userId);
// Get all available features
$checker->getAvailableFeatures($userId);
Stripe Setup
- Create a Stripe account at stripe.com
- Set environment variables —
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET, success/cancel URLs - Configure plans — edit
config/packages/stripe.yaml - Sync plans —
docker compose exec php bin/console app:stripe:sync-plans - Set up webhook — point
https://yourdomain.com/api/v1/webhooks/stripeto receive events
Local Testing with Stripe CLI
stripe listen --forward-to localhost/api/v1/webhooks/stripe
Webhook Events
| Stripe Event | Action |
|---|---|
checkout.session.completed | Creates subscription (free → paid upgrade) |
customer.subscription.updated | Updates plan/status |
customer.subscription.deleted | Cancels subscription |
invoice.payment_failed | Marks subscription as past due |
invoice.paid | Reactivates subscription after successful payment |
Subscription Lifecycle
User signs up → Free plan (automatic)
|
v
Checkout → Stripe payment → Webhook → Paid plan (Starter/Pro)
|
+----------+----------+
v v v
Recurring One-time Cancel
| | |
Invoice cycle Lifetime Downgrade
| access to Free
+----+----+
v v
Paid Failed
| |
Active Past Due → Expired → Free
GitHub Organization Invite (Optional)
When a user completes a paid subscription, they can be automatically invited to your GitHub organization:
- Webhook fires on payment
- Subscription is created/upgraded
- GitHub API invite is sent
- Confirmation email is sent
Set PERSONAL_GITHUB_API_TOKEN, ORGANIZATION_GITHUB_NAME, and ORGANIZATION_GITHUB_URL to enable this feature. Failed invites are logged but don't block the subscription.