getContent(); $signature = $request->header('X-Tokenview-Signature'); $payload = $request->json()->all(); if (! is_array($payload) || $payload === []) { $decoded = json_decode($raw, true); $payload = is_array($decoded) ? $decoded : []; } Log::info('tokenview webhook received', [ 'ip' => $request->ip(), 'method' => $request->method(), 'has_signature' => is_string($signature) && $signature !== '', 'body_bytes' => strlen($raw), 'payload' => $payload !== [] ? $payload : $raw, ]); // Tokenview probes the webhook (often unsigned GET/POST) before a // sign key exists. Always 200 + non-empty body; only skip ingest. $signed = $monitor->verifySignature($raw, $signature); if (! $signed) { Log::warning('tokenview webhook bad signature (acked 200, skipped ingest)', [ 'ip' => $request->ip(), 'body_bytes' => strlen($raw), ]); } elseif ($payload !== []) { try { $monitor->handleWebhook($payload); } catch (\Throwable $e) { Log::warning('tokenview webhook handle failed: '.$e->getMessage(), [ 'exception' => $e::class, ]); } } return response('ok', 200)->header('Content-Type', 'text/plain; charset=UTF-8'); } }