crumbls/subscriptions v2.0.1
Events
Lifecycle events for hooking payment workflows, sending emails, syncing analytics, or any other side effect that should happen when a subscription changes state.
Event catalog
| Event | Class | Fired when |
|---|---|---|
| Created | Crumbls\Subscriptions\Events\SubscriptionCreated |
$model->subscribe(...) succeeds |
| Canceled | Crumbls\Subscriptions\Events\SubscriptionCanceled |
$sub->cancel() succeeds. Carries bool $immediate |
| Renewed | Crumbls\Subscriptions\Events\SubscriptionRenewed |
$sub->renew() succeeds |
| Plan changed | Crumbls\Subscriptions\Events\SubscriptionPlanChanged |
$sub->changePlan(...) succeeds. Carries $oldPlan and $newPlan |
All events expose $subscription as a public readonly property.
Wiring listeners
// app/Providers/EventServiceProvider.php (or AppServiceProvider boot)
use Crumbls\Subscriptions\Events\SubscriptionCreated;
use Crumbls\Subscriptions\Events\SubscriptionCanceled;
use Illuminate\Support\Facades\Event;
public function boot(): void
{
Event::listen(SubscriptionCreated::class, SendWelcomeEmail::class);
Event::listen(SubscriptionCanceled::class, NotifyAccountManager::class);
}
Common patterns
Welcome email on first subscription
class SendWelcomeEmail
{
public function handle(SubscriptionCreated $event): void
{
$event->subscription->subscriber->notify(
new SubscriptionStarted($event->subscription)
);
}
}
Cancel the recurring payment when the subscription is canceled
class CancelStripeSubscription
{
public function handle(SubscriptionCanceled $event): void
{
$stripeId = $event->subscription->subscriber->stripe_subscription_id;
if ($stripeId) {
Stripe::cancel($stripeId, immediately: $event->immediate);
}
}
}
Track plan upgrades and downgrades
class TrackPlanChange
{
public function handle(SubscriptionPlanChanged $event): void
{
$direction = $event->newPlan->price > $event->oldPlan->price
? 'upgrade'
: 'downgrade';
analytics()->track('plan_changed', [
'subscriber' => $event->subscription->subscriber_id,
'old_plan' => $event->oldPlan->slug,
'new_plan' => $event->newPlan->slug,
'direction' => $direction,
]);
}
}
Broadcasting
These events are plain PHP / Laravel events -- they do not implement ShouldBroadcast out of the box. If you want to broadcast, extend the event in your application:
namespace App\Events;
use Crumbls\Subscriptions\Events\SubscriptionCanceled as BaseEvent;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class SubscriptionCanceled extends BaseEvent implements ShouldBroadcast
{
public function broadcastOn(): array
{
return [new PrivateChannel('user.' . $this->subscription->subscriber_id)];
}
}
Then dispatch your version from a listener on the base event, or override the model methods to dispatch yours instead.