your site -> Webhooks, or /dashboard/webhooks). */ declare(strict_types=1); header('Content-Type: application/json; charset=UTF-8'); $SECRET = getenv('VERITUS_WEBHOOK_SECRET') ?: 'whsec_PUT_YOURS_HERE'; if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { http_response_code(405); echo '{"ok":false}'; exit; } // 1. Verify signature over the RAW body (never the re-encoded JSON). $raw = file_get_contents('php://input'); $given = $_SERVER['HTTP_X_VERITUS_SIGNATURE'] ?? ''; $expected = 'sha256=' . hash_hmac('sha256', $raw, $SECRET); if (!hash_equals($expected, $given)) { http_response_code(401); echo '{"ok":false,"error":"bad_signature"}'; exit; } // 2. Parse and dispatch on event type. $body = json_decode($raw, true) ?: []; $event = $body['event'] ?? ''; $data = $body['data'] ?? []; if ($event === 'verdict.overridden') { $email = strtolower(trim((string)($data['email'] ?? ''))); $verdict = strtolower(trim((string)($data['new_verdict'] ?? ''))); if ($email !== '' && $verdict === 'allow') { // ─── TODO: activate this user's account in your own system ─── // e.g. UPDATE users SET verified='yes' WHERE LOWER(email)=? // and optionally email them that they're now active. // ───────────────────────────────────────────────────────────── } // verdict 'block'/'review' -> leave the account held. Do nothing. } // 3. Always return 2xx fast so Veritus doesn't retry. http_response_code(200); echo '{"ok":true}';