Want today's gold and silver rate on your jewellery website, updating on its own? This tutorial gives you working PHP and JavaScript to do it the secure way: your server talks to the rate API, caches the answer, and your page shows the numbers. It works on any PHP host, including Hostinger shared hosting, and you can adapt it for WordPress.
The secure architecture
- Browser asks your server for rates:
/rates.php. - Your server checks a small cache file. If it is older than 60 seconds, it calls the rate API with your secret key.
- Your server returns only the rates — never the key.
This keeps your API key private, protects you if the API is briefly unreachable (the last good rate is served from cache) and reduces API calls no matter how many visitors you have.
Step 1: the PHP proxy (rates.php)
<?php
// rates.php — put this on YOUR website
declare(strict_types=1);
header('Content-Type: application/json; charset=UTF-8');
const API_URL = 'https://2ndcode.com/tools/metal-rate/api/latest.php';
const API_KEY = 'YOUR_SECRET_API_KEY'; // keep it here, never in JavaScript
const CACHE = __DIR__ . '/rates-cache.json';
const TTL = 60; // seconds
if (is_file(CACHE) && time() - filemtime(CACHE) < TTL) {
readfile(CACHE);
exit;
}
$ch = curl_init(API_URL);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 8,
CURLOPT_HTTPHEADER => ['X-API-Key: ' . API_KEY],
]);
$body = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode((string) $body, true);
if ($code === 200 && !empty($data['success'])) {
file_put_contents(CACHE, $body, LOCK_EX);
echo $body;
} elseif (is_file(CACHE)) {
readfile(CACHE); // API down: serve last good rates
} else {
http_response_code(503);
echo json_encode(['success' => false, 'message' => 'Rates unavailable']);
}
Step 2: the HTML widget
<div class="rate-box">
<div>Gold 24K <strong id="g24">–</strong> /10g</div>
<div>Gold 22K <strong id="g22">–</strong> /10g</div>
<div>Silver <strong id="sil">–</strong> /kg</div>
<small id="upd"></small>
</div>
Step 3: the JavaScript
<script>
const inr = n => '₹' + Number(n).toLocaleString('en-IN');
async function loadRates() {
try {
const r = await fetch('/rates.php', { cache: 'no-store' });
const d = await r.json();
if (!d.success) return;
document.getElementById('g24').textContent = inr(d.gold_24k);
document.getElementById('g22').textContent = inr(d.gold_22k);
document.getElementById('sil').textContent = inr(d.silver);
document.getElementById('upd').textContent = 'Updated ' + d.updated_at;
} catch (e) { /* keep last values on screen */ }
}
loadRates();
setInterval(loadRates, 60000); // refresh every minute
</script>
Using textContent (not innerHTML) means even a broken response can never inject HTML into your page.
Using it in WordPress
Upload rates.php to your site root (next to wp-config.php), then add the HTML and script to a Custom HTML block or your theme's header. For a cleaner build, wrap the proxy as a small plugin with a shortcode.
Display tips that build trust
- Always show the unit (per 10 g, per kg) and "excluding GST & making charges".
- Show the update time so customers know the rate is live.
- Keep the rate box above the fold on mobile — most rate checks happen on phones.
- Add a "Call for today's best price" button next to the rate.
See today's live rates and contact details on the Gold & Silver Rate page. Background reading: how a gold rate API works.
Quick answers
Why not call the rate API directly from JavaScript?
Because the API key would be visible to every visitor. Call the API from your server (PHP), cache the result, and give your front-end only the numbers.
How often should the widget refresh?
Every 30–60 seconds is plenty for most jewellery sites. Faster refresh adds server load without helping customers.