Events & Hooks
v1.2 (module events), v1.3 (SubscriptionActivated, redirect hook)
ChargePanda fires platform events at key lifecycle moments. Your module listens to these events to react without modifying core code.
Listening to events
Register listeners in your ModuleServiceProvider::boot():
public function boot(): void
{
$this->loadWebRoutes();
$this->loadViews();
$this->app['events']->listen(
\App\Events\SubscriptionActivated::class,
\Modules\MyPlugin\Listeners\HandleSubscriptionActivated::class
);
}Your listener class:
<?php
namespace Modules\MyPlugin\Listeners;
use App\Events\SubscriptionActivated;
class HandleSubscriptionActivated
{
public function handle(SubscriptionActivated $event): void
{
$subscription = $event->subscription;
$user = $subscription->user;
// Do something — provision resources, send email, log, etc.
}
}Available core events
App\Events\ModuleActivated (v1.2)
Fired when a module is activated through the admin UI.
class ModuleActivated
{
public \App\Models\Module $module;
}Use case: Run a setup seeder the first time your module is activated.
$this->app['events']->listen(
\App\Events\ModuleActivated::class,
function (\App\Events\ModuleActivated $event) {
if ($event->module->slug !== 'my-plugin') {
return;
}
// Run setup only once
if (! setting('my-plugin.setup_complete')) {
(new \Modules\MyPlugin\Database\Seeders\SetupSeeder())->run();
\App\Models\Setting::updateSettings(['my-plugin' => ['setup_complete' => true]]);
}
}
);App\Events\SubscriptionActivated (v1.3)
Fired after a subscription transitions to ACTIVE status (paid checkout completion or manual activation).
class SubscriptionActivated
{
public \App\Models\Subscription $subscription;
}Use case: Provision resources for new subscribers, send a welcome email, set a post-payment redirect.
public function handle(SubscriptionActivated $event): void
{
$subscription = $event->subscription;
// Only act on subscriptions for your product
$myProductId = setting('my-plugin.linked_product_id');
if (! $this->belongsToMyProduct($subscription, $myProductId)) {
return;
}
// Provision something
\Modules\MyPlugin\Models\UserWorkspace::firstOrCreate([
'user_id' => $subscription->user_id,
]);
// Send email
\Mail::to($subscription->user)->send(new \Modules\MyPlugin\Mail\WelcomeMail($subscription));
}Post-payment redirect hook (v1.3)
By default, ChargePanda redirects to the generic thank-you page after a successful order. A listener can override this by writing to the redirect_after_order session key inside a SubscriptionActivated listener:
public function handle(SubscriptionActivated $event): void
{
// ... verify this is your subscription ...
session(['redirect_after_order' => route('my-plugin.account.index')]);
}OrderController::completed() checks this key after activation and redirects before rendering the standard page. The key is consumed (pulled) on first use so it doesn't persist across requests.
Only one listener should set this key per request. If multiple modules set it, the last write wins.
Firing your own events (optional)
You can fire your own events from module code. Other modules (or future versions of your own module) can listen to them:
// Define the event
namespace Modules\MyPlugin\Events;
class ItemCreated
{
public function __construct(
public readonly \Modules\MyPlugin\Models\Item $item
) {}
}
// Fire it
event(new \Modules\MyPlugin\Events\ItemCreated($item));Document your events alongside your module so other developers can integrate with them.