nurbekjummayev/cbu-currency
最新稳定版本:1.1.0
Composer 安装命令:
composer require nurbekjummayev/cbu-currency
包简介
Central Bank of Uzbekistan currency rates package for Laravel
README 文档
README
A Laravel package for working with Central Bank of Uzbekistan (CBU) currency exchange rates. This package provides easy-to-use methods for fetching, storing, and converting currencies with high precision using BCMath.
English version | O'zbek versiyasi
📋 Table of Contents
- Features
- Requirements
- Installation
- Configuration
- Usage
- Artisan Commands
- Auto Synchronization
- Database Structure
- Testing
- API Endpoints
- License
✨ Features
- 📊 CBU API Integration - Fetch currency rates from Central Bank API
- 💱 High-Precision Conversion - Accurate calculations using BCMath
- 🗄️ Database Storage - Store historical rates for fast access
- 🎯 Simple API - Intuitive and convenient interface
- ⚙️ Configurable - Full configuration capabilities
- 🔄 Auto Synchronization - Automatic currency updates
- 📅 Historical Data - Rates for any date
- 🚀 RESTful API - Complete REST API endpoints
- ✅ Full Test Coverage - 43 tests included
- 🎨 Fluent Interface - Beautiful and readable code
📦 Requirements
- PHP ^8.1|^8.2|^8.3|^8.4
- Laravel ^10.0|^11.0|^12.0
- BCMath PHP Extension
- GuzzleHTTP ^7.0
🚀 Installation
1. Install via Composer
composer require nurbekjummayev/cbu-currency
2. Publish Configuration and Migrations
# Publish config file php artisan vendor:publish --tag=cbu-currency-config # Publish migrations (optional, auto-loaded by default) php artisan vendor:publish --tag=cbu-currency-migrations
⚙️ Configuration
Configuration file: config/cbu-currency.php
return [ // CBU API Base URL 'base_url' => env('CBU_BASE_URL', 'https://cbu.uz/ru/arkhiv-kursov-valyut/json'), // Cache duration in minutes 'cache_duration' => env('CBU_CACHE_DURATION', 60), // Default currency code 'default_currency' => env('CBU_DEFAULT_CURRENCY', 'USD'), // BCMath calculation scale (decimal places) 'scale' => env('CBU_SCALE', 2), // Data source: 'database' or 'api' 'source' => env('CBU_SOURCE', 'database'), // Enable/disable logging 'log_enabled' => env('CBU_LOG_ENABLED', true), // API routes configuration 'routes' => [ 'prefix' => env('CBU_ROUTES_PREFIX', 'api/cbu'), 'middleware' => ['api'], ], ];
Environment Variables
Add to your .env file:
CBU_BASE_URL=https://cbu.uz/ru/arkhiv-kursov-valyut/json CBU_CACHE_DURATION=60 CBU_DEFAULT_CURRENCY=USD CBU_SCALE=2 CBU_SOURCE=database CBU_LOG_ENABLED=true CBU_ROUTES_PREFIX=api/cbu
Data Source
The CBU_SOURCE configuration determines where currency rates are fetched from:
Option 1: Database (Recommended)
- Value:
database - Pros: Faster response, works offline, reduced API calls
- Cons: Requires periodic synchronization
- Best for: Production environments
When using database source, you need to:
Step 1: Run Migrations
php artisan migrate
This creates two tables:
currencies- stores currency information (USD, EUR, etc.)currency_rates- stores daily exchange rates
Step 2: Sync Currencies
# Fetch and store all available currencies from CBU
php artisan cbu:sync-currencies
Step 3: Fetch Exchange Rates
# Fetch today's rates php artisan cbu:fetch-rates # Fetch rates for specific date php artisan cbu:fetch-rates 2025-01-25 # Fetch yesterday's rates php artisan cbu:fetch-rates yesterday
Option 2: API (Direct)
- Value:
api - Pros: Always fresh data, no database needed
- Cons: Slower response, requires internet connection
- Best for: Development or when real-time data is critical
When using api source:
- No migrations needed
- No synchronization required
- Data fetched directly from CBU API on each request
📖 Usage
Currency Conversion
The convert() method provides a fluent interface for currency conversion with high precision using BCMath.
use Cbu\Currency\Facades\CbuCurrency; // Basic conversion $result = CbuCurrency::convert() ->from('USD') ->to('EUR') ->amount(100) ->get(); echo $result->result; // 94.11 echo $result->fromRate; // 12705.00 echo $result->toRate; // 13500.00 echo $result->amountInUzs; // 1270500.00
Convert to UZS
$result = CbuCurrency::convert() ->from('USD') ->to('UZS') ->amount(100) ->get(); echo $result->result; // 1270500.00
Convert from UZS
$result = CbuCurrency::convert() ->from('UZS') ->to('USD') ->amount(1000000) ->get(); echo $result->result; // 78.70
Cross Currency Conversion
// USD to EUR through UZS $result = CbuCurrency::convert() ->from('USD') ->to('EUR') ->amount(100) ->get(); // Calculation: 100 USD * 12705 = 1270500 UZS // 1270500 UZS / 13500 = 94.11 EUR echo $result->result; // 94.11 echo $result->amountInUzs; // 1270500.00
Using Numeric Codes
$result = CbuCurrency::convert() ->fromCode(840) // USD ->toCode(978) // EUR ->amount(100) ->get();
Specify Date
// Specific date $result = CbuCurrency::convert() ->from('USD') ->to('EUR') ->amount(100) ->date('2025-01-25') ->get(); // Today's date $result = CbuCurrency::convert() ->from('USD') ->to('EUR') ->amount(100) ->today() ->get();
Change Data Source
use Cbu\Currency\Enums\CurrencySource; // Force API source $result = CbuCurrency::convert() ->source(CurrencySource::API) ->from('USD') ->to('EUR') ->amount(100) ->get(); // Force database source $result = CbuCurrency::convert() ->source(CurrencySource::DATABASE) ->from('USD') ->to('EUR') ->amount(100) ->get();
With Caching
// Cache result for 60 minutes $result = CbuCurrency::convert() ->from('USD') ->to('EUR') ->amount(100) ->cache(60) ->get();
Get Exchange Rates
The rate() method retrieves exchange rates for specific currencies and dates.
use Cbu\Currency\Facades\CbuCurrency; // Get single currency rate for today $rate = CbuCurrency::rate('USD'); echo $rate->ccy; // "USD" echo $rate->rate; // 12705.00 echo $rate->diff; // 15.25 echo $rate->date; // "2025-11-09"
Get Rate for Specific Date
// Get USD rate for specific date $rate = CbuCurrency::rate('USD', '2025-01-25'); echo $rate->rate; // 12705.00 echo $rate->date; // "2025-01-25"
Get All Rates
// Get all currencies rates for today $rates = CbuCurrency::rate(); foreach ($rates as $rate) { echo "{$rate->ccy}: {$rate->rate}\n"; } // USD: 12705.00 // EUR: 13500.00 // RUB: 130.00
Get All Rates for Specific Date
// Get all rates for specific date $rates = CbuCurrency::rate(null, '2025-01-25'); foreach ($rates as $rate) { echo "{$rate->ccy}: {$rate->rate} ({$rate->date})\n"; }
Get Currencies List
The currencies() method retrieves available currency information.
use Cbu\Currency\Facades\CbuCurrency; // Get all currencies $currencies = CbuCurrency::currencies(); foreach ($currencies as $currency) { echo "{$currency->ccy} - {$currency->name_en}\n"; } // USD - US Dollar // EUR - Euro // RUB - Russian Ruble
Get Specific Currency
// Get single currency info $currency = CbuCurrency::currencies('USD'); echo $currency->ccy; // "USD" echo $currency->name_en; // "US Dollar" echo $currency->name_uz; // "AQSH dollari" echo $currency->name_ru; // "Доллар США" echo $currency->code; // 840
Get Currency Codes Only
// Get array of currency codes $codes = CbuCurrency::currencies()->pluck('ccy')->toArray(); // ['USD', 'EUR', 'RUB', 'GBP', 'JPY', ...]
Sync Currencies
The sync() method synchronizes currencies and rates from CBU API to your database.
use Cbu\Currency\Facades\CbuCurrency; // Sync currencies list CbuCurrency::sync('currencies'); // Sync today's rates CbuCurrency::sync('rates'); // Sync rates for specific date CbuCurrency::sync('rates', '2025-01-25');
Sync Both Currencies and Rates
// Sync both currencies and rates CbuCurrency::sync('currencies'); CbuCurrency::sync('rates');
🔧 Artisan Commands
The package provides two Artisan commands for managing currency data.
1. Sync Currencies
Fetch and store all available currencies from CBU API to database.
php artisan cbu:sync-currencies
What it does:
- Fetches all currencies from CBU API
- Adds new currencies to
currenciestable - Updates existing currency information
Example output:
Fetching currencies from CBU API...
Found 30 currencies
Synced: USD, EUR, RUB, GBP, JPY, CHF...
Currency synchronization completed successfully.
When to use:
- After initial installation
- When CBU adds new currencies
- Weekly maintenance (recommended)
2. Fetch Exchange Rates
Fetch and store exchange rates for a specific date.
# Fetch today's rates php artisan cbu:fetch-rates # Fetch for specific date php artisan cbu:fetch-rates 2025-01-25 # Fetch yesterday's rates php artisan cbu:fetch-rates yesterday # Fetch for relative date php artisan cbu:fetch-rates "1 week ago" php artisan cbu:fetch-rates "2025-01-01"
What it does:
- Fetches exchange rates from CBU API for specified date
- Stores rates in
currency_ratestable - Updates existing rates if already present
Example output:
Fetching rates for date: 2025-01-25
Found 30 rates
Saved: USD (12705.00), EUR (13500.00), RUB (130.00), GBP (16200.00)...
Currency rates fetched successfully.
When to use:
- Daily to keep rates up-to-date
- To fetch historical rates
- After syncing currencies
⏰ Auto Synchronization
For production environments, automate currency updates using Laravel's Task Scheduler.
Laravel Scheduler
Add to app/Console/Kernel.php:
<?php namespace App\Console; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { protected function schedule(Schedule $schedule) { // Fetch rates daily at 10:00 AM (after CBU updates) $schedule->command('cbu:fetch-rates') ->dailyAt('10:00') ->onFailure(function () { // Notify admin if sync fails }); // Sync currencies every Monday at 9:00 AM $schedule->command('cbu:sync-currencies') ->weekly() ->mondays() ->at('09:00'); } }
Activate Scheduler
Ensure the Laravel scheduler is running by adding this to your cron:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Alternative: Direct Cron Jobs
If not using Laravel Scheduler, add cron jobs directly:
# Fetch rates daily at 10:00 AM 0 10 * * * cd /path-to-your-project && php artisan cbu:fetch-rates # Sync currencies every Monday at 9:00 AM 0 9 * * 1 cd /path-to-your-project && php artisan cbu:sync-currencies
Docker/Kubernetes
For containerized environments, use supervisor or similar:
[program:cbu-scheduler] command=/usr/bin/php /var/www/html/artisan schedule:work autostart=true autorestart=true
🗄️ Database Structure
Currencies Table
| Column | Type | Description |
|---|---|---|
| id | bigint | Primary key |
| ccy | string | Currency code (unique) - USD, EUR, RUB |
| name_uz | string | Name in Uzbek - AQSH dollari |
| name_oz | string | Name in Uzbek (Cyrillic) - АҚШ доллари |
| name_ru | string | Name in Russian - Доллар США |
| name_en | string | Name in English - US Dollar |
| code | string | Numeric code - 840 |
| cbu_id | string | CBU identifier |
| created_at | timestamp | Creation time |
| updated_at | timestamp | Update time |
Currency Rates Table
| Column | Type | Description |
|---|---|---|
| id | bigint | Primary key |
| currency_id | bigint | Foreign key to currencies |
| date | date | Rate date (indexed) |
| currency_date | date | Original CBU date |
| rate | decimal(15,4) | Exchange rate - 12705.0000 |
| diff | decimal(15,4) | Difference from previous - 15.2500 |
| nominal | integer | Nominal value - 1 |
| created_at | timestamp | Creation time |
| updated_at | timestamp | Update time |
Indexes:
date- For fast lookups['currency_id', 'date']- Composite index
Unique constraint: ['currency_id', 'date'] - Only one rate per currency per day
🧪 Testing
The package provides full test coverage using Pest PHP framework.
Running Tests
# All tests composer test # Unit tests only vendor/bin/pest --testsuite=Unit # Feature tests only vendor/bin/pest --testsuite=Feature # Verbose mode vendor/bin/pest --verbose
For detailed testing documentation, see TESTING.md
🌐 API Endpoints
The package automatically registers RESTful API endpoints for accessing currency data.
Base URL: {your-domain}/api/cbu
1. Get All Currencies
GET /api/cbu/currencies
Response:
{
"msg": null,
"error": null,
"success": true,
"data": [
{
"ccy": "USD",
"name_uz": "AQSH dollari",
"name_en": "US Dollar",
"code": 840
},
{
"ccy": "EUR",
"name_uz": "EVRO",
"name_en": "Euro",
"code": 978
}
]
}
2. Get Currency Codes
GET /api/cbu/currencies/codes
Response:
{
"msg": null,
"error": null,
"success": true,
"data": ["USD", "EUR", "RUB", "GBP", "JPY", "CHF"]
}
3. Get Specific Currency
GET /api/cbu/currencies/{code}
Example:
GET /api/cbu/currencies/USD
Response:
{
"msg": null,
"error": null,
"success": true,
"data": {
"ccy": "USD",
"name_uz": "AQSH dollari",
"name_en": "US Dollar",
"name_ru": "Доллар США",
"code": 840
}
}
4. Get Today's Rates
GET /api/cbu/rates/today
Response:
{
"msg": null,
"error": null,
"success": true,
"data": [
{
"ccy": "USD",
"rate": 12705.00,
"diff": 15.25,
"date": "2025-11-09"
},
{
"ccy": "EUR",
"rate": 13500.00,
"diff": -10.50,
"date": "2025-11-09"
}
]
}
5. Get Rates by Date
GET /api/cbu/rates?date={date}
Query Parameters:
date(optional): Date inY-m-dformat (e.g.,2025-01-25)
Example:
GET /api/cbu/rates?date=2025-01-25
6. Get Specific Currency Rate
GET /api/cbu/rates/{code}?date={date}
Example:
GET /api/cbu/rates/USD?date=2025-01-15
Response:
{
"msg": null,
"error": null,
"success": true,
"data": {
"ccy": "USD",
"rate": 12705.00,
"diff": 15.25,
"nominal": 1,
"date": "2025-01-15"
}
}
7. Convert Currency
POST /api/cbu/convert Content-Type: application/json
Request Body:
{
"amount": 100,
"from": "USD",
"to": "EUR",
"date": "2025-01-15"
}
Response:
{
"msg": null,
"error": null,
"success": true,
"data": {
"amount": 100,
"from_currency": "USD",
"to_currency": "EUR",
"result": 94.11,
"from_rate": 12705.00,
"to_rate": 13500.00,
"amount_in_uzs": 1270500.00,
"date": "2025-01-15"
}
}
Validation Rules:
amount- required, numeric, minimum 0.01from- required, valid 3-letter currency codeto- required, valid 3-letter currency codedate- optional, Y-m-d format, cannot be future date
8. Get Conversion Rate
GET /api/cbu/convert/rate/{from}/{to}?date={date}
Returns the conversion rate for 1 unit of source currency.
Example:
GET /api/cbu/convert/rate/USD/EUR?date=2025-01-15
Response:
{
"msg": null,
"error": null,
"success": true,
"data": {
"amount": 1,
"from_currency": "USD",
"to_currency": "EUR",
"result": 0.94,
"from_rate": 12705.00,
"to_rate": 13500.00,
"amount_in_uzs": 12705.00,
"date": "2025-01-15"
}
}
Error Responses
All endpoints return a consistent error format:
{
"msg": "Currency not found",
"error": "The currency code 'XYZ' does not exist",
"success": false,
"data": []
}
Common HTTP Status Codes:
200- Success400- Bad Request (validation failed)404- Not Found (currency or rate not found)500- Internal Server Error
Customizing API Routes
You can customize the API route prefix in config/cbu-currency.php:
'routes' => [ 'prefix' => env('CBU_ROUTES_PREFIX', 'api/cbu'), 'middleware' => ['api'], ],
Or in .env:
CBU_ROUTES_PREFIX=api/v1/currency
📄 License
MIT License. See LICENSE file for details.
👨💻 Author
Nurbek Jummayev
- GitHub: @nurbekjummayev
- Email: jummayevnurbek279@gmail.com
🔗 Useful Links
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-11-08