active()->where('slug', $planSlug)->firstOrFail(); $user = $request->user(); if ($user->subscribed()) { return $this->backToBookings(__('Es besteht bereits ein aktives Abo. Ein Tarifwechsel ist aktuell über den Support möglich.')); } $priceId = $interval === 'yearly' ? $plan->stripe_price_id_yearly : $plan->stripe_price_id_monthly; if (! $priceId) { return $this->backToBookings(__('Dieser Tarif ist noch nicht buchbar. Bitte versuchen Sie es später erneut.')); } return $this->checkout->forSubscription($user, $plan, $interval); } public function singlePm(Request $request): Checkout|RedirectResponse { if (! config('billing.single_pm_stripe_price_id')) { return $this->backToBookings(__('Die Einzel-Pressemitteilung ist noch nicht buchbar. Bitte versuchen Sie es später erneut.')); } $purchase = SinglePurchase::query()->create([ 'user_id' => $request->user()->id, 'type' => SinglePurchaseType::SinglePm->value, 'status' => SinglePurchaseStatus::Pending->value, 'price_cents' => (int) config('billing.single_pm_price_cents'), 'currency' => 'EUR', ]); return $this->checkout->forSinglePurchase($request->user(), $purchase); } /** * Stripe Billing Portal: Selbstverwaltung des Abos (Zahlungsmethode, * Rechnungen, Kündigung). Nur mit aktivem Abo sinnvoll. */ public function billingPortal(Request $request): RedirectResponse { $user = $request->user(); if (! $user->hasStripeId() || ! $user->subscribed()) { return $this->backToBookings(__('Es besteht kein aktives Abo, das verwaltet werden könnte.')); } return redirect()->away($this->checkout->billingPortalUrl($user)); } private function backToBookings(string $notice): RedirectResponse { return redirect() ->route('me.bookings.index') ->with('checkout-notice', $notice); } }