Karachi - Today, the following are the buying and selling rates that are being observed in the interbank: PKR Interbank Rates *{ margin:0; padding:0; box-sizing:border-box; font-family:'Poppins',sans-serif; } body{ background:#e5e7eb; padding:8px; } .wrapper{ width:100%; max-width:420px; margin:auto; background:#ffffff; border:1px solid #d1d5db; } .title{ background:#000; color:#fff; text-align:center; padding:8px 5px; font-size:13px; font-weight:600; letter-spacing:.5px; } .status{ display:flex; justify-content:space-between; background:#f3f4f6; padding:5px 8px; font-size:10px; border-bottom:1px solid #d1d5db; } .live{ color:#059669; font-weight:600; } .table{ width:100%; } .row{ display:grid; grid-template-columns: 34px 55px 1fr 1fr; align-items:center; gap:4px; padding:6px 6px; border-bottom:1px solid #e5e7eb; font-size:11px; } .head{ background:#111827; color:#fff; font-weight:600; font-size:10px; text-transform:uppercase; } .flag{ width:22px; height:15px; object-fit:cover; border:1px solid #ddd; } .code{ font-weight:600; color:#111827; } .buy{ text-align:right; color:#047857; font-weight:600; } .sell{ text-align:right; color:#dc2626; font-weight:600; } .loading{ text-align:center; padding:20px; font-size:11px; color:#6b7280; } PKR INTERBANK RATES ● LIVE SBP --:--:-- Flag Code Buy PKR Sell PKR Loading live rates... const KEY = '83eeb16b08afef26484d102e'; const LIST = { USD:{f:"us"}, GBP:{f:"gb"}, EUR:{f:"eu"}, SAR:{f:"sa"}, AED:{f:"ae"}, CAD:{f:"ca"}, AUD:{f:"au"}, CNY:{f:"cn"}, JPY:{f:"jp"} }; async function loadRates(){ try{ const res = await fetch(`https://v6.exchangerate-api.com/v6/${KEY}/latest/PKR`); const data = await res.json(); if(data.result==="success"){ let html=''; for(const [code, meta] of Object.entries(LIST)){ const p = 1 / data.conversion_rates[code]; html += ` <div class="row"> <div><img class="flag" src="https://flagcdn.com/w40/${meta.f}.png"></div> <div class="code">${code}</div> <div class="buy">${(p-0.05).toFixed(2)}</div> <div class="sell">${(p+0.05).toFixed(2)}</div> </div>`; } document.getElementById('rates').innerHTML = html; document.getElementById('clock').innerText = new Date().toLocaleTimeString(); } }catch(err){ document.getElementById('rates').innerHTML='<div class="loading">Unable to fetch rates</div>'; } } loadRates(); setInterval(loadRates,30000); const PROXY_URL = 'https://api.allorigins.win/raw?url='; const TARGET_URL = 'https://www.forex.com.pk/inter_bank_rates.asp'; let cachedRates = []; let lastUpdateTime = null; let refreshInterval = null; let isFetching = false; // Update only changed rates function updateRates(rates) { const container = document.getElementById('ratesListContainer'); const timestampLabel = document.getElementById('timestampLabel'); if (!container) return; rates.forEach(rate => { const rowId = `row-${rate.code}`; let row = document.getElementById(rowId); const meta = getCurrencyMeta(rate.code); const flagUrl = `https://flagcdn.com/w40/${meta.flag}.png`; const rowHtml = ` <div class="currency-row" id="${rowId}"> <div class="currency-info"> <img class="flag-icon" src="${flagUrl}" alt="${rate.code}" loading="lazy" onerror="this.src='https://cdn.jsdelivr.net/gh/studiolego/flag-icons/flags/1x1/${meta.flag}.svg'"> <div class="currency-text"> <span class="currency-code">${rate.code}</span> <span class="currency-name">${meta.name}</span> </div> </div> <div class="buy-block"> <span class="buy-pill">${rate.buy}</span> </div> <div class="sell-block"> <span class="sell-pill">${rate.sell}</span> </div> </div> `; if (!row) { container.insertAdjacentHTML('beforeend', rowHtml); } else { const buyEl = row.querySelector('.buy-pill'); const sellEl = row.querySelector('.sell-pill'); if (buyEl && buyEl.innerText !== rate.buy) buyEl.innerText = rate.buy; if (sellEl && sellEl.innerText !== rate.sell) sellEl.innerText = rate.sell; } }); if (timestampLabel) { const timeStr = new Date().toLocaleTimeString('en-PK', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); timestampLabel.innerText = timeStr; lastUpdateTime = timeStr; } } // Fetch with retry & timeout async function fetchLiveRates(force = false) { if (isFetching && !force) return; isFetching = true; const container = document.getElementById('ratesListContainer'); if (!container) return; try { const controller = new AbortController(); const timeout = setTimeout(() => controller.abort(), 7000); // faster timeout 7s const response = await fetch(PROXY_URL + encodeURIComponent(TARGET_URL), { signal: controller.signal }); clearTimeout(timeout); if (!response.ok) throw new Error(`HTTP ${response.status}`); const htmlText = await response.text(); const parsedRates = parseRatesFromHTML(htmlText); if (parsedRates && parsedRates.length > 0) { cachedRates = parsedRates; updateRates(parsedRates); } else if (cachedRates.length > 0) { updateRates(cachedRates); // use last known rates } else { cachedRates = getFallbackRates(); updateRates(cachedRates); } } catch (err) { console.error("Fetch failed:", err); if (cachedRates.length > 0) { updateRates(cachedRates); // keep showing last known } else { cachedRates = getFallbackRates(); updateRates(cachedRates); } } finally { isFetching = false; } } // Fast interval refresh function startFastRefresh() { fetchLiveRates(); // initial fetch if (refreshInterval) clearInterval(refreshInterval); refreshInterval = setInterval(() => { if (!document.hidden) fetchLiveRates(false); }, 15000); // 15s interval for fast update } document.addEventListener('visibilitychange', () => { if (!document.hidden) fetchLiveRates(false); }); document.addEventListener('click', e => { if (e.target.classList && e.target.classList.contains('retry-btn')) fetchLiveRates(true); }); // Start updating startFastRefresh();