Skip to main content

Hooks and Events

Subscribd fires Laravel events at every significant billing milestone. Listen to them from AppServiceProvider, a dedicated EventServiceProvider, or anywhere you register listeners in your application.

Registering listeners

use Illuminate\Support\Facades\Event;
use Pixelworxio\Subscribd\Events\SubscriptionCreated;

// AppServiceProvider::boot()
Event::listen(SubscriptionCreated::class, function (SubscriptionCreated $event) {
    // $event->subscription — the created Subscription model
    // $event->subscription->billable — the subscriber
});
Or use a dedicated listener class:
Event::listen(SubscriptionCreated::class, SendWelcomeEmail::class);

Event reference

Subscription lifecycle

EventFired whenKey properties
SubscriptionCreatedA new subscription is created and active$subscription
SubscriptionUpdatedAny attribute on a subscription changes$subscription, $changes
SubscriptionCanceledA subscription is canceled (grace or immediate)$subscription
SubscriptionResumedA canceled subscription in grace period is resumed$subscription
SubscriptionExpiredA subscription reaches end of life with no renewal$subscription
SubscriptionPausedA subscription is paused$subscription
SubscriptionUnpausedA paused subscription is resumed$subscription
SubscriptionPastDueA subscription enters past due status$subscription
PlanSwappedA subscription’s plan changes$subscription, $oldPlan, $newPlan

Trial events

EventFired whenKey properties
TrialStartedA subscription is created with a trial period$subscription
TrialEndingTrial is within the notify_days_before window$subscription, $trialEndsAt
TrialEndedTrial period expires$subscription
TrialConvertedTrial is converted to an active subscription$subscription
TrialCanceledTrial is canceled before converting$subscription
TrialExtendedTrial end date is extended$subscription, $extendedUntil

Payment events

EventFired whenKey properties
InvoicePaidAn invoice is successfully paid$invoice
InvoicePaymentFailedAn invoice payment attempt fails$invoice
InvoiceCreatedA new invoice is generated$invoice
InvoiceRefundedA refund is issued on a paid invoice$invoice, $amount
PaymentRetryFailedA dunning retry attempt fails$invoice, $attempt
PaymentMethodExpiringA payment method is within notify_days_before of expiry$billable, $paymentMethod

Coupon events

EventFired whenKey properties
CouponAppliedA coupon is applied to a subscription$subscription, $coupon
CouponExpiredAn applied coupon reaches its expiry$subscription, $coupon

All events namespace

All events live under Pixelworxio\Subscribd\Events\:
use Pixelworxio\Subscribd\Events\SubscriptionCreated;
use Pixelworxio\Subscribd\Events\SubscriptionCanceled;
use Pixelworxio\Subscribd\Events\SubscriptionExpired;
use Pixelworxio\Subscribd\Events\SubscriptionPastDue;
use Pixelworxio\Subscribd\Events\PlanSwapped;
use Pixelworxio\Subscribd\Events\TrialStarted;
use Pixelworxio\Subscribd\Events\TrialEnding;
use Pixelworxio\Subscribd\Events\TrialConverted;
use Pixelworxio\Subscribd\Events\InvoicePaid;
use Pixelworxio\Subscribd\Events\InvoicePaymentFailed;
use Pixelworxio\Subscribd\Events\PaymentRetryFailed;
use Pixelworxio\Subscribd\Events\CouponApplied;

Using observers

For more complex scenarios, register a model observer on Subscription or Invoice directly:
use Pixelworxio\Subscribd\Models\Subscription;

Subscription::observe(SubscriptionObserver::class);

Lifecycle hooks

For lightweight callbacks that don’t warrant a full listener, use the action hooks API:
use Pixelworxio\Subscribd\Actions\CreateSubscription;

CreateSubscription::before(function (Billable $billable, Plan $plan, array $options) {
    // Runs before the action executes
    // Return false to abort
});

CreateSubscription::after(function (Subscription $subscription) {
    // Runs after the subscription is created
});
Hook callbacks receive the same arguments as the action’s execute() method. before callbacks can abort execution by returning false. after callbacks receive the action’s return value. Available action hooks:
ActionHook receives
CreateSubscription::beforeBillable $billable, Plan $plan, array $options
CreateSubscription::afterSubscription $subscription
SwapPlan::beforeSubscription $subscription, Plan $newPlan, array $options
SwapPlan::afterSubscription $subscription
CancelSubscription::beforeSubscription $subscription, bool $immediately
CancelSubscription::afterSubscription $subscription
ResumeSubscription::beforeSubscription $subscription
ResumeSubscription::afterSubscription $subscription
PauseSubscription::beforeSubscription $subscription, array $options
PauseSubscription::afterSubscription $subscription
ConvertTrialToActive::beforeSubscription $subscription
ConvertTrialToActive::afterSubscription $subscription

Testing events

Use Laravel’s Event::fake() to assert events are dispatched in tests:
use Pixelworxio\Subscribd\Events\SubscriptionCreated;
use Pixelworxio\Subscribd\Events\PlanSwapped;
use Illuminate\Support\Facades\Event;

it('fires SubscriptionCreated on subscribe', function () {
    Event::fake([SubscriptionCreated::class]);

    $user = User::factory()->create();
    $plan = Plan::factory()->create(['key' => 'pro']);

    app(\Pixelworxio\Subscribd\Actions\CreateSubscription::class)->execute($user, $plan);

    Event::assertDispatched(SubscriptionCreated::class, function ($event) use ($user) {
        return $event->subscription->billable->is($user);
    });
});

Next steps

  • Webhooks — Gateway events that trigger these Subscribd events
  • Testing — Testing billing flows with Event::fake()
  • Dunning — Events fired during the payment retry cycle