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

PlanFeatures
FreeBasicAccess
StarterBasicAccess, AdvancedReports, ApiAccess
ProBasicAccess, 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

  1. Create a Stripe account at stripe.com
  2. Set environment variablesSTRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, success/cancel URLs
  3. Configure plans — edit config/packages/stripe.yaml
  4. Sync plansdocker compose exec php bin/console app:stripe:sync-plans
  5. Set up webhook — point https://yourdomain.com/api/v1/webhooks/stripe to receive events

Local Testing with Stripe CLI

stripe listen --forward-to localhost/api/v1/webhooks/stripe

Webhook Events

Stripe EventAction
checkout.session.completedCreates subscription (free → paid upgrade)
customer.subscription.updatedUpdates plan/status
customer.subscription.deletedCancels subscription
invoice.payment_failedMarks subscription as past due
invoice.paidReactivates 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:

  1. Webhook fires on payment
  2. Subscription is created/upgraded
  3. GitHub API invite is sent
  4. 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.