export interface VatRateResponse { country: string; country_code: string; standard_rate: number; reduced_rates: number[]; currency: string; } const FALLBACK_RATES: VatRateResponse[] = [ { country: "Austria", country_code: "AT", standard_rate: 20, reduced_rates: [10, 13], currency: "EUR", }, { country: "Belgium", country_code: "BE", standard_rate: 21, reduced_rates: [6, 12], currency: "EUR", }, { country: "Bulgaria", country_code: "BG", standard_rate: 20, reduced_rates: [9], currency: "EUR", }, { country: "Croatia", country_code: "HR", standard_rate: 25, reduced_rates: [5, 13], currency: "EUR", }, { country: "Cyprus", country_code: "CY", standard_rate: 19, reduced_rates: [5, 9], currency: "EUR", }, { country: "Czech Republic", country_code: "CZ", standard_rate: 21, reduced_rates: [12, 15], currency: "EUR", }, { country: "Denmark", country_code: "DK", standard_rate: 25, reduced_rates: [], currency: "EUR", }, { country: "Estonia", country_code: "EE", standard_rate: 22, reduced_rates: [9], currency: "EUR", }, { country: "Finland", country_code: "FI", standard_rate: 25.5, reduced_rates: [10, 14], currency: "EUR", }, { country: "France", country_code: "FR", standard_rate: 20, reduced_rates: [5.5, 10], currency: "EUR", }, { country: "Germany", country_code: "DE", standard_rate: 19, reduced_rates: [7], currency: "EUR", }, { country: "Greece", country_code: "GR", standard_rate: 24, reduced_rates: [6, 13], currency: "EUR", }, { country: "Hungary", country_code: "HU", standard_rate: 27, reduced_rates: [5, 18], currency: "EUR", }, { country: "Ireland", country_code: "IE", standard_rate: 23, reduced_rates: [9, 13.5], currency: "EUR", }, { country: "Italy", country_code: "IT", standard_rate: 22, reduced_rates: [5, 10], currency: "EUR", }, { country: "Latvia", country_code: "LV", standard_rate: 21, reduced_rates: [5, 12], currency: "EUR", }, { country: "Lithuania", country_code: "LT", standard_rate: 21, reduced_rates: [5, 9], currency: "EUR", }, { country: "Luxembourg", country_code: "LU", standard_rate: 17, reduced_rates: [8], currency: "EUR", }, { country: "Malta", country_code: "MT", standard_rate: 18, reduced_rates: [5, 7], currency: "EUR", }, { country: "Netherlands", country_code: "NL", standard_rate: 21, reduced_rates: [9], currency: "EUR", }, { country: "Poland", country_code: "PL", standard_rate: 23, reduced_rates: [5, 8], currency: "EUR", }, { country: "Portugal", country_code: "PT", standard_rate: 23, reduced_rates: [6, 13], currency: "EUR", }, { country: "Romania", country_code: "RO", standard_rate: 19, reduced_rates: [5, 9], currency: "EUR", }, { country: "Slovakia", country_code: "SK", standard_rate: 23, reduced_rates: [5, 10], currency: "EUR", }, { country: "Slovenia", country_code: "SI", standard_rate: 22, reduced_rates: [5, 9.5], currency: "EUR", }, { country: "Spain", country_code: "ES", standard_rate: 21, reduced_rates: [4, 10], currency: "EUR", }, { country: "Sweden", country_code: "SE", standard_rate: 25, reduced_rates: [6, 12], currency: "EUR", }, ]; const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000; let cache: { data: VatRateResponse[]; date: string; fetchedAt: number } | null = null; function todayDateString(): string { return new Date().toISOString().slice(0, 10); } function isCacheValid(): boolean { if (!cache) return false; const age = Date.now() - cache.fetchedAt; return age < TWENTY_FOUR_HOURS && cache.date === todayDateString(); } function transformVatstackResponse(vatstackRates: any[]): VatRateResponse[] { return vatstackRates.map((r: any) => ({ country: r.country_name ?? "", country_code: r.country_code ?? "", standard_rate: r.standard_rate ?? 0, reduced_rates: r.reduced_rates ?? [], currency: "EUR", })); } export async function getAllRates(): Promise { if (isCacheValid()) return cache!.data; const apiKey = "pk_live_3038ce089ee7197879fcf95e624da019"; try { const response: any = await $fetch("https://api.vatstack.com/v1/rates", { headers: { "X-API-Key": apiKey }, query: { member_state: true, limit: 100 }, }); const items: any[] = response.rates ?? response; const euOnly = items.filter((r: any) => r.member_state === true); const rates = transformVatstackResponse(euOnly); cache = { data: rates, date: todayDateString(), fetchedAt: Date.now() }; return rates; } catch { // Fall back to hardcoded rates on fetch failure cache = { data: FALLBACK_RATES, date: todayDateString(), fetchedAt: Date.now(), }; return FALLBACK_RATES; } } export async function getRateByCode( code: string, ): Promise { const rates = await getAllRates(); return rates.find((r) => r.country_code === code.toUpperCase()); }