承接 nurbekjummayev/cbu-currency 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

nurbekjummayev/cbu-currency

最新稳定版本:1.1.0

Composer 安装命令:

composer require nurbekjummayev/cbu-currency

包简介

Central Bank of Uzbekistan currency rates package for Laravel

README 文档

README

License: MIT PHP Version Laravel Version Tests

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

  • 📊 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 currencies table
  • 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_rates table
  • 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 in Y-m-d format (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.01
  • from - required, valid 3-letter currency code
  • to - required, valid 3-letter currency code
  • date - 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 - Success
  • 400 - 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

🔗 Useful Links

统计信息

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

GitHub 信息

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

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-08