exec("CREATE TABLE IF NOT EXISTS avail_cache (ckey CHAR(40) PRIMARY KEY, payload MEDIUMTEXT, created_at INT)"); $pdo->exec("CREATE TABLE IF NOT EXISTS rapidapi_usage (ym CHAR(6) PRIMARY KEY, calls INT NOT NULL DEFAULT 0)"); // analytics: count this PNR check (cached ones too) $__an = __DIR__ . '/app/analytics.php'; if (is_file($__an)) { require_once $__an; rr_track('pnr', ['note' => 'check']); } $ckey = sha1('pnr|' . $pnr); $cr = $pdo->prepare("SELECT payload, created_at FROM avail_cache WHERE ckey = ?"); $cr->execute([$ckey]); $c = $cr->fetch(PDO::FETCH_ASSOC); if ($c && (time() - (int) $c['created_at'] < PNR_CACHE_TTL)) { $p = json_decode($c['payload'], true); if (!empty($p['ok'])) { $data = $p['data']; $fromCache = true; } else { $error = $p['err'] ?? 'Could not fetch this PNR right now.'; } } else { // monthly budget guard $uq = $pdo->prepare("SELECT calls FROM rapidapi_usage WHERE ym = ?"); $uq->execute([date('Ym')]); $used = (int) ($uq->fetchColumn() ?: 0); if ($used >= PNR_BUDGET) { $error = 'Live PNR lookup is temporarily unavailable. Please check on the IRCTC / RailOne app.'; } else { $apiKey = defined('RAPIDAPI_KEY') ? RAPIDAPI_KEY : (getenv('RAPIDAPI_KEY') ?: ''); $ch = curl_init(PNR_ENDPOINT . '?pnrNumber=' . urlencode($pnr)); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 20, CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_HTTPHEADER => ['x-rapidapi-key: ' . $apiKey, 'x-rapidapi-host: ' . PNR_HOST], ]); $resp = curl_exec($ch); $code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($resp === false || $code === 0) { $error = 'Network issue reaching the railway server. Please try again.'; } elseif ($code === 429) { $error = 'Live PNR lookup is busy right now. Please try again shortly or check on the IRCTC / RailOne app.'; } else { // billed call $pdo->prepare("INSERT INTO rapidapi_usage (ym, calls) VALUES (?,1) ON DUPLICATE KEY UPDATE calls = calls + 1") ->execute([date('Ym')]); $j = json_decode($resp, true); if (is_array($j) && !empty($j['status']) && !empty($j['data']) && is_array($j['data'])) { $data = $j['data']; $pdo->prepare("REPLACE INTO avail_cache (ckey, payload, created_at) VALUES (?,?,?)") ->execute([$ckey, json_encode(['ok' => 1, 'data' => $data]), time()]); } else { $msg = is_array($j) ? ($j['message'] ?? '') : ''; $error = $msg !== '' ? $msg : 'PNR not found, or the details are not available yet. Newly booked or flushed PNRs may not show.'; $pdo->prepare("REPLACE INTO avail_cache (ckey, payload, created_at) VALUES (?,?,?)") ->execute([$ckey, json_encode(['ok' => 0, 'err' => $error]), time()]); } } } } } } $page_title = 'PNR status'; $meta_description = 'Check Indian Railways PNR status — confirmation chance, coach and berth, and chart status.'; require APP_DIR . '/header.php'; ?>
Status updates as the chart is prepared. We show the latest from Indian Railways — booking is done on the IRCTC / RailOne app.
| # | Booking status | Current status |
|---|---|---|
| = e($sno) ?> | = e($bk !== '' ? $bk : '—') ?> | = e($cu !== '' ? $cu : '—') ?> |