File size: 2,834 Bytes
4a285d2 ef85da9 4a285d2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import axios from 'axios';
export class ExchangeRateService {
private cachedRate: number | null = null;
private cacheExpiry: Date | null = null;
private readonly CACHE_DURATION_MS = 60 * 60 * 1000;
private readonly FALLBACK_RATE: number;
constructor() {
this.FALLBACK_RATE = parseFloat(process.env.NGN_PER_USD || '750');
}
async getNGNToUSDRate(): Promise<number> {
if (this.cachedRate && this.cacheExpiry && new Date() < this.cacheExpiry) {
console.log('Using cached exchange rate:', this.cachedRate);
return this.cachedRate;
}
try {
const rate = await this.fetchExchangeRate();
this.cachedRate = rate;
this.cacheExpiry = new Date(Date.now() + this.CACHE_DURATION_MS);
console.log('Fetched new exchange rate:', rate);
return rate;
} catch (error) {
console.error('Failed to fetch exchange rate, using fallback:', error);
return this.FALLBACK_RATE;
}
}
private async fetchExchangeRate(): Promise<number> {
try {
const response = await axios.get('https://api.exchangerate-api.com/v4/latest/USD', {
timeout: 5000,
});
const rate = response.data.rates?.NGN;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('ExchangeRate-API failed, trying alternative...');
}
// Option 2: CurrencyAPI (requires free API key, but more reliable)
const currencyApiKey = process.env.CURRENCY_API_KEY;
if (currencyApiKey) {
try {
const response = await axios.get(
`https://api.currencyapi.com/v3/latest?apikey=${currencyApiKey}¤cies=NGN&base_currency=USD`,
{ timeout: 5000 }
);
const rate = response.data.data?.NGN?.value;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('CurrencyAPI failed, trying alternative...');
}
}
// Option 3: Fixer.io (requires API key)
const fixerApiKey = process.env.FIXER_API_KEY;
if (fixerApiKey) {
try {
const response = await axios.get(
`https://api.fixer.io/latest?access_key=${fixerApiKey}&base=USD&symbols=NGN`,
{ timeout: 5000 }
);
const rate = response.data.rates?.NGN;
if (rate && rate > 0) {
return rate;
}
} catch (error) {
console.warn('Fixer.io failed, using fallback...');
}
}
// If all APIs fail, throw error to use fallback
throw new Error('All exchange rate APIs failed');
}
/**
* Get the fallback rate (from env or default)
*/
getFallbackRate(): number {
return this.FALLBACK_RATE;
}
/**
* Clear the cache (useful for testing or manual refresh)
*/
clearCache(): void {
this.cachedRate = null;
this.cacheExpiry = null;
}
}
|