From 4cda4d3bdaf6e0614172fa9842391fa9eb6bf36b Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Tue, 7 Jul 2026 11:42:31 +0000 Subject: [PATCH] STR-Spiegelung: USt aus total_taxes lesen (Stripe-API ohne tax-Feld) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aktuelle Stripe-API-Versionen liefern kein Top-Level-`tax` mehr auf der Invoice — die Spiegelung buchte 0 USt und markierte die Rechnung als netto (QA-Befund 07.07., STR-00001). Fallback-Kette: tax (alt) → total_taxes (aktuell) → total_tax_amounts (Übergangsname). Co-Authored-By: Claude Fable 5 --- app/Listeners/ProcessStripeWebhook.php | 5 ++++- .../Billing/StripeWebhookProcessingTest.php | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/app/Listeners/ProcessStripeWebhook.php b/app/Listeners/ProcessStripeWebhook.php index 4e646e61..165c4d52 100644 --- a/app/Listeners/ProcessStripeWebhook.php +++ b/app/Listeners/ProcessStripeWebhook.php @@ -74,7 +74,10 @@ class ProcessStripeWebhook } $subtotal = (int) ($stripeInvoice['subtotal'] ?? 0); - $tax = (int) ($stripeInvoice['tax'] ?? 0); + // Steuer je nach Stripe-API-Generation: `tax` (alt), sonst Summe aus + // `total_taxes` (aktuell) bzw. `total_tax_amounts` (Übergangsname). + $tax = (int) ($stripeInvoice['tax'] + ?? collect($stripeInvoice['total_taxes'] ?? $stripeInvoice['total_tax_amounts'] ?? [])->sum('amount')); $total = (int) ($stripeInvoice['total'] ?? $subtotal + $tax); $invoice = Invoice::query()->create([ diff --git a/tests/Feature/Billing/StripeWebhookProcessingTest.php b/tests/Feature/Billing/StripeWebhookProcessingTest.php index fd93a3b1..7d906d8b 100644 --- a/tests/Feature/Billing/StripeWebhookProcessingTest.php +++ b/tests/Feature/Billing/StripeWebhookProcessingTest.php @@ -52,6 +52,25 @@ test('a paid stripe invoice is mirrored into the STR circle', function () { expect($invoice->invoiceBillingAddress->name)->toBe('Alpha GmbH'); }); +test('a current-api invoice without top-level tax reads total_taxes', function () { + // Stripe-API ab 2025: kein `tax`-Feld mehr, Steuer steht in `total_taxes` + // (QA-Befund 07.07.: USt. wurde als 0 gespiegelt). + $user = User::factory()->create(['stripe_id' => 'cus_test_1']); + + app(ProcessStripeWebhook::class)->handle(new WebhookReceived(stripeInvoicePayload($user, [ + 'tax' => null, + 'subtotal' => 2900, + 'total' => 3451, + 'total_taxes' => [['amount' => 551, 'taxable_amount' => 2900, 'tax_behavior' => 'exclusive']], + ]))); + + $invoice = Invoice::sole(); + expect($invoice->amount_cents)->toBe(2900); + expect($invoice->tax_cents)->toBe(551); + expect($invoice->total_cents)->toBe(3451); + expect($invoice->is_netto)->toBeFalse(); +}); + test('duplicate webhook deliveries do not create a second invoice', function () { $user = User::factory()->create(['stripe_id' => 'cus_test_1']); $listener = app(ProcessStripeWebhook::class);