diff --git a/src/app/Backends/OpenExchangeRates.php b/src/app/Backends/OpenExchangeRates.php new file mode 100644 --- /dev/null +++ b/src/app/Backends/OpenExchangeRates.php @@ -0,0 +1,50 @@ + $apiKey, 'base' => 'USD']); + $url = 'https://openexchangerates.org/api/latest.json?' . $query; + $html = file_get_contents($url, false); + $rates = []; + + if ($html && ($result = json_decode($html, true)) && !empty($result['rates'])) { + foreach ($result['rates'] as $code => $rate) { + $rates[strtoupper($code)] = $rate; + } + + if ($baseCurrency != 'USD') { + if ($base = $rates[$baseCurrency]) { + foreach ($rates as $code => $rate) { + $rates[$code] = $rate / $base; + } + } else { + $rates = []; + } + } + + foreach ($rates as $code => $rate) { + \Log::debug(sprintf("Update %s: %0.8f", $code, $rate)); + } + } else { + throw new \Exception("Failed to parse exchange rates"); + } + + if (count($rates) > 1) { + $rates[$baseCurrency] = 1; + return $rates; + } + + throw new \Exception("Failed to retrieve exchange rates"); + } +} diff --git a/src/app/Console/Commands/Data/Import/ExchangerateCommand.php b/src/app/Console/Commands/Data/Import/ExchangerateCommand.php new file mode 100644 --- /dev/null +++ b/src/app/Console/Commands/Data/Import/ExchangerateCommand.php @@ -0,0 +1,48 @@ +argument('sourceCurrency')); + $rates = \App\Backends\OpenExchangeRates::retrieveRates($sourceCurrency); + + // + // export + // + $file = resource_path("exchangerates-$sourceCurrency.php"); + + $out = " $rate) { + $out .= sprintf(" '%s' => '%s',\n", $countryCode, $rate); + } + + $out .= "];\n"; + + file_put_contents($file, $out); + } +} diff --git a/src/app/Providers/Payment/Mollie.php b/src/app/Providers/Payment/Mollie.php --- a/src/app/Providers/Payment/Mollie.php +++ b/src/app/Providers/Payment/Mollie.php @@ -562,15 +562,15 @@ $providerMethods = array_merge( // Fallback to EUR methods (later provider methods will override earlier ones) - //mollie()->methods()->allActive( - // [ - // 'sequenceType' => $type, - // 'amount' => [ - // 'value' => '1.00', - // 'currency' => 'EUR' - // ] - // ] - //), + (array)mollie()->methods()->allActive( + [ + 'sequenceType' => $type, + 'amount' => [ + 'value' => '1.00', + 'currency' => 'EUR' + ] + ] + ), // Prefer CHF methods (array)mollie()->methods()->allActive( [ diff --git a/src/app/Providers/PaymentProvider.php b/src/app/Providers/PaymentProvider.php --- a/src/app/Providers/PaymentProvider.php +++ b/src/app/Providers/PaymentProvider.php @@ -199,8 +199,7 @@ protected function exchangeRate(string $sourceCurrency, string $targetCurrency): float { if (strcasecmp($sourceCurrency, $targetCurrency)) { - throw new \Exception("Currency conversion is not yet implemented."); - //FIXME Not yet implemented + return \App\Utils::exchangeRate($sourceCurrency, $targetCurrency); } return 1.0; } @@ -312,11 +311,10 @@ 'id' => self::METHOD_PAYPAL, 'icon' => self::$paymentMethodIcons[self::METHOD_PAYPAL] ], - // TODO Enable once we're ready to offer them - // self::METHOD_BANKTRANSFER => [ - // 'id' => self::METHOD_BANKTRANSFER, - // 'icon' => self::$paymentMethodIcons[self::METHOD_BANKTRANSFER] - // ] + self::METHOD_BANKTRANSFER => [ + 'id' => self::METHOD_BANKTRANSFER, + 'icon' => self::$paymentMethodIcons[self::METHOD_BANKTRANSFER] + ] ]; case PaymentProvider::TYPE_RECURRING: return [ diff --git a/src/app/Utils.php b/src/app/Utils.php --- a/src/app/Utils.php +++ b/src/app/Utils.php @@ -5,6 +5,7 @@ use Carbon\Carbon; use Illuminate\Support\Facades\Auth; use Ramsey\Uuid\Uuid; +use Illuminate\Support\Facades\Cache; /** * Small utility functions for App. @@ -406,4 +407,24 @@ return $env; } + + + /** + * Retrieve an exchange rate. + * + * @param string $sourceCurrency: Currency from which to convert + * @param string $targetCurrency: Currency to convert to + * + * @return float Exchange rate + */ + public static function exchangeRate(string $sourceCurrency, string $targetCurrency): float + { + $rates = include resource_path("exchangerates-$sourceCurrency.php"); + + if (!isset($rates[$targetCurrency])) { + throw new \Exception("Failed to find exchange rate for " . $targetCurrency); + } + + return floatval($rates[$targetCurrency]); + } } diff --git a/src/config/currency.php b/src/config/currency.php --- a/src/config/currency.php +++ b/src/config/currency.php @@ -1,116 +1,5 @@ 'USD', - - /* - |-------------------------------------------------------------------------- - | API Key for OpenExchangeRates.org - |-------------------------------------------------------------------------- - | - | Only required if you with to use the Open Exchange Rates api. You can - | always just use Yahoo, the current default. - | - */ - - 'api_key' => env('OPENEXCHANGERATES_API_KEY', null), - - /* - |-------------------------------------------------------------------------- - | Default Storage Driver - |-------------------------------------------------------------------------- - | - | Here you may specify the default storage driver that should be used - | by the framework. - | - | Supported: "database", "filesystem" - | - */ - - 'driver' => 'filesystem', - - /* - |-------------------------------------------------------------------------- - | Default Storage Driver - |-------------------------------------------------------------------------- - | - | Here you may specify the default cache driver that should be used - | by the framework. - | - | Supported: all cache drivers supported by Laravel - | - */ - - 'cache_driver' => null, - - /* - |-------------------------------------------------------------------------- - | Storage Specific Configuration - |-------------------------------------------------------------------------- - | - | Here you may configure as many storage drivers as you wish. - | - */ - - 'drivers' => [ - - 'database' => [ - 'class' => \Torann\Currency\Drivers\Database::class, - 'connection' => null, - 'table' => 'currencies', - ], - - 'filesystem' => [ - 'class' => \Torann\Currency\Drivers\Filesystem::class, - 'disk' => null, - 'path' => 'currencies.json', - ], - - ], - - /* - |-------------------------------------------------------------------------- - | Currency Formatter - |-------------------------------------------------------------------------- - | - | Here you may configure a custom formatting of currencies. The reason for - | this is to help further internationalize the formatting past the basic - | format column in the table. When set to `null` the package will use the - | format from storage. - | - | More info: - | http://lyften.com/projects/laravel-currency/doc/formatting.html - | - */ - - 'formatter' => null, - - /* - |-------------------------------------------------------------------------- - | Currency Formatter Specific Configuration - |-------------------------------------------------------------------------- - | - | Here you may configure as many currency formatters as you wish. - | - */ - - 'formatters' => [ - - 'php_intl' => [ - 'class' => \Torann\Currency\Formatters\PHPIntl::class, - ], - - ], + 'openexchangerates_api_key' => env('OPENEXCHANGERATES_API_KEY', null), ];