whereJsonContains('events', $event) ->get(); foreach ($webhooks as $webhook) { $this->send($webhook, $event, $payload); } } private function send(Webhook $webhook, string $event, array $payload): void { $body = json_encode([ 'event' => $event, 'timestamp' => now()->toIso8601String(), 'payload' => $payload, ]); $signature = 'sha256=' . hash_hmac('sha256', $body, $webhook->secret); try { $response = Http::timeout(8) ->withHeaders([ 'Content-Type' => 'application/json', 'X-Mailwolt-Event' => $event, 'X-Mailwolt-Sig' => $signature, ]) ->withBody($body, 'application/json') ->post($webhook->url); $webhook->update([ 'last_triggered_at' => now(), 'last_status' => $response->status(), ]); } catch (\Throwable $e) { $webhook->update([ 'last_triggered_at' => now(), 'last_status' => 0, ]); Log::warning("Webhook #{$webhook->id} failed: " . $e->getMessage()); } } public static function generateSecret(): string { return bin2hex(random_bytes(32)); } }