feat: Improve currency exchange rate fetching in BillingManager by adding a primary source from the Central Bank of Russia and a fallback to an alternative API, along with updates to currency formatting for better precision.
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 2m17s

This commit is contained in:
2025-12-06 14:50:45 +07:00
parent ad75ca8ff5
commit fee74c377f
+29 -6
View File
@@ -116,8 +116,28 @@ function BillingManager() {
const fetchExchangeRates = async () => {
setRatesLoading(true);
try {
const response = await axios.get('https://api.exchangerate-api.com/v4/latest/USD');
const rates = response.data.rates;
// Основной источник: ЦБ РФ (base = RUB)
const cbr = await axios.get('https://www.cbr-xml-daily.ru/latest.js');
const rubPerUsd = cbr.data && cbr.data.rates?.USD ? 1 / Number(cbr.data.rates.USD) : null;
const rubPerEur = cbr.data && cbr.data.rates?.EUR ? 1 / Number(cbr.data.rates.EUR) : null;
if (rubPerUsd) {
const eurPerUsd = rubPerEur ? rubPerUsd / rubPerEur : 1;
setExchangeRates({
USD: 1,
EUR: eurPerUsd, // сколько EUR за 1 USD
RUB: rubPerUsd // сколько RUB за 1 USD
});
return;
}
} catch (error) {
console.warn('ЦБ недоступен, пробуем резервный источник:', error?.message);
}
try {
// Резервный источник: open.er-api
const response = await axios.get('https://open.er-api.com/v6/latest/USD');
const rates = response.data?.rates || {};
setExchangeRates({
USD: 1,
EUR: rates.EUR || 1,
@@ -125,7 +145,8 @@ function BillingManager() {
});
} catch (error) {
console.error('Ошибка при загрузке курсов валют:', error);
setExchangeRates({ USD: 1, EUR: 0.85, RUB: 95 });
// Фолбек на разумные значения
setExchangeRates({ USD: 1, EUR: 1.05, RUB: 95 });
} finally {
setRatesLoading(false);
}
@@ -233,11 +254,12 @@ function BillingManager() {
}
function formatCurrency(amount, currency = 'USD') {
if (!amount) return '—';
if (amount === undefined || amount === null || amount === '') return '—';
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: currency,
maximumFractionDigits: 0
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(amount);
}
@@ -246,7 +268,8 @@ function BillingManager() {
return new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
maximumFractionDigits: 0
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(rubAmount);
}