Ask what the dollar rate is in Pakistan and any honest answer starts with, which one? There are two, the interbank rate, where banks trade with each other, the number in news headlines and used for official transactions, and the open market rate, what exchange companies actually quote when a person walks in with rupees or dollars. They differ, sometimes by a little, in stressed periods visibly, and a forex site that shows one number is answering half the question. This post is how the site models, fetches, and presents both truthfully.
The split reaches the schema first, market_type as a first-class column, with the buying-selling pair that currencies quote as:
// wp_pfr_rates
// currency | market_type ('interbank'|'open_market') | buying | selling | recorded_at
function pfr_get_latest($currency, $market = 'open_market') {
global $wpdb;
return $wpdb->get_row($wpdb->prepare(
'SELECT * FROM ' . $wpdb->prefix . 'pfr_rates
WHERE currency = %s AND market_type = %s
ORDER BY recorded_at DESC LIMIT 1',
$currency, $market
));
}
Note the default. When a shortcode does not specify a market, it gets open market, a deliberate audience decision, the site’s typical reader is a person or a remittance family for whom the exchange-company counter is reality, while the interbank number is context. The buying and selling columns matter just as much, an exchange company buys your dollars at one price and sells you dollars at a higher one, the spread is their margin, and a site quoting one number is hiding which side of the counter it means.
Presentation puts the two markets side by side rather than making the reader choose blind, the rate pages render both through the same shortcode with the market attribute:
// on the USD page:
// [forex_rate_live currency="USD" market="open_market"]
// [forex_rate_live currency="USD" market="interbank"]
$a = shortcode_atts(array('currency' => 'USD', 'market' => 'open_market'), $atts);
$r = pfr_get_latest($a['currency'], $a['market']);
return sprintf(
'<div class="pfr-live pfr-%1$s"><h3>%2$s</h3>
<span>Buying PKR %3$s</span> <span>Selling PKR %4$s</span></div>',
esc_attr($a['market']),
$a['market'] === 'interbank' ? 'Interbank' : 'Open Market',
number_format((float) $r->buying, 2),
number_format((float) $r->selling, 2)
);
And because two numbers invite the obvious question, each rate page explains the difference in plain words right beside them, which market applies to a bank transfer, which to cash at an exchange counter, why they diverge when the rupee is under pressure. The fetching side inherits the silver site’s engine with market-aware parsing, interbank figures from sources that publish them, open market from exchange-company listings, each with its own sanity ranges, because the two markets legitimately differ and a validator built for one would false-flag the other. Modelling the domain’s real shape, two markets, two sides of the counter, cost two columns and honest labels, and it is the difference between a currency site and a currency answer.
A few things people ask me about this
Which rate applies to sending remittances to Pakistan? Bank and formal-channel transfers settle around interbank-linked rates, cash exchanged at an exchange company moves at open market. The site labels both so the reader matches the number to their own transaction.
Why do buying and selling differ, and which is the rate? The spread is the exchange company’s margin, both are the rate, from opposite sides of the counter. Quote the pair, a single number silently picks a side for the reader.
Next
With two markets modelled honestly, the next question was operational, how the numbers get into the site each day, and why I chose typing over automation to start. That is the next post.
