brightcreations/exchange-rates 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

brightcreations/exchange-rates

Composer 安装命令:

composer require brightcreations/exchange-rates

包简介

A Laravel package for fetching exchange rates from various sources.

README 文档

README

Downloads License Last Commit Stars Tests

A comprehensive Laravel package for fetching, storing, and managing exchange rates from various external APIs. This library provides a clean, extensible architecture for handling currency exchange rates with support for both current and historical data.

🚀 Features

  • Multiple API Support: Built-in support for Exchange Rate API, Open Exchange Rates, and World Bank
  • Automatic Fallback: Intelligent fallback mechanism that tries services in order until one succeeds
  • Historical Data: Store and retrieve historical exchange rates
  • Bulk Operations: Efficient bulk operations for multiple currencies
  • Database Storage: Automatic storage and caching of exchange rates
  • Smart Caching: Automatic caching for World Bank yearly data
  • Extensible Architecture: Easy to add new exchange rate providers
  • DTO Pattern: Clean data transfer objects for type-safe operations
  • Repository Pattern: Clean separation between data access and business logic
  • Built-in REST Endpoints: Ready-to-use read-only HTTP endpoints with normal and reversed lookup modes

📦 Installation

1. Install via Composer

composer require brightcreations/exchange-rates

2. Publish Configuration and Migrations

# Publish configuration file
php artisan vendor:publish --tag=exchange-rates-config

# Publish migrations
php artisan vendor:publish --tag=exchange-rate-migrations

# Run migrations
php artisan migrate

3. Configure Environment Variables

Add the following to your .env file:

# Exchange Rate API
EXCHANGE_RATE_API_TOKEN=your_api_token_here
EXCHANGE_RATE_API_VERSION=v6
EXCHANGE_RATE_API_BASE_URL=https://v6.exchangerate-api.com/v6/

# Open Exchange Rates
OPEN_EXCHANGE_RATE_BASE_URL=https://openexchangerates.org/api/
OPEN_EXCHANGE_RATE_APP_ID=your_app_id_here

# World Bank (No API key required - Free fallback service)
WORLD_BANK_EXCHANGE_RATE_BASE_URL=https://api.worldbank.org/v2

🏗️ Architecture Overview

This library follows a clean, layered architecture:

  • Services: Handle API communication and business logic
  • Repositories: Manage database operations
  • DTOs: Type-safe data transfer objects
  • Contracts: Define interfaces for extensibility
  • Models: Eloquent models for database entities

Historical rate provider capabilities

When consuming historical rates (e.g. via brightcreations/money-converter fetchOnFail(), interpolate(), or extrapolate()), provider behaviour varies:

Provider Auto-fetch on getHistoricalExchangeRate miss Granularity Notes
OpenExchangeRateService Yes Daily Fetches and stores on ModelNotFoundException
ExchangeRateApiService Yes Daily Same as Open Exchange Rates
WorldBankExchangeRateApiService No (DB only) Yearly Pre-populate with php artisan exchange-rates:backfill
FallbackExchangeRateService Delegates to fallback order Per provider First successful provider in fallback_order wins

See money-converter historical conversion docs for how fetchOnFail, interpolate(), and extrapolate() use these capabilities.

Programmatic check:

use BrightCreations\ExchangeRates\Facades\ExchangeRate;

ExchangeRate::supportsHistoricalApiFetch(); // true when provider auto-fetches on historical miss
ExchangeRate::isSupportHistoricalExchangeRate(); // true when historical DB reads are available

Consuming with money-converter

brightcreations/money-converter is the recommended package for currency conversion in Laravel apps that use this library.

  1. Install both packages: composer require brightcreations/money-converter brightcreations/exchange-rates
  2. Follow the money-converter integration guide to publish configs, migrate, and populate rates
  3. money-converter's default PDO provider reads the same currency_exchange_rates tables this package writes

Version requirement: money-converter ^0.6.0 requires exchange-rates ^0.8.0 for bounding-rate repository methods used by interpolation and extrapolation.

📚 Documentation

🔧 Quick Start

Basic Usage

use BrightCreations\ExchangeRates\Facades\ExchangeRate;

class CurrencyController extends Controller
{
    public function getRates(string $currency = 'USD')
    {
        // Fetch from provider, store, and return current exchange rates
        $rates = ExchangeRate::storeExchangeRates($currency);

        return response()->json($rates);
    }
}

Historical Data

use BrightCreations\ExchangeRates\Facades\HistoricalExchangeRate;
use Carbon\Carbon;

class HistoricalController extends Controller
{
    public function getHistoricalRates(string $currency, string $date)
    {
        $dateTime = Carbon::parse($date);

        $rates = HistoricalExchangeRate::getHistoricalExchangeRates($currency, $dateTime);

        return response()->json($rates);
    }
}

Repository Usage

use BrightCreations\ExchangeRates\Facades\ExchangeRateRepository;

$rate = ExchangeRateRepository::getExchangeRate('USD', 'EUR');

Note: You can also use Laravel's resolve() or app() helpers to access the services directly:

$service = resolve(ExchangeRateServiceInterface::class);
$service = app(ExchangeRateServiceInterface::class);

The facades are the recommended and most convenient way for most use cases.

🌐 Built-in HTTP Endpoints

The package ships with a default read-only REST endpoint that returns exchange rates already stored in the database. It does not call any external provider — use storeExchangeRates(...) (via Artisan commands or your own code) to populate data first.

Route Configuration

Routes are enabled by default. Publish the config to customise or disable them:

// config/exchange-rates.php
'routes' => [
    'enabled'    => true,
    'prefix'     => 'exchange-rates', // segment appended after 'api/'
    'middleware' => ['api'],
],

