diff --git a/app/Listeners/HandleStripeWebhook.php b/app/Listeners/HandleStripeWebhook.php index 00ec40a..2f205a4 100644 --- a/app/Listeners/HandleStripeWebhook.php +++ b/app/Listeners/HandleStripeWebhook.php @@ -129,8 +129,9 @@ final class HandleStripeWebhook private function bustPlanCache(User $user): void { - $tag = Cache::tags(['plans']); - $tag->forget("plan_for_user_{$user->id}"); - $tag->forget("plan_cadence_for_user_{$user->id}"); + $cache = Cache::supportsTags() ? Cache::tags(['plans']) : Cache::store(); + + $cache->forget("plan_for_user_{$user->id}"); + $cache->forget("plan_cadence_for_user_{$user->id}"); } } diff --git a/tests/Feature/Payments/HandleStripeWebhookTest.php b/tests/Feature/Payments/HandleStripeWebhookTest.php index 6c89f4c..09b6bc0 100644 --- a/tests/Feature/Payments/HandleStripeWebhookTest.php +++ b/tests/Feature/Payments/HandleStripeWebhookTest.php @@ -24,6 +24,24 @@ it('busts the plan cache on customer.subscription.created', function (): void { expect(Cache::tags(['plans'])->get("plan_for_user_{$user->id}"))->toBeNull(); }); +it('busts the plan cache without error on a cache store that does not support tags', function (): void { + // The `file` driver is not taggable — calling Cache::tags() on it throws. + // This guards against a regression where bustPlanCache assumed a taggable store. + config(['cache.default' => 'file']); + Cache::store('file')->flush(); + expect(Cache::supportsTags())->toBeFalse(); + + $user = User::factory()->create(['stripe_id' => 'cus_notags_1']); + Cache::put("plan_for_user_{$user->id}", 'stale', 3600); + + (new HandleStripeWebhook)->handle(new WebhookReceived([ + 'type' => 'customer.subscription.created', + 'data' => ['object' => ['customer' => 'cus_notags_1']], + ])); + + expect(Cache::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',