'Guests 100', 'increments' => ['extra_guests' => 100], 'price_id' => 'pri_guests', ]); $package = Package::factory()->endcustomer()->create([ 'max_guests' => 50, ]); $event = Event::factory()->for($this->tenant)->create([ 'status' => 'published', ]); $eventPackage = EventPackage::create([ 'event_id' => $event->id, 'package_id' => $package->id, 'purchased_price' => $package->price, 'purchased_at' => now(), 'used_photos' => 0, 'used_guests' => 0, 'gallery_expires_at' => now()->addDays(7), ]); $addon = EventPackageAddon::create([ 'event_package_id' => $eventPackage->id, 'event_id' => $event->id, 'tenant_id' => $this->tenant->id, 'addon_key' => 'extra_guests', 'quantity' => 1, 'extra_guests' => 100, 'status' => 'pending', 'metadata' => [ 'addon_intent' => 'intent-123', ], ]); $payload = [ 'event_type' => 'transaction.completed', 'data' => [ 'id' => 'txn_addon_1', 'custom_data' => [ 'addon_intent' => 'intent-123', 'addon_key' => 'extra_guests', ], ], ]; $handler = app(EventAddonWebhookService::class); $handled = $handler->handle($payload); $this->assertTrue($handled); $addon->refresh(); $eventPackage->refresh(); $this->assertSame('completed', $addon->status); $this->assertSame('txn_addon_1', $addon->transaction_id); $this->assertSame(100, $eventPackage->extra_guests); Notification::assertSentTimes(AddonPurchaseReceipt::class, 1); } public function test_webhook_uses_stored_increments_over_catalog(): void { Notification::fake(); Config::set('package-addons.extra_guests', [ 'label' => 'Guests 50', 'increments' => ['extra_guests' => 50], 'price_id' => 'pri_guests', ]); $package = Package::factory()->endcustomer()->create([ 'max_guests' => 50, ]); $event = Event::factory()->for($this->tenant)->create([ 'status' => 'published', ]); $eventPackage = EventPackage::create([ 'event_id' => $event->id, 'package_id' => $package->id, 'purchased_price' => $package->price, 'purchased_at' => now(), 'used_photos' => 0, 'used_guests' => 0, 'gallery_expires_at' => now()->addDays(7), ]); $addon = EventPackageAddon::create([ 'event_package_id' => $eventPackage->id, 'event_id' => $event->id, 'tenant_id' => $this->tenant->id, 'addon_key' => 'extra_guests', 'quantity' => 2, 'extra_guests' => 400, 'status' => 'pending', 'metadata' => [ 'addon_intent' => 'intent-456', 'increments' => ['extra_guests' => 200], ], ]); $payload = [ 'event_type' => 'transaction.completed', 'data' => [ 'id' => 'txn_addon_2', 'custom_data' => [ 'addon_intent' => 'intent-456', 'addon_key' => 'extra_guests', ], ], ]; $handler = app(EventAddonWebhookService::class); $handled = $handler->handle($payload); $this->assertTrue($handled); $addon->refresh(); $eventPackage->refresh(); $this->assertSame('completed', $addon->status); $this->assertSame('txn_addon_2', $addon->transaction_id); $this->assertSame(400, $eventPackage->extra_guests); Notification::assertSentTimes(AddonPurchaseReceipt::class, 1); } }