Downgrade-Vorkehrungen: Kontingent-Sperre beim Tarifwechsel, Gutschriften nicht spiegeln
QA-Befund 07.07.: Der Wechsel zurück in einen kleineren Tarif erzeugte eine Proration-Gutschrift (negative Stripe-Rechnung) — die STR-Spiegelung crashte an den unsigned-Spalten (Webhook-500), und der Wechsel war trotz verbrauchtem Monatskontingent möglich. - ProcessStripeWebhook: Belege ohne positiven Rechnungsbetrag (Gutschrift/Null-Rechnung) werden geloggt übersprungen statt gespiegelt - CheckoutController::swap: Wechsel gesperrt, wenn der Monatsverbrauch das Kontingent des Ziel-Tarifs übersteigt (möglich ab Monatserstem) - Buchungs-Modal: erklärt die Sperre inkl. Datum statt Bestätigungs- Button; Proration-Hinweis deckt jetzt auch die Guthaben-Richtung ab Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
090a893cc6
commit
4b7f6d3f0f
6 changed files with 165 additions and 3 deletions
|
|
@ -94,6 +94,22 @@ class CheckoutController extends Controller
|
|||
return $this->backToBookings(__('Dieser Tarif ist bereits Ihr aktueller Tarif.'));
|
||||
}
|
||||
|
||||
// Downgrade-Vorkehrung (QA-Befund 07.07.): Der Kontingent-Zähler
|
||||
// läuft pro Kalendermonat — wer mehr PMs genutzt hat, als der
|
||||
// Ziel-Tarif monatlich enthält, bekäme beim sofortigen Wechsel die
|
||||
// anteilige Gutschrift für einen bereits konsumierten Monat. Solche
|
||||
// Wechsel sind erst ab dem nächsten Monatsersten möglich.
|
||||
$quotaUsed = (int) $user->press_release_quota_used_this_month;
|
||||
|
||||
if ($quotaUsed > (int) $plan->press_release_quota) {
|
||||
return $this->backToBookings(__('Ein Wechsel zu :plan ist erst ab dem :date möglich: Sie haben in diesem Monat bereits :used Pressemitteilungen genutzt — dieser Tarif enthält :quota pro Monat.', [
|
||||
'plan' => $plan->name,
|
||||
'date' => now()->addMonth()->startOfMonth()->format('d.m.Y'),
|
||||
'used' => $quotaUsed,
|
||||
'quota' => (int) $plan->press_release_quota,
|
||||
]));
|
||||
}
|
||||
|
||||
try {
|
||||
$this->checkout->swapSubscription($user, $plan, $interval);
|
||||
} catch (IncompletePayment $exception) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,21 @@ class ProcessStripeWebhook
|
|||
?? collect($stripeInvoice['total_taxes'] ?? $stripeInvoice['total_tax_amounts'] ?? [])->sum('amount'));
|
||||
$total = (int) ($stripeInvoice['total'] ?? $subtotal + $tax);
|
||||
|
||||
// Ein Tarifwechsel nach unten erzeugt eine Proration-Gutschrift:
|
||||
// Stripe meldet sie als "bezahlte" Rechnung mit negativem Betrag,
|
||||
// das Guthaben verbleibt als Kundenkonto-Saldo und mindert künftige
|
||||
// Rechnungen. In den STR-Rechnungsausgang gehört so ein Beleg nicht
|
||||
// (QA-Befund 07.07.: unsigned-Spalten → Webhook-500) — der Beleg
|
||||
// selbst bleibt bei Stripe einsehbar.
|
||||
if ($total <= 0) {
|
||||
Log::info('STR-Spiegelung übersprungen: Stripe-Beleg ohne positiven Rechnungsbetrag (Gutschrift/Null-Rechnung).', [
|
||||
'stripe_invoice_id' => $stripeInvoiceId,
|
||||
'total_cents' => $total,
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$invoice = Invoice::query()->create([
|
||||
'user_id' => $user->id,
|
||||
'invoice_billing_address_id' => $this->snapshotAddress($user, $stripeInvoice)->id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue