attributes->get('tenant_id'); if ($event->tenant_id !== $tenantId) { return ApiError::response( 'event_not_found', 'Event not accessible', __('Das Event konnte nicht gefunden werden.'), 404, ['event_slug' => $event->slug ?? null] ); } $eventPackage = $event->eventPackage ?: $event->eventPackages() ->orderByDesc('purchased_at') ->orderByDesc('created_at') ->first(); if ($eventPackage) { $event->setRelation('eventPackage', $eventPackage); } $checkout = $this->checkoutService->createCheckout( $request->attributes->get('tenant'), $event, $request->validated(), ); return response()->json([ 'checkout_url' => $checkout['checkout_url'] ?? null, 'checkout_id' => $checkout['id'] ?? null, 'expires_at' => $checkout['expires_at'] ?? null, ]); } public function purchase(EventAddonPurchaseLookupRequest $request, Event $event): JsonResponse { $tenantId = $request->attributes->get('tenant_id'); if ($event->tenant_id !== $tenantId) { return ApiError::response( 'event_not_found', 'Event not accessible', __('Das Event konnte nicht gefunden werden.'), 404, ['event_slug' => $event->slug ?? null] ); } $validated = $request->validated(); $addonIntent = trim((string) ($validated['addon_intent'] ?? '')); $checkoutId = trim((string) ($validated['checkout_id'] ?? '')); $addonKey = trim((string) ($validated['addon_key'] ?? '')); $baseQuery = EventPackageAddon::query() ->where('tenant_id', $tenantId) ->where('event_id', $event->id) ->with(['event:id,name,slug']); $addon = null; if ($addonIntent !== '') { $addon = (clone $baseQuery) ->where('metadata->addon_intent', $addonIntent) ->orderByDesc('created_at') ->first(); } if (! $addon && $checkoutId !== '') { $addon = (clone $baseQuery) ->where('checkout_id', $checkoutId) ->orderByDesc('created_at') ->first(); } if (! $addon && $addonKey !== '') { $addon = (clone $baseQuery) ->where('addon_key', $addonKey) ->orderByRaw("case status when 'completed' then 0 when 'pending' then 1 else 2 end") ->orderByDesc('purchased_at') ->orderByDesc('created_at') ->first(); } if (! $addon) { $addon = (clone $baseQuery) ->orderByRaw("case status when 'completed' then 0 when 'pending' then 1 else 2 end") ->orderByDesc('purchased_at') ->orderByDesc('created_at') ->first(); } if (! $addon) { return ApiError::response( 'addon_not_found', 'Add-on purchase not found', __('Der Add-on Kauf wurde nicht gefunden.'), 404, ['event_slug' => $event->slug ?? null] ); } $label = Arr::get($addon->metadata ?? [], 'label') ?? $addon->addon_key; return response()->json([ 'data' => [ 'id' => $addon->id, 'addon_key' => $addon->addon_key, 'label' => $label, 'quantity' => (int) ($addon->quantity ?? 1), 'status' => $addon->status, 'amount' => $addon->amount !== null ? (float) $addon->amount : null, 'currency' => $addon->currency, 'extra_photos' => (int) $addon->extra_photos, 'extra_guests' => (int) $addon->extra_guests, 'extra_gallery_days' => (int) $addon->extra_gallery_days, 'purchased_at' => $addon->purchased_at?->toIso8601String(), 'receipt_url' => Arr::get($addon->receipt_payload, 'receipt_url'), 'checkout_id' => $addon->checkout_id, 'transaction_id' => $addon->transaction_id, 'created_at' => $addon->created_at?->toIso8601String(), 'addon_intent' => Arr::get($addon->metadata ?? [], 'addon_intent'), 'event' => $addon->event ? [ 'id' => $addon->event->id, 'slug' => $addon->event->slug, 'name' => $addon->event->name, ] : null, ], ]); } }