laravel-nbp maintained by beziworld
Laravel NBP
Exchange rates and gold prices from the NBP Web API (Narodowy Bank Polski) for Laravel, with the VAT invoice rate rule (art. 31a), currency conversion, caching and typed results.
Installation
composer require beziworld/laravel-nbp
php artisan vendor:publish --tag=nbp-config # optional
No API key is needed. Responses are cached: past data for 30 days, current data for 30 minutes.
Usage
use Beziworld\Nbp\Enums\Table;
use Beziworld\Nbp\Facades\Nbp;
Nbp::rate('EUR'); // latest average rate (table A)
Nbp::rate('EUR', '2026-11-03')->mid; // 4.2512
Nbp::rate('USD', table: Table::C); // ->bid / ->ask (buy and sell rates)
Nbp::rates('EUR', '2026-01-01', '2026-06-30'); // ranges longer than the API limit are split automatically
Nbp::lastRates('CHF', 10);
Nbp::table(Table::A, '2026-11-03')->rate('GBP');
Nbp::convert(100, 'EUR', 'PLN'); // 425.12 (falls back to table B for exotic currencies)
Nbp::gold(); // price of 1 g of gold in PLN
Rate for foreign currency invoices
Art. 31a of the VAT Act (and the income tax acts) require the average NBP rate from the last business day
before the tax point. invoiceRate() applies this rule, including weekends and holidays:
$rate = Nbp::invoiceRate('EUR', $invoice->sale_date);
$invoice->update([
'exchange_rate' => $rate->mid,
'exchange_table' => $rate->number, // e.g. "212/A/NBP/2026", required on the invoice
'exchange_date' => $rate->effectiveDate->toDateString(),
'vat_pln' => round($invoice->vat * $rate->mid, 2),
]);
Usage examples
Prices in several currencies in the shop
$priceEur = Nbp::convert($product->price_pln, 'PLN', 'EUR');
Daily rate snapshot (scheduler)
Schedule::call(function () {
foreach (Nbp::table()->rates as $code => $rate) {
ExchangeRate::updateOrCreate(['code' => $code, 'date' => $rate->effectiveDate], ['mid' => $rate->mid]);
}
})->weekdays()->at('12:30');
Chart data
$points = collect(Nbp::rates('EUR', now()->subYear(), now()))
->map(fn ($rate) => ['x' => $rate->effectiveDate->toDateString(), 'y' => $rate->mid]);
Errors
RateNotFound: no publication for that day (weekend, holiday, today before about 12:00 for table A) or an unknown currency.ApiException: the API rejected the request or could not be reached.- Both extend
NbpException.
Publication times: table A every business day 11:45-12:15, table B on Wednesdays, table C 07:45-08:15.
Development
composer install
composer ci # pint --test, phpstan (level 8), pest
Author
Created and maintained by Kamil Ćwiertnia, beziworld.eu.
- E-mail: biuro@beziworld.eu
- Issues: GitHub issues
Need a custom Laravel project or an accounting integration? Get in touch through beziworld.eu.
Other packages by the author
laravel-company-data · laravel-polish-validation · laravel-polish-calendar · laravel-przelewy24 · laravel-tpay · laravel-smsapi · laravel-directadmin
License
MIT. See LICENSE.md. Data source: Narodowy Bank Polski. This package is not affiliated with NBP.