Looking to hire Laravel developers? Try LaraJobs

laravel-company-data maintained by beziworld

Description
Polish company data for Laravel: GUS REGON (BIR) lookup, VAT white list (Biała lista) with bank account checks and EU VIES validation.
Last update
2026/11/04 14:35 (dev-master)
License
Downloads
1
Tags

Comments
comments powered by Disqus

Laravel Company Data

tests Latest Version License

Polish and EU company data for Laravel from three official sources:

  • GUS REGON (BIR 1.1/1.2): company name, address, type and full reports by NIP, REGON or KRS
  • VAT white list (Wykaz podatników VAT): VAT status, registered bank accounts and account checks with a request id as evidence
  • VIES: validation of EU VAT numbers

Polska wersja dokumentacji

Installation

composer require beziworld/laravel-company-data
php artisan vendor:publish --tag=company-data-config   # optional
GUS_API_KEY=your-key          # free, request it at regon_bir@stat.gov.pl
GUS_SANDBOX=false             # true: test database with the public test key
VIES_REQUESTER_COUNTRY=PL     # optional: get a VIES consultation number
VIES_REQUESTER_VAT_NUMBER=PL1234563218

The white list and VIES need no keys. Lookups are cached for 12 hours (the white list allows only 100 searches a day per IP address).

GUS

use Beziworld\CompanyData\Facades\Gus;

$company = Gus::findByNip('526-104-08-28');   // or findByRegon(), findByKrs(), findManyByNip([...])

$company->name;            // "GŁÓWNY URZĄD STATYSTYCZNY"
$company->regon;           // "000331501"
$company->type;            // EntityType::LegalEntity
$company->address();       // "ul. Test-Krucza 208, 00-925 Warszawa"
$company->isActive();

Gus::fullReport($company);  // all registered fields; the report is chosen from the entity type
Gus::pkd($company);         // PKD codes
Gus::dataDate();            // date of the register data

Sessions are opened on demand, cached for 55 minutes and renewed automatically when GUS expires them.

VAT white list

use Beziworld\CompanyData\Facades\WhiteList;

$taxpayer = WhiteList::searchNip('5261040828');           // state of the register today
$taxpayer = WhiteList::searchNip('5261040828', '2026-10-01');

$taxpayer?->status;              // VatStatus::Active / Exempt / NotRegistered
$taxpayer?->accountNumbers;      // list of 26-digit NRB numbers
$taxpayer?->representatives;

$check = WhiteList::checkAccount('5261040828', 'PL61 1090 1014 0000 0712 1981 2874');
$check->assigned;                // true when the account belongs to an active VAT payer (virtual accounts included)
$check->requestId;               // "I55y3-996fi98": store it as evidence of the check

Paying an invoice above PLN 15,000 to an account that is not on the white list can make the payer jointly liable for the supplier's VAT and excludes the expense from tax costs. Store requestId with the payment.

The API moved to wykazpodatnikowvat.mf.gov.pl in October 2026 (the old wl-api.mf.gov.pl stops on 1 December 2026); the package uses the new host by default.

VIES

use Beziworld\CompanyData\Facades\Vies;

$result = Vies::check('DE811569869');   // or check('811569869', 'DE')
$result->valid;
$result->name;                          // null when the member state does not disclose it
$result->requestIdentifier;             // consultation number when requester data are configured

Vies::isValid('PL5261040828');
Vies::status();                         // ['PL' => true, 'DE' => false, ...]

National systems are often temporarily unavailable or rate limited (MS_UNAVAILABLE, MS_MAX_CONCURRENT_REQ). Such errors are retried and, if they persist, thrown as ViesException with isTemporary() === true. An invalid number is not an exception: it returns valid === false.

Usage examples

Fill in the company form from NIP

Route::get('/api/company/{nip}', function (string $nip) {
    $company = Gus::findByNip($nip);

    abort_if($company === null, 404);

    return [
        'name' => $company->name,
        'street' => $company->streetLine(),
        'postal_code' => $company->postalCode,
        'city' => $company->postCity ?? $company->city,
        'regon' => $company->regon,
    ];
});

Verify a supplier before paying

public function pay(Invoice $invoice): void
{
    $check = WhiteList::checkAccount($invoice->supplier_nip, $invoice->bank_account);

    if (! $check->assigned && $invoice->gross >= 15000) {
        throw new SupplierAccountNotVerified($invoice);
    }

    $invoice->payments()->create([
        'amount' => $invoice->gross,
        'white_list_request_id' => $check->requestId,
    ]);
}

Reverse charge for EU customers

try {
    $reverseCharge = Vies::check($order->vat_number)->valid;
} catch (ViesException $e) {
    $reverseCharge = false;   // or queue a re-check when $e->isTemporary()
}

Combine it with beziworld/laravel-polish-validation to validate the NIP checksum before calling the APIs.

Exceptions

GusException, WhiteListException (errorCode() such as WL-191, isLimitExceeded(), isTemporary()) and ViesException (errorCode(), isTemporary()), all extending CompanyDataException.

Development

composer install
composer ci   # pint --test, phpstan (level 8), pest

Author

Created and maintained by Kamil Ćwiertnia, beziworld.eu.

Need a B2B integration or a custom Laravel project? Get in touch through beziworld.eu.

Other packages by the author

laravel-polish-validation · laravel-polish-calendar · laravel-nbp · laravel-przelewy24 · laravel-tpay · laravel-smsapi · laravel-directadmin

License

MIT. See LICENSE.md. Data sources: Statistics Poland (GUS), Ministry of Finance, European Commission. This package is not affiliated with any of them.