From ff759611b951dbfaa5f41c574ab61b1be330a33c Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Thu, 7 May 2026 11:35:36 -0300 Subject: [PATCH] refactor: allow yearly to monthly swaps in BillingController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops the abort_if guard that blocked switching from a yearly billing cadence to monthly. The product decision was reversed — users should be free to move in either direction without going through support. Removes the corresponding 'swap blocks yearly to monthly downgrade' test. --- .../Controllers/App/BillingController.php | 10 ------- tests/Feature/BillingControllerTest.php | 27 ------------------- 2 files changed, 37 deletions(-) diff --git a/app/Http/Controllers/App/BillingController.php b/app/Http/Controllers/App/BillingController.php index 67836c76..3926bac5 100644 --- a/app/Http/Controllers/App/BillingController.php +++ b/app/Http/Controllers/App/BillingController.php @@ -143,16 +143,6 @@ public function swap(Request $request, Plan $plan): RedirectResponse 'Invalid price for this plan', ); - $currentPlan = $account->plan; - $isOnYearly = $currentPlan && $subscription->stripe_price === $currentPlan->stripe_yearly_price_id; - $isTargetMonthly = $priceId === $plan->stripe_monthly_price_id; - - abort_if( - $isOnYearly && $isTargetMonthly, - 422, - 'Cannot downgrade from yearly to monthly billing.', - ); - $authorization = Gate::inspect('swapPlan', [$account, $plan]); if ($authorization->denied()) { diff --git a/tests/Feature/BillingControllerTest.php b/tests/Feature/BillingControllerTest.php index 003f1772..78be2a60 100644 --- a/tests/Feature/BillingControllerTest.php +++ b/tests/Feature/BillingControllerTest.php @@ -244,33 +244,6 @@ ])); }); -test('swap blocks yearly to monthly downgrade', function () { - config(['trypost.self_hosted' => false]); - - $plan = Plan::where('slug', 'max')->first(); - $plan->update([ - 'stripe_monthly_price_id' => 'price_monthly', - 'stripe_yearly_price_id' => 'price_yearly', - ]); - $this->account->update(['plan_id' => $plan->id]); - - $this->user->unsetRelation('account'); - - $this->account->subscriptions()->create([ - 'type' => Account::SUBSCRIPTION_NAME, - 'stripe_id' => 'sub_test_'.fake()->uuid(), - 'stripe_status' => 'active', - 'stripe_price' => 'price_yearly', - ]); - - $response = $this->actingAs($this->user) - ->post(route('app.billing.swap', $plan), [ - 'price_id' => 'price_monthly', - ]); - - $response->assertStatus(422); -}); - test('swap rejects invalid price_id for plan', function () { config(['trypost.self_hosted' => false]);