The final URL is always api/{prefix}/..., so the default resolves to /api/exchange-rates/{currency}.

Normal Mode — rates from a base currency

GET /api/exchange-rates/{currency}

{currency} is the base currency. Returns all stored target currencies and their rates.

Parameter Location Required Description
currency path yes ISO 4217 base currency code (3 letters, e.g. USD). Case-insensitive.
currencies query string no Comma-separated target currency codes to filter by (e.g. EUR,GBP,SAR). If omitted, all stored targets are returned.

Example — all targets

GET /api/exchange-rates/USD
{
    "data": {
        "base_currency": "USD",
        "rates": [
            { "target_currency": "EUR", "rate": "0.9200000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "target_currency": "GBP", "rate": "0.7800000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "target_currency": "SAR", "rate": "3.7500000000", "last_updated": "2026-03-09T00:00:00.000000Z" }
        ]
    }
}

Example — filtered

GET /api/exchange-rates/USD?currencies=EUR,SAR
{
    "data": {
        "base_currency": "USD",
        "rates": [
            { "target_currency": "EUR", "rate": "0.9200000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "target_currency": "SAR", "rate": "3.7500000000", "last_updated": "2026-03-09T00:00:00.000000Z" }
        ]
    }
}

Reversed Mode — rates into a target currency

GET /api/exchange-rates/{currency}?reversed=true

{currency} becomes the target currency. Returns all stored source currencies that have a rate pointing to this target. Each rate is the stored source → target value (same direction as source_currencytarget_currency).

Parameter Location Required Description
currency path yes ISO 4217 target currency code (3 letters, e.g. EUR). Case-insensitive.
reversed query string yes Must be true (or 1) to activate this mode.
currencies query string no Comma-separated source currency codes to filter by (e.g. USD,GBP). If omitted, all stored sources are returned.

Example — all sources

GET /api/exchange-rates/EUR?reversed=true
{
    "data": {
        "target_currency": "EUR",
        "rates": [
            { "source_currency": "USD", "rate": "0.9200000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "source_currency": "GBP", "rate": "1.1800000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "source_currency": "SAR", "rate": "0.2453000000", "last_updated": "2026-03-09T00:00:00.000000Z" }
        ]
    }
}

Example — filtered

GET /api/exchange-rates/EUR?reversed=true&currencies=USD,SAR
{
    "data": {
        "target_currency": "EUR",
        "rates": [
            { "source_currency": "USD", "rate": "0.9200000000", "last_updated": "2026-03-09T00:00:00.000000Z" },
            { "source_currency": "SAR", "rate": "0.2453000000", "last_updated": "2026-03-09T00:00:00.000000Z" }
        ]
    }
}

Example — reciprocal pair lookup

Equivalent to GET /api/exchange-rates/GBP?currencies=USD when a GBP→USD row is stored:

GET /api/exchange-rates/USD?reversed=true&currencies=GBP
{
    "data": {
        "target_currency": "USD",
        "rates": [
            { "source_currency": "GBP", "rate": "1.3352310000", "last_updated": "2026-03-09T00:00:00.000000Z" }
        ]
    }
}

HTTP Responses

Status Meaning
200 Success. rates is an empty array when no data is stored for that currency.
422 Validation error — invalid currency code format.

🔌 Supported APIs

The library uses an intelligent fallback mechanism. By default, it tries services in this order:

  1. Open Exchange Rates (primary)
  2. Exchange Rate API (secondary)
  3. World Bank (tertiary fallback)

Exchange Rate API

  • Provider: Exchange Rate API
  • Features: Current and historical rates, real-time updates
  • Requires: API Token
  • Cost: Free tier available

Open Exchange Rates

  • Provider: Open Exchange Rates
  • Features: Current and historical rates, real-time updates
  • Requires: App ID
  • Cost: Free tier available

World Bank Exchange Rate API

  • Provider: World Bank Open Data
  • Features: Historical yearly average rates
  • Requires: No API key (free and open)
  • Cost: Free
  • Data: Yearly averages (less precise than real-time services)
  • Coverage: ~160+ currencies mapped from country data
  • Caching: 24-hour cache for efficiency

Note on World Bank Data: The World Bank service provides yearly average exchange rates based on country-level data. While less precise than real-time APIs, it serves as an excellent free fallback option. Exchange rates are computed by:

  1. Fetching LCU (Local Currency Unit) per USD rates by country
  2. Mapping countries to currencies using pragmarx/countries
  3. Computing cross-currency rates from USD-anchored values

Limitations:

  • Yearly averages only (not daily/real-time)
  • Some currencies may not be available if country mapping fails
  • Aggregate regions (like "Euro Area") are filtered out automatically

🔄 Fallback Configuration

You can customise the fallback order in config/exchange-rates.php:

'fallback_order' => [
    OpenExchangeRateService::class,
    ExchangeRateApiService::class,
    WorldBankExchangeRateApiService::class,
],

Or use a specific service directly:

use BrightCreations\ExchangeRates\Concretes\WorldBankExchangeRateApiService;

$worldBankService = app(WorldBankExchangeRateApiService::class);
$rates = $worldBankService->storeExchangeRates('EUR');

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License — see the LICENSE file for details.

🆘 Support

For support, please contact:

Made with ❤️ by Bright Creations

brightcreations/exchange-rates 适用场景与选型建议

brightcreations/exchange-rates 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 8.64k 次下载、GitHub Stars 达 1, 最近一次更新时间为 2025 年 05 月 22 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「currency conversion」 「laravel」 「exchange rates」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 brightcreations/exchange-rates 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 brightcreations/exchange-rates 我们能提供哪些服务?
定制开发 / 二次开发

基于 brightcreations/exchange-rates 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 8.64k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 15
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-05-22