- {{ __('verfügbare Credits') }} -
-diff --git a/app/Http/Controllers/CheckoutController.php b/app/Http/Controllers/CheckoutController.php index 440535c..b2460a2 100644 --- a/app/Http/Controllers/CheckoutController.php +++ b/app/Http/Controllers/CheckoutController.php @@ -60,6 +60,21 @@ class CheckoutController extends Controller 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() diff --git a/app/Services/Billing/StripeCheckoutService.php b/app/Services/Billing/StripeCheckoutService.php index f83ad31..693f9ad 100644 --- a/app/Services/Billing/StripeCheckoutService.php +++ b/app/Services/Billing/StripeCheckoutService.php @@ -35,6 +35,15 @@ class StripeCheckoutService ]); } + /** + * URL zum Stripe Billing Portal (Zahlungsmethode, Rechnungen, Kündigung). + * Rücksprung auf die Buchungs-Seite. + */ + public function billingPortalUrl(User $user): string + { + return $user->billingPortalUrl(route('me.bookings.index')); + } + /** * Stripe-Checkout für eine Einzel-PM. Die `single_purchase_id` in den * Session-Metadaten schließt den Kreis: `checkout.session.completed` diff --git a/dev/frontend/hub-flux/PROGRESS.md b/dev/frontend/hub-flux/PROGRESS.md index bd30481..e433d92 100644 --- a/dev/frontend/hub-flux/PROGRESS.md +++ b/dev/frontend/hub-flux/PROGRESS.md @@ -5,6 +5,28 @@ --- +## 2026-06-12 · Phase 9F · Tarif-Seite + Checkout-UI ✅ + +- **Was**: „Buchungen & Add-ons" vom Credit-Konzept-Mock auf echte Daten + umgestellt: 4-Tier-Raster aus `plans` (Alpine Monat/Jahr-Toggle, + „2 Monate gratis"), Checkout-Buttons auf die 9E-Routen, Einzel-PM als + separater No-Abo-Block, Aktueller-Tarif-Panel (Abo / Bestandstarif + unbegrenzt / offene Einzelkäufe / leer) mit Kontingent-Kachel, + „Abo verwalten" → Stripe Billing Portal (neue Route + `me.checkout.billing-portal`), aktive Buchungen + Verlauf real. + Credit-Pakete/Marktplatz/Platzierungen entfernt (→ 9I bzw. Phase 2). + Stripe Tax im Dashboard aktiviert („SaaS – business use", exklusiv). +- **Dateien**: `resources/views/livewire/customer/bookings.blade.php` + (Neufassung), `app/Http/Controllers/CheckoutController.php` + + `app/Services/Billing/StripeCheckoutService.php` (Billing Portal), + `routes/customer.php`. +- **Build/Test**: Suite 519 passed / 4 skipped, Pint clean; 9 neue Tests + in `BookingsPageTest`, `PanelConsolidationTest` auf neue Seite angepasst. +- **Offene Fragen**: Stripe Tax + Produkt-Sync vor Relaunch im Live-Mode + wiederholen. +- **Nächster Schritt**: 9G Tageslimit (`plans.daily_limit` beim + Veröffentlichen), dann 9H Einzel-PM-Abo-Brücke, 9I Launch-Credits. + ## 2026-06-12 · Phase 9E · Stripe-Anbindung komplett ✅ - **Was**: Produkt-Sync nach Stripe (Tarife + Einzel-PM, Netto-Preise, diff --git a/docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md b/docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md index 75a766c..17fcfe0 100644 --- a/docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md +++ b/docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md @@ -42,7 +42,7 @@ Phase 9 setzt das Decision-Update vom 11./12.06.2026 um — in zwei Blöcken: | — | **Review-Stopp mit User** | | | | **9D** ✅ | Tarif-Datenmodell: Pläne, Einzelkäufe, Cashier, Rechnungskreise STR-/MAN-, MAN-Fälligkeitslauf (Stub-Ablösung folgt mit 9E) | L | hoch (Datenmodell) | | **9E** ✅ | Stripe-Anbindung: Produkt-Sync (Tarife + Einzel-PM), Webhook-Verarbeitung (STR-Spiegelung, Einmalkauf-Erfüllung, Endpoint registriert), Checkout-Flows (Backend), Slot-Logik auf Plan-Kontingent (Grandfathered = unbegrenzt), Stripe Tax | L | mittel | -| **9F** | Tarif-Seite + Checkout-UI (Raster, Einzel-PM-Block, „2 Monate gratis", Enterprise-Hinweis) | M | gering | +| **9F** ✅ | Tarif-Seite + Checkout-UI: Buchungs-Seite mit echtem 4-Tier-Raster (Monat/Jahr-Toggle, „2 Monate gratis"), Einzel-PM-Block, Bestandstarif-Anzeige, „Abo verwalten" (Stripe Billing Portal), Enterprise-Hinweis | M | gering | | **9G** | Tageslimit je Tier (Business 2 / Pro 3 / Agency 5; gilt auch für Extra-PMs) | S | gering | | **9H** | Einzel-PM-Kauf (19 €) + Einzel→Abo-Brücke (Anrechnung 30 Tage) | M | mittel | | **9I** | Launch-Credits: Extra-PM, Boost (nur Grün), Veröffentlichungsnachweis-PDF | L | mittel | @@ -201,12 +201,22 @@ ist hybrid mit zwei getrennten Rechnungskreisen (plus Altbestand): - Offen → §7 der Billing-Doku: Stripe Tax im Dashboard aktivieren, Live-Mode-Sync vor Relaunch. -### 9F · Tarif-Seite + Checkout-UI +### 9F · Tarif-Seite + Checkout-UI ✅ (12.06.2026) -- Raster mit 4 Tiers; Einzel-PM als separater No-Abo-Block (nicht als - billigste Spalte); Enterprise als dezenter Sales-Hinweis unter der Tabelle. -- Jahrespreis kommuniziert als „2 Monate gratis". -- Einstieg aus dem Submit-Gate-Hinweis (9C) und aus „Buchungen & Add-ons". +- ✅ „Buchungen & Add-ons" zeigt das echte 4-Tier-Raster aus `plans` + (Monat/Jahr-Toggle, Jahrespreis als „2 Monate gratis") mit + Checkout-Buttons auf `me.checkout.subscription`; Einzel-PM als + separater No-Abo-Block (`me.checkout.single-pm`); Enterprise als + dezenter Hinweis unter dem Raster. Der Credit-Konzept-Mock ist + abgelöst (Credits → 9I bzw. Phase 2). +- ✅ Aktueller Tarif real: Abo (Preis, Kontingent, Kündigungsstatus), + Bestandstarif (unbegrenzt, nächste MAN-Rechnung) oder offene + Einzelkäufe; Kontingent-Kachel (`Unbegrenzt` bei Bestandsschutz). +- ✅ „Abo verwalten" → Stripe Billing Portal (`me.checkout.billing-portal`: + Zahlungsmethode, Rechnungen, Kündigung). +- ✅ Aktive Buchungen + Verlauf aus echten Daten (Abo, Legacy-Vereinbarung, + offene/eingelöste Einzelkäufe mit PM-Verknüpfung). +- Einstieg aus dem Submit-Gate-Hinweis (9C) führt bereits hierher. ### 9G · Tageslimit diff --git a/docs/STATUS-ABGLEICH-USER-PANEL.md b/docs/STATUS-ABGLEICH-USER-PANEL.md index e3eab0d..3b2463b 100644 --- a/docs/STATUS-ABGLEICH-USER-PANEL.md +++ b/docs/STATUS-ABGLEICH-USER-PANEL.md @@ -128,8 +128,8 @@ Zentrale Billing-Referenz: [`user-admin/Billing-und-Rechnungskreise.md`](./user- | Rechnungen mit Legacy-Archiv | umgesetzt | ✅ | | Hybride Rechnungskreise STR-/MAN- (Decision 12.06.) | umgesetzt (Phase 9D) — Nummern-Generator, MAN-Fälligkeitslauf, Grandfather-Migration, USt-Logik (`VatResolver`) | ✅ | | Tarif-Datenmodell + Cashier | umgesetzt (Phase 9D) — `plans`, `single_purchases`, `User` ist Billable | ✅ | -| Stripe-Checkout/Webhooks + STR-Spiegelung | umgesetzt (Phase 9E) — Produkt-Sync, Webhook-Verarbeitung, Checkout-Backend, Plan-Kontingent | ✅ (UI → 9F) | -| Buchungen & Add-ons (UI) | nur Stub | 📝 (mit 9F Tarif-Seite) | +| Stripe-Checkout/Webhooks + STR-Spiegelung | umgesetzt (Phase 9E) — Produkt-Sync, Webhook-Verarbeitung, Checkout-Backend, Plan-Kontingent | ✅ | +| Buchungen & Add-ons (UI) | umgesetzt (Phase 9F) — Tarif-Raster, Einzel-PM-Block, Bestandstarife, Billing Portal | ✅ | | Zahlungsmethoden firmenscharf | **fehlt** | 📝 (Phase 2) | --- diff --git a/docs/user-admin/Billing-und-Rechnungskreise.md b/docs/user-admin/Billing-und-Rechnungskreise.md index 561413a..9245e09 100644 --- a/docs/user-admin/Billing-und-Rechnungskreise.md +++ b/docs/user-admin/Billing-und-Rechnungskreise.md @@ -1,8 +1,8 @@ # Billing & Rechnungskreise (hybrides Modell) Stand: 12.06.2026 — Datenmodell, MAN-Kreis, USt-Behandlung (Phase 9D) sowie -Stripe-Sync, Webhook-Verarbeitung, Checkout-Flows und Plan-Kontingent -(Phase 9E) umgesetzt. Es fehlt die Checkout-UI (Phase 9F). +Stripe-Sync, Webhook-Verarbeitung, Checkout-Flows, Plan-Kontingent +(Phase 9E) und Tarif-Seite/Checkout-UI (Phase 9F) umgesetzt. Dieses Dokument ist die zentrale Referenz für das Abrechnungssystem: Rechnungskreise, Tarif-Datenmodell, Steuerlogik, Befehle und Konfiguration. @@ -61,12 +61,13 @@ monatlicher Reset), danach wird der älteste bezahlte Einmalkauf eingelöst (`single_purchases.status → consumed`, verknüpft mit der PM). Die frühere Stub-Spalte `users.press_release_quota` ist entfernt. -**Checkout-Einstiege** (Phase 9E; UI-Anbindung folgt in 9F): +**Checkout-Einstiege** (Phase 9E/9F — verdrahtet auf der Buchungs-Seite): | Route | Zweck | |---|---| | `me.checkout.subscription` (`/admin/me/checkout/abo/{slug}/{monthly\|yearly}`) | Stripe-Checkout für ein Tarif-Abo | | `me.checkout.single-pm` (`/admin/me/checkout/einzel-pm`) | Stripe-Checkout Einzel-PM (legt `single_purchases`-Eintrag `pending` an; Webhook setzt `paid`) | +| `me.checkout.billing-portal` (`/admin/me/checkout/abo-verwalten`) | Stripe Billing Portal (Zahlungsmethode, Rechnungen, Kündigung) | Erfolg/Abbruch landen auf der Buchungs-Seite (`?checkout=erfolg|abbruch`). Die Steuer ergänzt **Stripe Tax** automatisch (`Cashier::calculateTaxes()` @@ -180,12 +181,12 @@ CLI ausgegebene `whsec_…` temporär als `STRIPE_WEBHOOK_SECRET` in die `.env`. Routen siehe Abschnitt 2), Slot-Logik auf Plan-Kontingent umgestellt (Grandfathered = unbegrenzt, Entscheidung 12.06.2026), Stub-Spalte entfernt, Stripe Tax aktiviert (`Cashier::calculateTaxes()`). -1. **Phase 9F**: Tarif-Seite/Buchungs-UI an die Checkout-Routen anbinden - (die Buchungs-Seite ist noch Konzept-Mock mit deaktivierten Buttons); - echte Tarif-/Buchungsdaten statt Platzhalter anzeigen. -2. **Stripe Tax im Dashboard aktivieren** (Ursprungsadresse/Registrierung - hinterlegen) — ohne das schlägt der Checkout mit automatischer Steuer - fehl. Im Test-Mode prüfen, dann im Live-Mode wiederholen; dort auch +1. **Phase 9F erledigt** (12.06.2026): Die Buchungs-Seite zeigt das echte + Tarif-Raster (Monat/Jahr-Toggle), den Einzel-PM-Block, Bestandstarife + und „Abo verwalten" (Stripe Billing Portal, `me.checkout.billing-portal`). +2. **Stripe Tax**: im Dashboard aktiviert (12.06.2026, Produkt-Steuercode + „SaaS – business use", Steuer nicht im Preis enthalten — passt zu den + Netto-Preisen). Vor Relaunch im **Live-Mode** wiederholen; dort auch `billing:sync-stripe-plans` erneut ausführen (Live-Produkt-IDs). 3. **VIES-Validierung** der USt-ID (aktuell Formatprüfung; Stripe prüft die im Checkout erfasste USt-ID asynchron selbst). diff --git a/docs/user-admin/checkliste-user-backend.md b/docs/user-admin/checkliste-user-backend.md index d6bff00..51b05dc 100644 --- a/docs/user-admin/checkliste-user-backend.md +++ b/docs/user-admin/checkliste-user-backend.md @@ -129,6 +129,7 @@ Verbindliche Entscheidungen: `docs/Decision-Update Preisstruktur & Veröffentlic - [x] USt-Behandlung (12.06.): alle neuen Preise netto; `VatResolver` (DE immer Steuer, EU nur mit USt-ID befreit/Reverse Charge, Drittland befreit), `vat_id` an Rechnungsadresse + Rechnungs-Snapshot, `tax_note` auf Rechnungen; Grandfathered rechnen auf Netto-Basis der letzten Legacy-Rechnung (Brutto bleibt fuer DE-Bestandskunden gleich). - [ ] VIES-Validierung der USt-ID (aktuell Formatpruefung) — vor Gate-/Checkout-Aktivierung. - [x] Stripe-Checkout + Webhooks (Phase 9E, 12.06.): Produkt-Sync nach Stripe (Tarife + Einzel-PM, netto, Stripe Tax), STR-Rechnungsspiegelung + Einmalkauf-Erfuellung per Webhook (Endpoint registriert), Checkout-Flows als Backend (`me.checkout.subscription`/`me.checkout.single-pm`), Slot-Logik auf Plan-Kontingent umgestellt (Grandfathered = unbegrenzt, Bestandsschutz), Quota-Stub-Spalte entfernt. UI-Anbindung folgt in 9F. Doku: `docs/user-admin/Billing-und-Rechnungskreise.md`. +- [x] Tarif-Seite + Checkout-UI (Phase 9F, 12.06.): Buchungs-Seite mit echtem 4-Tier-Raster (Monat/Jahr-Toggle, "2 Monate gratis"), Einzel-PM-Block, Bestandstarif-Anzeige (unbegrenzt), "Abo verwalten" via Stripe Billing Portal; Credit-Mock abgeloest (Credits → 9I/Phase 2). - [ ] Tageslimit je Tier (Business 2 / Pro 3 / Agency 5), gilt auch fuer Extra-PMs. - [ ] Launch-Credits: Extra-PM, Boost (nur gruene PMs), Veroeffentlichungsnachweis-PDF; Credit-Anker 1 Credit = 1 €. - [ ] Einzel→Abo-Bruecke (19 € Anrechnung innerhalb 30 Tagen). diff --git a/resources/views/livewire/customer/bookings.blade.php b/resources/views/livewire/customer/bookings.blade.php index fde55b5..b7fc5b5 100644 --- a/resources/views/livewire/customer/bookings.blade.php +++ b/resources/views/livewire/customer/bookings.blade.php @@ -1,103 +1,74 @@ user(); + $subscription = $user->subscription(); + $currentPlan = $user->currentPlan(); + + $currentInterval = null; + if ($currentPlan && $subscription) { + $currentInterval = $subscription->stripe_price === $currentPlan->stripe_price_id_yearly + ? 'yearly' + : 'monthly'; + } + return [ // Rückkehr aus dem Stripe-Checkout (?checkout=erfolg|abbruch) // bzw. Hinweis aus den Checkout-Guards (Session-Flash). 'checkoutResult' => request()->query('checkout'), 'checkoutNotice' => session('checkout-notice'), - 'creditSummary' => [ - 'total' => 17, - 'bonus' => 12, - 'paid' => 5, - 'auto_refill' => __('ab 10 Credits empfohlen'), - 'validity' => __('Bonus-Credits verfallen monatlich, gekaufte Credits bleiben 24 Monate gültig.'), - ], - 'currentPlan' => [ - 'name' => 'Starter', - 'price' => '19 €/Mo.', - 'press_releases' => '3 PMs/Monat', - 'bonus_credits' => 12, - ], - 'creditPackages' => [ - ['name' => 'Test', 'credits' => 10, 'price' => '10 €', 'rate' => '1,00 €', 'saving' => null], - ['name' => 'Standard', 'credits' => 50, 'price' => '45 €', 'rate' => '0,90 €', 'saving' => '10 %'], - ['name' => 'Plus', 'credits' => 150, 'price' => '120 €', 'rate' => '0,80 €', 'saving' => '20 %'], - ['name' => 'Pro', 'credits' => 500, 'price' => '375 €', 'rate' => '0,75 €', 'saving' => '25 %'], - ['name' => 'Business', 'credits' => 1500, 'price' => '1.050 €', 'rate' => '0,70 €', 'saving' => '30 %'], - ], - 'serviceGroups' => [ - [ - 'title' => __('Veröffentlichung'), - 'description' => __('Basisleistungen rund um Veröffentlichung, Korrektur und Aktualisierung.'), - 'services' => [ - ['name' => __('Standard-PM (Pay-as-you-go)'), 'credits' => '19', 'meta' => __('1 Veröffentlichung')], - ['name' => __('PM-Korrektur'), 'credits' => '8', 'meta' => __('Pfad C')], - ['name' => __('PM-Update'), 'credits' => '4', 'meta' => __('im ersten Jahr ggf. kostenlos')], - ['name' => __('Depublizierung'), 'credits' => '19–25', 'meta' => __('abhängig vom Aufwand')], - ], - ], - [ - 'title' => __('Bilder'), - 'description' => __('Stock- und KI-Bilder für mehr Sichtbarkeit in Listen und Detailseiten.'), - 'services' => [ - ['name' => __('Free-Stock'), 'credits' => '0', 'meta' => __('Unsplash, Pexels')], - ['name' => __('Premium-Stock'), 'credits' => '8', 'meta' => __('Adobe, Shutterstock')], - ['name' => __('KI-Bild generieren'), 'credits' => '4', 'meta' => __('neues Motiv')], - ['name' => __('KI-Bild Re-Generation'), 'credits' => '2', 'meta' => __('Variante erzeugen')], - ], - ], - [ - 'title' => __('KI-Textservices'), - 'description' => __('Qualität verbessern, Score-Stufe erreichen und bessere Headlines testen.'), - 'services' => [ - ['name' => __('Quality-Check'), 'credits' => '3', 'meta' => __('Stil und Pressestil')], - ['name' => __('Lektorat'), 'credits' => '8', 'meta' => __('sprachliche Prüfung')], - ['name' => __('Pressetext-Optimierung'), 'credits' => '15', 'meta' => __('Headlines und SEO')], - ['name' => __('Headline-Booster'), 'credits' => '5', 'meta' => __('nur Headlines')], - ['name' => __('PM aus Stichworten generieren'), 'credits' => '25', 'meta' => __('Entwurf aus Briefing')], - ['name' => __('Übersetzung DE/EN'), 'credits' => '12', 'meta' => __('pro Sprachrichtung')], - ], - ], - [ - 'title' => __('Distribution'), - 'description' => __('Zusätzliche Formate und externe Reichweite für passende Meldungen.'), - 'services' => [ - ['name' => __('PDF-Export mit Branding'), 'credits' => '2', 'meta' => __('für Weitergabe')], - ['name' => __('Social-Snippet-Generierung'), 'credits' => '3', 'meta' => __('Kurztexte')], - ['name' => __('Verteiler-Versand klein'), 'credits' => '39', 'meta' => __('branchenspezifisch')], - ['name' => __('Verteiler-Versand mittel'), 'credits' => '99', 'meta' => __('mehr Empfänger')], - ['name' => __('Verteiler-Versand groß'), 'credits' => '199', 'meta' => __('branchenübergreifend')], - ], - ], - [ - 'title' => __('Account & Profil'), - 'description' => __('Vertrauen, Wiedererkennung und zusätzliche Profilfunktionen.'), - 'services' => [ - ['name' => __('Verifiziertes Firmenprofil'), 'credits' => '79', 'meta' => __('einmalig')], - ['name' => __('Custom Subdomain'), 'credits' => '49', 'meta' => __('pro Jahr')], - ['name' => __('Erweiterte Statistiken'), 'credits' => '15', 'meta' => __('pro Monat')], - ], - ], - ], - 'placements' => [ - ['name' => __('Highlight Kategorie'), 'credits' => '15', 'duration' => __('3 Tage'), 'tier' => __('Standard'), 'score' => '30+'], - ['name' => __('Highlight Kategorie'), 'credits' => '30', 'duration' => __('7 Tage'), 'tier' => __('Standard'), 'score' => '30+'], - ['name' => __('Startseite-Highlight'), 'credits' => '39', 'duration' => __('24 h'), 'tier' => __('Geprüft'), 'score' => '60+'], - ['name' => __('Startseite-Highlight'), 'credits' => '89', 'duration' => __('3 Tage'), 'tier' => __('Geprüft'), 'score' => '60+'], - ['name' => __('Top-Slot Startseite'), 'credits' => '119', 'duration' => __('24 h'), 'tier' => __('Hochwertig'), 'score' => '80+'], - ['name' => __('Newsletter-Erwähnung'), 'credits' => '59', 'duration' => __('nächster Versand'), 'tier' => __('Geprüft'), 'score' => '60+'], - ['name' => __('Social-Share'), 'credits' => '25', 'duration' => __('offizieller Kanal'), 'tier' => __('Geprüft'), 'score' => '60+'], - ], - 'activeBookings' => [], - 'bookingHistory' => [], + + 'plans' => Plan::query()->active()->get(), + 'currentPlan' => $currentPlan, + 'currentInterval' => $currentInterval, + 'subscription' => $subscription, + + // Bestandstarife: laufende Legacy-Vereinbarungen (MAN-Kreis, + // unbegrenzte PMs — Entscheidung 12.06.2026). + 'legacyOptions' => $user->userPaymentOptions() + ->whereIn('status', [ + UserPaymentOptionStatus::Active->value, + UserPaymentOptionStatus::Grandfathered->value, + ]) + ->orderBy('current_period_end') + ->get(), + + 'openPurchases' => $user->singlePurchases() + ->grantingSubmission() + ->orderBy('paid_at') + ->get(), + 'consumedPurchases' => $user->singlePurchases() + ->where('status', SinglePurchaseStatus::Consumed->value) + ->with('pressRelease') + ->latest('consumed_at') + ->limit(10) + ->get(), + + 'quotaRemaining' => $user->pressReleaseQuotaRemaining(), + 'quotaTotal' => $user->pressReleaseQuotaTotal(), + 'singlePmPrice' => $this->formatEuro((int) config('billing.single_pm_price_cents')), + 'singlePmAvailable' => (bool) config('billing.single_pm_stripe_price_id'), ]; } }; ?> @@ -137,13 +108,12 @@ new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class exte
- {{ __('Der Marktplatz für Credit-Pakete, KI-Services, Platzierungen und Firmen-Add-ons. Die Preise folgen dem neuen Credit-Modell: 1 Credit entspricht dem Listenwert von 1 €.') }} + {{ __('Tarif wählen oder einzelne Pressemitteilung buchen. Alle Preise sind Nettopreise zzgl. USt.; die Abrechnung erfolgt sicher über Stripe.') }}
@@ -151,221 +121,234 @@ new #[Layout('components.layouts.app'), Title('Buchungen & Add-ons')] class exte- {{ __('verfügbare Credits') }} -
-- {{ __('inkl. :credits Bonus-Credits und :pms', [ - 'credits' => $currentPlan['bonus_credits'], - 'pms' => $currentPlan['press_releases'], - ]) }} -
-- {{ __('Bei mehreren PMs mit KI-Optimierung oder Platzierungen ergänzt das Standard-Paket die monatlichen Bonus-Credits am saubersten.') }} -
-
+ {{ __(':quota Pressemitteilungen pro Monat', ['quota' => $currentPlan->press_release_quota]) }}
+ @if ($currentPlan->daily_limit)
+ · {{ __('max. :limit Veröffentlichungen pro Tag', ['limit' => $currentPlan->daily_limit]) }}
@endif
-
-
+ {{ __('Gekündigt — läuft am :date aus.', ['date' => $subscription->ends_at?->format('d.m.Y')]) }} +
+ @endif + @elseif ($legacyOptions->isNotEmpty()) + @foreach ($legacyOptions as $option) ++ {{ __('Unbegrenzte Pressemitteilungen (Bestandsschutz).') }} + @if ($option->current_period_end) + {{ __('Nächste Rechnung am :date.', ['date' => $option->current_period_end->format('d.m.Y')]) }} + @endif +
++ {{ __('Ihre bisherigen Konditionen gelten unverändert weiter; die Abrechnung erfolgt wie gewohnt per Rechnung.') }} +
+ @elseif ($openPurchases->isNotEmpty()) ++ {{ __('Jeder Kauf berechtigt zu genau einer Veröffentlichung — eingelöst wird er erst, wenn die Pressemitteilung live geht.') }} +
+ @else ++ {{ __('Wählen Sie unten einen Tarif oder buchen Sie eine einzelne Pressemitteilung ohne Abo.') }} +
+ @endif ++ {{ __('Zahlungsmethode, Rechnungen und Kündigung — sicher über das Stripe-Kundenportal.') }} +
+ @endif +- {{ __('Platzierungen bleiben an Qualitätsstufen gekoppelt: Standard reicht für Kategorie-Highlights, Geprüft für Startseite/Newsletter/Social und Hochwertig für den Top-Slot.') }} -
+ {{-- ============== TARIF-RASTER ============== --}} ++ {{ __('Monatlich kündbar. Im Jahrestarif sind 2 Monate gratis — Sie zahlen 10 von 12 Monaten.') }} +
+- {{ $placement['duration'] }} -
-+ {{ __('Mehr als 60 Pressemitteilungen pro Monat, mehrere Teams oder Sonderkonditionen? Enterprise-Konditionen erhalten Sie auf Anfrage über den Support.') }} +
- {{-- ============== SERVICE-MARKTPLATZ ============== --}} -+ {{ __('Genau eine Veröffentlichung inklusive KI-Prüfung. Eingelöst wird der Kauf erst, wenn die Pressemitteilung live geht — Ablehnungen kosten nichts.') }} + @if ($openPurchases->isNotEmpty()) + + {{ trans_choice('Aktuell :count offener Kauf.|Aktuell :count offene Käufe.', $openPurchases->count(), ['count' => $openPurchases->count()]) }} + + @endif +
+- {{ $group['description'] }} -
-- {{ __('Gebuchte Highlights, Newsletter-Platzierungen oder Add-ons erscheinen hier mit Laufzeit und zugehöriger Firma.') }} + {{ __('Ihr Abo, Bestandstarife und offene Einzelkäufe erscheinen hier mit Laufzeit und Abrechnungsart.') }}
- {{ __('Nach dem ersten Checkout werden Verbrauch, Rechnungsbezug und betroffene Pressemitteilung hier nachvollziehbar.') }} + {{ __('Eingelöste Einzelkäufe erscheinen hier mit der zugehörigen Pressemitteilung.') }}