diff --git a/app/Livewire/OrderSuccess.php b/app/Livewire/OrderSuccess.php index 66517e25..a2469750 100644 --- a/app/Livewire/OrderSuccess.php +++ b/app/Livewire/OrderSuccess.php @@ -8,6 +8,7 @@ use Livewire\Attributes\Layout; use Livewire\Attributes\Title; use Livewire\Component; +use Stripe\Exception\InvalidRequestException; #[Layout('components.layout')] #[Title('Thank You for Your Purchase')] @@ -41,8 +42,11 @@ private function loadEmail(): ?string return $email; } - $stripe = Cashier::stripe(); - $checkoutSession = $stripe->checkout->sessions->retrieve($this->checkoutSessionId); + try { + $checkoutSession = Cashier::stripe()->checkout->sessions->retrieve($this->checkoutSessionId); + } catch (InvalidRequestException $e) { + return $this->redirect('/mobile'); + } if (! ($email = $checkoutSession?->customer_details?->email)) { return null; @@ -86,8 +90,11 @@ private function loadSubscription(): ?Subscription return Subscription::tryFrom($subscription); } - $stripe = Cashier::stripe(); - $priceId = $stripe->checkout->sessions->allLineItems($this->checkoutSessionId)->first()?->price->id; + try { + $priceId = Cashier::stripe()->checkout->sessions->allLineItems($this->checkoutSessionId)->first()?->price->id; + } catch (InvalidRequestException $e) { + return $this->redirect('/mobile'); + } if (! $priceId) { return null; diff --git a/tests/Feature/Livewire/OrderSuccessTest.php b/tests/Feature/Livewire/OrderSuccessTest.php index 8733b4d7..611120f7 100644 --- a/tests/Feature/Livewire/OrderSuccessTest.php +++ b/tests/Feature/Livewire/OrderSuccessTest.php @@ -12,6 +12,7 @@ use PHPUnit\Framework\Attributes\Test; use Stripe\Checkout\Session as CheckoutSession; use Stripe\Collection; +use Stripe\Exception\InvalidRequestException; use Stripe\LineItem; use Stripe\StripeClient; use Tests\TestCase; @@ -111,6 +112,34 @@ public function it_polls_for_updates_from_database() ->assertDontSee('License registration in progress'); } + #[Test] + public function it_redirects_to_mobile_route_when_checkout_session_is_not_found() + { + $mockStripeClient = $this->createMock(StripeClient::class); + + $mockStripeClient->checkout = new class {}; + + $mockStripeClient->checkout->sessions = new class + { + public function retrieve() + { + throw new InvalidRequestException('No such checkout.session'); + } + + public function allLineItems() + { + throw new InvalidRequestException('No such checkout.session'); + } + }; + + $this->app->bind(StripeClient::class, function ($app, $parameters) use ($mockStripeClient) { + return $mockStripeClient; + }); + + Livewire::test(OrderSuccess::class, ['checkoutSessionId' => 'not_a_real_checkout_session']) + ->assertRedirect('/mobile'); + } + private function mockStripeClient(): void { $mockCheckoutSession = CheckoutSession::constructFrom([