94 lines
2.9 KiB
PHP
94 lines
2.9 KiB
PHP
<?php
|
||
|
||
namespace Koneko\CurrencyApi\Services;
|
||
|
||
use Illuminate\Support\Facades\Http;
|
||
use Koneko\VuexyAdmin\Models\CurrencyRate;
|
||
use Koneko\VuexyAdmin\Models\Setting;
|
||
use Carbon\Carbon;
|
||
|
||
class CurrencyApiService
|
||
{
|
||
protected array $providers = ['banxico', 'fixer', 'ecb'];
|
||
|
||
/**
|
||
* Obtiene la tasa de cambio de una moneda en una fecha específica.
|
||
*/
|
||
public function getExchangeRate(string $currency, $date = null): ?float
|
||
{
|
||
$date = $date ?: Carbon::now()->toDateString();
|
||
|
||
return CurrencyRate::where('currency_code', $currency)
|
||
->where('date', '<=', $date)
|
||
->orderByDesc('date')
|
||
->first()
|
||
?->exchange_rate;
|
||
}
|
||
|
||
/**
|
||
* Actualiza las tasas de cambio de las 10 divisas.
|
||
*/
|
||
public function updateExchangeRates()
|
||
{
|
||
foreach ($this->providers as $provider) {
|
||
$this->fetchAndStoreRates($provider);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Obtiene tasas de un proveedor y las guarda.
|
||
*/
|
||
protected function fetchAndStoreRates(string $provider)
|
||
{
|
||
$rates = match ($provider) {
|
||
'banxico' => $this->fetchBanxicoRates(),
|
||
'fixer' => $this->fetchFixerRates(),
|
||
default => []
|
||
};
|
||
|
||
foreach ($rates as $currency => $rate) {
|
||
CurrencyRate::updateOrCreate(
|
||
['currency_code' => $currency, 'date' => Carbon::now()->toDateString(), 'source' => $provider],
|
||
['exchange_rate' => $rate]
|
||
);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Obtiene tasas de Banxico (solo las divisas disponibles en su API).
|
||
*/
|
||
protected function fetchBanxicoRates(): array
|
||
{
|
||
$apiKey = Setting::getValue('banxico.api_key');
|
||
$url = "https://www.banxico.org.mx/SieAPIRest/service/v1/series/SF43718,SF46410,SF46407,SF46406,SF60632/datos/oportuno/?token={$apiKey}";
|
||
|
||
$response = Http::get($url);
|
||
|
||
if ($response->successful()) {
|
||
$data = $response->json();
|
||
return [
|
||
'USD' => (float) ($data['bmx']['series'][0]['datos'][0]['dato'] ?? null),
|
||
'EUR' => (float) ($data['bmx']['series'][1]['datos'][0]['dato'] ?? null),
|
||
'GBP' => (float) ($data['bmx']['series'][2]['datos'][0]['dato'] ?? null),
|
||
'JPY' => (float) ($data['bmx']['series'][3]['datos'][0]['dato'] ?? null),
|
||
'CAD' => (float) ($data['bmx']['series'][4]['datos'][0]['dato'] ?? null),
|
||
];
|
||
}
|
||
|
||
return [];
|
||
}
|
||
|
||
/**
|
||
* Obtiene tasas de Fixer.io.
|
||
*/
|
||
protected function fetchFixerRates(): array
|
||
{
|
||
$apiKey = Setting::getValue('fixer.api_key');
|
||
$url = "http://data.fixer.io/api/latest?access_key={$apiKey}&symbols=USD,EUR,GBP,JPY,CAD,AUD,CHF,CNY,GTQ,MXN";
|
||
|
||
$response = Http::get($url);
|
||
|
||
return $response->successful() ? $response->json()['rates'] ?? [] : [];
|
||
}
|
||
}
|