Phase 9E (Abschluss): Checkout-Flows und Plan-Kontingent statt Quota-Stub
- Checkout-Backend: me.checkout.subscription (Tarif-Abo monatlich/jährlich)
und me.checkout.single-pm (Einzel-PM 19 € netto, pending-Kauf mit
Webhook-Erfüllung); StripeCheckoutService als mockbarer Stripe-Wrapper;
Stripe Tax via Cashier::calculateTaxes() (Netto-Preise, USt-ID-Abfrage)
- Slot-Logik: Kontingent aus dem Tarif (plans.press_release_quota) plus
bezahlte Einmalkäufe; Verbrauch bei Veröffentlichung zuerst aus dem
Plan-Zähler, danach Einlösung des ältesten Einmalkaufs (consumed +
PM-Verknüpfung); Grandfathered = unbegrenzt (Entscheidung 12.06.2026,
Bestandsschutz); Stub-Spalte users.press_release_quota entfernt
- billing:sync-stripe-plans legt zusätzlich das Einzel-PM-Produkt an
(STRIPE_PRICE_SINGLE_PM); Test-Mode-Sync gelaufen
- Buchungs-Seite: Rückmeldung nach Checkout (erfolg/abbruch/Guard-Hinweis)
- Tests: PressReleaseQuotaTest auf Plan-Semantik neu geschrieben,
CheckoutFlowTest (8 Tests), Modal-/API-Tests angepasst; Suite 510 passed
- Doku: Billing-und-Rechnungskreise (Kontingent-Tabelle, Checkout-Routen,
Webhook-Events, Stripe-CLI-Hinweis), PHASE-9-Plan 9E ✅, Checkliste,
STATUS-ABGLEICH, PROGRESS
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
38fab64e10
commit
c8dc99c3c8
24 changed files with 775 additions and 100 deletions
|
|
@ -41,7 +41,7 @@ Phase 9 setzt das Decision-Update vom 11./12.06.2026 um — in zwei Blöcken:
|
|||
| **9C** ✅ | Submit-Gate-Schnittstelle (`hasActiveBooking()`-Stub, Modal-Hinweis, Server-Guard) + Fix: Create-Form lief am Funnel vorbei | M | gering |
|
||||
| — | **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 — Backbone ✅ (Produkt-Sync nach Stripe, Webhook-Listener mit STR-Spiegelung + Einmalkauf-Erfüllung); offen: Checkout-Flows, Webhook-Endpoint registrieren, Slot-Logik auf Plan-Kontingent | L | mittel |
|
||||
| **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 |
|
||||
| **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 |
|
||||
|
|
@ -180,20 +180,26 @@ ist hybrid mit zwei getrennten Rechnungskreisen (plus Altbestand):
|
|||
`user_payment_options` (Replay-fähig — die Kern-Migration läuft kurz
|
||||
vor dem Relaunch erneut). Details:
|
||||
`dev/migration 2026/05-DATABASE-MERGE.md` §5.6 + `MIGRATION-STEPS.md`.
|
||||
- **Noch offen in 9D** (folgt mit 9E, braucht Checkout/Webhooks):
|
||||
Slot-Logik von `users.press_release_quota`-Stub auf Plan-Kontingent +
|
||||
Periodenzähler umstellen und Stub-Spalten entfernen.
|
||||
- ~~Noch offen in 9D~~ → mit 9E erledigt: Slot-Logik auf Plan-Kontingent
|
||||
umgestellt, Stub-Spalte entfernt.
|
||||
|
||||
### 9E · Stripe (Laravel Cashier)
|
||||
### 9E · Stripe (Laravel Cashier) ✅ (12.06.2026)
|
||||
|
||||
- Checkout für Abo (monatlich/jährlich) und Einmalzahlung (Einzel-PM, Credits);
|
||||
Stripe-Produkte/Preise anlegen und IDs in `plans` pflegen.
|
||||
- Webhooks (Subscription-Status, Zahlungsausfall, `invoice.paid`) + Spiegelung
|
||||
der Stripe-Rechnungen in `invoices` mit STR-Nummer aus dem
|
||||
`InvoiceNumberGenerator`.
|
||||
- Slot-Logik auf Plan-Kontingent umstellen (siehe 9D-Rest), Stub ablösen.
|
||||
- Benötigt `STRIPE_KEY`/`STRIPE_SECRET`/`STRIPE_WEBHOOK_SECRET` in `.env`
|
||||
(aktuell nicht gesetzt).
|
||||
- ✅ Produkt-Sync: `billing:sync-stripe-plans` legt Tarife (Monats-/Jahres-
|
||||
preise) und das Einzel-PM-Produkt als Netto-Preise in Stripe an
|
||||
(Test-Mode gelaufen; IDs in `plans` bzw. `STRIPE_PRICE_SINGLE_PM`).
|
||||
- ✅ Webhooks: `ProcessStripeWebhook` spiegelt bezahlte Stripe-Rechnungen
|
||||
mit STR-Nummer in `invoices` und erfüllt Einmalkäufe; Endpoint
|
||||
`https://pressekonto.com/stripe/webhook` registriert, Secret gesetzt.
|
||||
- ✅ Checkout-Flows (Backend): `me.checkout.subscription` +
|
||||
`me.checkout.single-pm` (CheckoutController → StripeCheckoutService);
|
||||
Stripe Tax via `Cashier::calculateTaxes()` (Netto-Preise). UI-Anbindung
|
||||
der Buttons folgt in 9F.
|
||||
- ✅ Slot-Logik: Plan-Kontingent + Einmalkauf-Verbrauch statt Stub;
|
||||
**Grandfathered = unbegrenzt** (Entscheidung 12.06.2026, Bestandsschutz).
|
||||
Details: `docs/user-admin/Billing-und-Rechnungskreise.md` §2.
|
||||
- Offen → §7 der Billing-Doku: Stripe Tax im Dashboard aktivieren,
|
||||
Live-Mode-Sync vor Relaunch.
|
||||
|
||||
### 9F · Tarif-Seite + Checkout-UI
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue