From a39d4b1b943e9d019e7f9732d753731a10549049 Mon Sep 17 00:00:00 2001 From: Ovidiu U Date: Thu, 23 Apr 2026 10:27:23 +0100 Subject: [PATCH] feat: consolidate stripe webhook handling into HandleStripeWebhook listener --- app/Listeners/HandleStripeWebhook.php | 36 +++++++++++++++++++ app/Providers/AppServiceProvider.php | 4 +-- .../Payments/HandleStripeWebhookTest.php | 30 ++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 app/Listeners/HandleStripeWebhook.php create mode 100644 tests/Feature/Payments/HandleStripeWebhookTest.php diff --git a/app/Listeners/HandleStripeWebhook.php b/app/Listeners/HandleStripeWebhook.php new file mode 100644 index 0000000..401a156 --- /dev/null +++ b/app/Listeners/HandleStripeWebhook.php @@ -0,0 +1,36 @@ +payload['type'] ?? null; + $stripeCustomerId = $event->payload['data']['object']['customer'] ?? null; + + if ($stripeCustomerId === null) { + return; + } + + $user = User::where('stripe_id', $stripeCustomerId)->first(); + + if ($user === null) { + return; + } + + match ($type) { + 'customer.subscription.created' => $this->bustPlanCache($user), + default => null, + }; + } + + private function bustPlanCache(User $user): void + { + Cache::tags(['plans'])->forget("plan_for_user_{$user->id}"); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 792bda2..e805751 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,7 +2,7 @@ namespace App\Providers; -use App\Listeners\DowngradeUserOnSubscriptionDeleted; +use App\Listeners\HandleStripeWebhook; use App\Services\ApiLogger; use App\Services\LlmPrediction\AnthropicPredictionProvider; use App\Services\LlmPrediction\GeminiPredictionProvider; @@ -41,7 +41,7 @@ class AppServiceProvider extends ServiceProvider { $this->configureDefaults(); - Event::listen(WebhookReceived::class, DowngradeUserOnSubscriptionDeleted::class); + Event::listen(WebhookReceived::class, HandleStripeWebhook::class); } /** diff --git a/tests/Feature/Payments/HandleStripeWebhookTest.php b/tests/Feature/Payments/HandleStripeWebhookTest.php new file mode 100644 index 0000000..4a50c04 --- /dev/null +++ b/tests/Feature/Payments/HandleStripeWebhookTest.php @@ -0,0 +1,30 @@ +create(['stripe_id' => 'cus_created_1']); + Cache::tags(['plans'])->put("plan_for_user_{$user->id}", 'stale', 3600); + + (new HandleStripeWebhook)->handle(new WebhookReceived([ + 'type' => 'customer.subscription.created', + 'data' => ['object' => ['customer' => 'cus_created_1']], + ])); + + expect(Cache::tags(['plans'])->get("plan_for_user_{$user->id}"))->toBeNull(); +}); + +it('ignores subscription.created when the user is not found', function (): void { + (new HandleStripeWebhook)->handle(new WebhookReceived([ + 'type' => 'customer.subscription.created', + 'data' => ['object' => ['customer' => 'cus_unknown']], + ])); + + expect(true)->toBeTrue(); +});