catalog->find($addonKey)) { throw ValidationException::withMessages([ 'addon_key' => __('Unbekanntes Add-on.'), ]); } $variantId = $this->catalog->resolveVariantId($addonKey); if (! $variantId) { throw ValidationException::withMessages([ 'addon_key' => __('Für dieses Add-on ist kein Lemon Squeezy Variant hinterlegt.'), ]); } $event->loadMissing('eventPackage'); if (! $event->eventPackage) { throw ValidationException::withMessages([ 'event' => __('Kein Paket für dieses Event hinterlegt.'), ]); } $addonIntent = (string) Str::uuid(); $increments = $this->catalog->resolveIncrements($addonKey); $metadata = array_filter([ 'tenant_id' => (string) $tenant->id, 'event_id' => (string) $event->id, 'event_package_id' => (string) $event->eventPackage->id, 'addon_key' => $addonKey, 'addon_intent' => $addonIntent, 'quantity' => $quantity, 'lemonsqueezy_variant_id' => $variantId, 'legal_version' => $this->resolveLegalVersion(), 'accepted_terms' => $acceptedTerms ? '1' : '0', 'accepted_waiver' => $acceptedWaiver ? '1' : '0', 'success_url' => $payload['success_url'] ?? null, 'cancel_url' => $payload['cancel_url'] ?? null, ], static fn ($value) => $value !== null && $value !== ''); $response = $this->checkout->createVariantCheckout($variantId, $metadata, [ 'success_url' => $payload['success_url'] ?? null, 'return_url' => $payload['cancel_url'] ?? null, 'customer_email' => $tenant->contact_email ?? $tenant->user?->email, ]); $checkoutUrl = $response['checkout_url'] ?? null; $checkoutId = $response['id'] ?? null; $transactionId = null; if (! $checkoutUrl) { Log::warning('Lemon Squeezy addon checkout response missing url', ['response' => $response]); } EventPackageAddon::create([ 'event_package_id' => $event->eventPackage->id, 'event_id' => $event->id, 'tenant_id' => $tenant->id, 'addon_key' => $addonKey, 'quantity' => $quantity, 'variant_id' => $variantId, 'checkout_id' => $checkoutId, 'transaction_id' => $transactionId, 'status' => 'pending', 'metadata' => array_merge($metadata, [ 'increments' => $increments, 'provider_payload' => $response, 'consents' => [ 'legal_version' => $metadata['legal_version'], 'accepted_terms_at' => $acceptedTerms ? now()->toIso8601String() : null, 'digital_content_waiver_at' => $acceptedWaiver ? now()->toIso8601String() : null, ], ]), 'extra_photos' => ($increments['extra_photos'] ?? 0) * $quantity, 'extra_guests' => ($increments['extra_guests'] ?? 0) * $quantity, 'extra_gallery_days' => ($increments['extra_gallery_days'] ?? 0) * $quantity, ]); return [ 'checkout_url' => $checkoutUrl, 'expires_at' => $response['expires_at'] ?? null, 'id' => $checkoutId, ]; } protected function resolveLegalVersion(): string { return config('app.legal_version', now()->toDateString()); } }