trim((string) ($dotEnv['database.default.hostname'] ?? getenv('database.default.hostname') ?: 'localhost')), 'user' => trim((string) ($dotEnv['database.default.username'] ?? getenv('database.default.username') ?: 'root')), 'pass' => trim((string) ($dotEnv['database.default.password'] ?? getenv('database.default.password') ?: '')), 'name' => trim((string) ($dotEnv['database.default.database'] ?? getenv('database.default.database') ?: 'hms_ci4_2026')), 'port' => (int) ($dotEnv['database.default.port'] ?? getenv('database.default.port') ?: 3306), ]; $mysqli = @new mysqli($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['name'], $dbConfig['port']); if (! $mysqli->connect_errno) { if ($token === '') { $token = resolveRuntimeSetting( ['GATEWAY_TO_HMS_TOKEN', 'ABDM_GATEWAY_TO_HMS_TOKEN', 'EKA_GATEWAY_TOKEN', 'EATRIA_BRIDGE_TOKEN', 'ABDM_BRIDGE_TOKEN'], $dotEnv, $mysqli ); $token = preg_replace('/^Bearer\s+/i', '', $token) ?? $token; } if ($secret === '') { $secret = resolveRuntimeSetting(['GATEWAY_TO_HMS_HMAC_SECRET', 'EKA_WEBHOOK_SECRET'], $dotEnv, $mysqli); } $mysqli->close(); } } if ($token === '') { fwrite(STDERR, "Error: missing token. Provide --token or M2_TOKEN, or use --auto-credentials.\n"); exit(1); } $nowUtc = gmdate('Y-m-d\\TH:i:s\\Z'); $reqBase = 'REQ-' . gmdate('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(3))); $txBase = 'TX-' . gmdate('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(2))); $tests = [ [ 'name' => 'Health Check', 'method' => 'GET', 'path' => '/api/v1/abdm/gateway/health', 'body' => null, ], [ 'name' => 'Discovery Care Contexts', 'method' => 'POST', 'path' => '/api/v1/abdm/gateway/discovery/care-contexts', 'body' => [ 'request_id' => $reqBase . '-DISC', 'transaction_id' => $txBase . '-DISC', 'hospital_hfr_id' => 'IN0510000828', 'abha_id' => $abha, 'abha_address' => $abha, 'patient' => [ 'name' => 'Demo Patient', 'gender' => 'M', 'year_of_birth' => 1985, ], ], ], [ 'name' => 'Health Information Fetch', 'method' => 'POST', 'path' => '/api/v1/abdm/gateway/health-information/fetch', 'body' => [ 'request_id' => $reqBase . '-FETCH', 'transaction_id' => $txBase . '-FETCH', 'hospital_hfr_id' => 'IN0510000828', 'consent_id' => 'CONS-DEMO-001', 'abha_id' => $abha, 'abha_address' => $abha, 'date_range' => [ 'from' => '2026-01-01T00:00:00Z', 'to' => $nowUtc, ], 'care_context_references' => [], ], ], [ 'name' => 'Consent Upsert', 'method' => 'POST', 'path' => '/api/v1/abdm/gateway/consent/upsert', 'body' => [ 'request_id' => $reqBase . '-CONS', 'hospital_hfr_id' => 'IN0510000828', 'patient_id' => 1, 'consent_id' => 'CONS-DEMO-001', 'status' => 'GRANTED', 'abha_id' => $abha, 'abha_address' => $abha, 'purpose' => 'treatment', 'date_range' => [ 'from' => '2026-01-01T00:00:00Z', 'to' => $nowUtc, ], 'hi_types' => ['OPConsultRecord', 'DiagnosticReportRecord'], 'raw_notification' => ['source' => 'local-test-runner'], ], ], [ 'name' => 'Link Status', 'method' => 'POST', 'path' => '/api/v1/abdm/gateway/link/status', 'body' => [ 'request_id' => $reqBase . '-LINK', 'hospital_hfr_id' => 'IN0510000828', 'abha_id' => $abha, 'abha_address' => $abha, 'care_context_reference' => 'OPD-1-' . gmdate('Ymd'), 'status' => 'linked', 'linked_at' => $nowUtc, 'source' => 'hip_initiated', ], ], ]; foreach ($tests as $test) { $method = (string) $test['method']; $path = (string) $test['path']; $body = $test['body']; $json = $body === null ? '' : (string) json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); $requestId = 'REQ-' . gmdate('YmdHis') . '-' . strtoupper(bin2hex(random_bytes(3))); $timestamp = gmdate('Y-m-d\\TH:i:s\\Z'); $signature = 'sha256=' . hash_hmac('sha256', $json, $secret !== '' ? $secret : ''); $headers = [ 'Authorization: Bearer ' . $token, 'X-Request-Id: ' . $requestId, 'X-Timestamp: ' . $timestamp, 'X-Eka-Signature: ' . $signature, 'Accept: application/json', ]; if ($method === 'POST') { $headers[] = 'Content-Type: application/json'; } $url = $baseUrl . $path; echo "\n============================================================\n"; echo 'TEST: ' . $test['name'] . "\n"; echo $method . ' ' . $url . "\n"; if ($dryRun) { $escapedHeaders = ''; foreach ($headers as $h) { $escapedHeaders .= ' -H ' . escapeshellarg($h); } if ($method === 'GET') { echo 'curl -i -X GET ' . escapeshellarg($url) . $escapedHeaders . "\n"; } else { echo 'curl -i -X POST ' . escapeshellarg($url) . $escapedHeaders . ' --data ' . escapeshellarg($json) . "\n"; } echo "(dry-run only; request not sent)\n"; continue; } $ch = curl_init($url); $opts = [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => $headers, CURLOPT_TIMEOUT => 30, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_CUSTOMREQUEST => $method, ]; if ($method === 'POST') { $opts[CURLOPT_POSTFIELDS] = $json; } curl_setopt_array($ch, $opts); $raw = curl_exec($ch); $errno = curl_errno($ch); $err = curl_error($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($errno !== 0) { echo 'cURL error: [' . $errno . '] ' . $err . "\n"; continue; } $decoded = json_decode((string) $raw, true); echo 'HTTP ' . $code . "\n"; if (is_array($decoded)) { echo (string) json_encode($decoded, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n"; } else { echo (string) $raw . "\n"; } } exit(0); function loadDotEnv(string $envPath): array { if (! is_file($envPath)) { return []; } $result = []; $lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: []; foreach ($lines as $line) { $trimmed = trim((string) $line); if ($trimmed === '' || str_starts_with($trimmed, '#')) { continue; } $parts = explode('=', $trimmed, 2); if (count($parts) !== 2) { continue; } $key = trim((string) $parts[0]); $val = trim((string) $parts[1]); $result[$key] = $val; } return $result; } function resolveRuntimeSetting(array $candidates, array $dotEnv, mysqli $mysqli): string { foreach ($candidates as $name) { $v = getenv($name); if ($v !== false && trim((string) $v) !== '') { return trim((string) $v); } if (! empty($dotEnv[$name])) { return trim((string) $dotEnv[$name]); } $nameEsc = $mysqli->real_escape_string((string) $name); $sql = "SELECT s_value FROM hospital_setting WHERE s_name = '" . $nameEsc . "' LIMIT 1"; $res = $mysqli->query($sql); if (! $res) { continue; } $row = $res->fetch_assoc(); $dbValue = trim((string) ($row['s_value'] ?? '')); if ($dbValue !== '') { return $dbValue; } } return ''; }