validate([ 'package_id' => ['required', 'exists:packages,id'], 'success_url' => ['nullable', 'url'], 'return_url' => ['nullable', 'url'], 'inline' => ['sometimes', 'boolean'], ]); $user = Auth::user(); $tenant = $user?->tenant; if (! $tenant) { throw ValidationException::withMessages(['tenant' => 'Tenant context missing.']); } $package = Package::findOrFail((int) $data['package_id']); if (! $package->paddle_price_id) { throw ValidationException::withMessages(['package_id' => 'Package is not linked to a Paddle price.']); } $session = $this->sessions->createOrResume($user, $package, [ 'tenant' => $tenant, ]); $this->sessions->selectProvider($session, CheckoutSession::PROVIDER_PADDLE); if ($request->boolean('inline')) { $metadata = array_merge($session->provider_metadata ?? [], [ 'mode' => 'inline', ]); $session->forceFill([ 'provider_metadata' => $metadata, ])->save(); return response()->json([ 'mode' => 'inline', 'items' => [ [ 'priceId' => $package->paddle_price_id, 'quantity' => 1, ], ], 'custom_data' => [ 'tenant_id' => (string) $tenant->id, 'package_id' => (string) $package->id, 'checkout_session_id' => (string) $session->id, ], 'customer' => array_filter([ 'email' => $user->email, 'name' => trim(($user->first_name ?? '').' '.($user->last_name ?? '')) ?: ($user->name ?? null), ]), ]); } $checkout = $this->checkout->createCheckout($tenant, $package, [ 'success_url' => $data['success_url'] ?? null, 'return_url' => $data['return_url'] ?? null, 'metadata' => [ 'checkout_session_id' => $session->id, ], ]); $session->forceFill([ 'paddle_checkout_id' => $checkout['id'] ?? $session->paddle_checkout_id, 'provider_metadata' => array_merge($session->provider_metadata ?? [], array_filter([ 'paddle_checkout_id' => $checkout['id'] ?? null, 'paddle_checkout_url' => $checkout['checkout_url'] ?? null, 'paddle_expires_at' => $checkout['expires_at'] ?? null, ])), ])->save(); return response()->json($checkout); } }