PHPackages                             rechtlogisch/evatr - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. rechtlogisch/evatr

ActiveLibrary

rechtlogisch/evatr
==================

Checks a VAT-ID using the eVatR REST-API of the German Federal Central Tax Office (Bundeszentralamt für Steuern, BZSt)

0.1.0(9mo ago)2313↓50%[1 PRs](https://github.com/rechtlogisch/evatr-php/pulls)MITPHPPHP ^8.2CI passing

Since Aug 8Pushed 5mo ago1 watchersCompare

[ Source](https://github.com/rechtlogisch/evatr-php)[ Packagist](https://packagist.org/packages/rechtlogisch/evatr)[ Docs](https://github.com/rechtlogisch/evatr-php)[ RSS](/packages/rechtlogisch-evatr/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (9)Versions (4)Used By (0)

[![Recht logisch eVatR banner image](rechtlogisch-evatr-banner.png)](rechtlogisch-evatr-banner.png)

[![Latest Version on Packagist](https://camo.githubusercontent.com/07d98fe7d46a69b7c0bbd2b7b0bf2f6e7ef50b7d900bbc82b4cfb785fbbb1f8b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f72656368746c6f67697363682f65766174722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rechtlogisch/evatr)[![Tests](https://camo.githubusercontent.com/f0e637288b8ee586ac4278003d1dd05323b613008e87f280837c0f393a6d195f/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f72656368746c6f67697363682f65766174722d7068702f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/rechtlogisch/evatr-php/actions/workflows/run-tests.yml)[![codecov](https://camo.githubusercontent.com/48f1fedfeabe3c2163f6273f29649ca966ecf4aed73922d6528eac8276a78405/68747470733a2f2f636f6465636f762e696f2f6769746875622f72656368746c6f67697363682f65766174722d7068702f67726170682f62616467652e7376673f746f6b656e3d)](https://codecov.io/github/rechtlogisch/evatr-php)[![Total Downloads](https://camo.githubusercontent.com/f558d505486e737f1c2c789b35f4acf59665f98a1fda2c10a4f3f448ab7cf85a/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f72656368746c6f67697363682f65766174722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/rechtlogisch/evatr)

evatr
=====

[](#evatr)

> Checks a VAT-ID using the eVatR REST-API of the German Federal Central Tax Office (Bundeszentralamt für Steuern, BZSt)

Caution

This package is in early development and is not yet ready for production use. It is currently being tested and may undergo significant changes.

Important

This is an unofficial wrapper for the eVatR API. For official documentation and terms of use, please refer to the [German Federal Central Tax Office (BZSt)](https://www.bzst.de/DE/Unternehmen/Identifikationsnummern/Umsatzsteuer-Identifikationsnummer/umsatzsteuer-identifikationsnummer_node.html) website.

Note

This package uses the new REST-API released in July 2025. The old XML-RPC API is being discontinued and will be sunset on **November 30th, 2025** (based on information from BZSt-Newsletter USTKV 01/2025 dated July 1st, 2025).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require rechtlogisch/evatr
```

Quick Start
-----------

[](#quick-start)

### Simple Validation

[](#simple-validation)

Validates only the VAT-ID without company data verification:

```
use Rechtlogisch\Evatr\Evatr;

$result = (new Evatr(
  vatIdOwn: 'DE123456789',     // Your German VAT-ID (required)
  vatIdForeign: 'ATU12345678', // VAT-ID to validate (required)
))->check();
```

or alternatively use the helper function:

```
$result = checkVatId(vatIdOwn: 'DE123456789', vatIdForeign: 'ATU12345678');
```

### Qualified Confirmation

[](#qualified-confirmation)

Validates VAT-ID and verifies company data:

```
use Rechtlogisch\Evatr\Evatr;

$result = (new Evatr(
  vatIdOwn: 'DE123456789',            // Your German VAT-ID (required)
  vatIdForeign: 'ATU12345678',        // VAT-ID to validate (required)
  company: 'Musterhaus GmbH & Co KG', // Company name (required for qualified confirmation)
  location: 'Musterort',              // City (required for qualified confirmation)
  street: 'Musterstrasse 22',         // Street address (optional)
  zip: '12345',                       // Postal code (optional)
))->check();
```

or alternatively use the helper function:

```
$result = confirmVatId(
  vatIdOwn: 'DE123456789',
  vatIdForeign: 'ATU12345678',
  company: 'Musterhaus GmbH & Co KG',
  street: 'Musterstrasse 22',
  zip: '12345',
  location: 'Musterort',
);
```

### Including Raw Response

[](#including-raw-response)

```
$result = (new Evatr(
  vatIdOwn: 'DE123456789',
  vatIdForeign: 'ATU12345678'
))->includeRaw()->check();
```

or with helper functions

```
$result = checkVatId(
  vatIdOwn: 'DE123456789',
  vatIdForeign: 'ATU12345678',
  includeRaw: true
);
```

API Reference
-------------

[](#api-reference)

### Constructor

[](#constructor)

```
$evatr = new Evatr(
  vatIdOwn: string,      // Your German VAT-ID (required)
  vatIdForeign: string,  // VAT-ID to confirm (required)
  company: ?string,      // Company name (optional, required for qualified confirmation)
  location: ?string,     // City (optional, required for qualified confirmation)
  street: ?string,       // Street address (optional)
  zip: ?string,          // Postal code (optional)
);
```

or alternatively using RequestDto:

```
$request = new RequestDto(
  vatIdOwn: 'DE123456789',
  vatIdForeign: 'ATU12345678',
  // ... other parameters
);
$evatr = new Evatr($request);
```

### Methods

[](#methods)

#### check(): ResultDto

[](#check-resultdto)

Performs the VAT-ID confirmation:

```
$result = $evatr->check();
```

#### includeRaw(bool $value = true): self

[](#includerawbool-value--true-self)

Includes the raw API response in the result:

```
$evatr->includeRaw(true)->check();
```

### Response Object (ResultDto)

[](#response-object-resultdto)

The `check()` method returns a `ResultDto` object with the following methods:

```
$result->getVatIdOwn(): string;         // Own VAT-ID which was used for the request
$result->getVatIdForeign(): string;     // Foreign VAT-ID which was checked
$result->getId(): string;              // Unique ID from API, related to request
$result->getHttpStatusCode(): ?int;     // HTTP status code
$result->getTimestamp(): ?string;       // Query timestamp (ISO-8601 string)
$result->getStatus(): ?Status;          // Status enum
$result->getMessage(): ?string;         // Human-readable message based on EVATR_LANG
$result->getDateFrom(): ?string;        // Valid from date
$result->getDateTill(): ?string;        // Valid until date
$result->getCompany(): ?QualifiedResult;   // Company validation result
$result->getStreet(): ?QualifiedResult;    // Street validation result
$result->getZip(): ?QualifiedResult;       // ZIP validation result
$result->getLocation(): ?QualifiedResult;  // Location validation result
$result->getRaw(): ?string;             // Raw API response (if requested)
$result->toArray(): array;              // Convert to array
```

### Status Codes

[](#status-codes)

The API returns various status codes via the `Status` enum. All status codes are available as enum cases:

```
use Rechtlogisch\Evatr\Enum\Status;

// Check the status
if ($result->getStatus() === Status::EVATR_0000) {
  // VAT-ID is valid
}

// Get human-readable description
$description = $result->getStatus()->description();
```

### Validation Results (Qualified Confirmation)

[](#validation-results-qualified-confirmation)

For qualified confirmations, the response includes validation results for each field via the `QualifiedResult` enum:

- **A** - Data matches registered information
- **B** - Data does not match registered information
- **C** - Data was not requested
- **D** - Data not provided by the EU member state

```
use Rechtlogisch\Evatr\Enum\QualifiedResult;

if ($result->getCompany() === QualifiedResult::A) {
  // Company name matches
}
```

### Helper Functions

[](#helper-functions)

The package provides convenient helper functions:

#### checkVatId()

[](#checkvatid)

```
function checkVatId(
    string $vatIdOwn,
    string $vatIdForeign,
    bool $includeRaw = false
): ResultDto;
```

#### confirmVatId()

[](#confirmvatid)

```
function confirmVatId(
  string $vatIdOwn,
  string $vatIdForeign,
  ?string $company,
  ?string $street,
  ?string $zip,
  ?string $location,
  bool $includeRaw = false
): ResultDto;
```

### Field Mapping

[](#field-mapping)

The API uses German terms, which have been mapped to parameters:

#### Request

[](#request)

BZSt APIevatranfragendeUstidvatIdOwnangefragteUstidvatIdForeignfirmennamecompanyortlocationstrassestreetplzzip#### Response

[](#response)

BZSt APIevatrididanfrageZeitpunkttimestampgueltigAbdateFromgueltigBisdateTillergFirmennamecompanyergStrassestreetergPlzzipergOrtlocation### Language of status messages (EVATR\_LANG)

[](#language-of-status-messages-evatr_lang)

By default, status messages (human-readable descriptions of evatr-\* codes) are returned in German. To switch to English messages, set the following environment variable:

```
# .env
EVATR_LANG=en
```

Warning

This English translation of the status messages is unofficial. Use at your own risk.

Supported values:

- de (default): German messages
- en: English messages

This affects:

- Status::description()
- ResultDto-&gt;toArray()\['message'\]

### Additional endpoints and helpers

[](#additional-endpoints-and-helpers)

The client exposes supplementary endpoints of the eVatR API.

#### Status messages

[](#status-messages)

```
$messages = Evatr::getStatusMessages(); // array of DTO\StatusMessage
```

Each StatusMessage item has the shape:

```
use Rechtlogisch\Evatr\DTO\StatusMessage;

$statusMessage = new StatusMessage(
  status: 'evatr-0000',
  category: 'Result', // category is always English and language-invariant: Result | Error | Hint
  http: 200,
  field: null,
  message: 'Die angefragte Ust-IdNr. ist zum Anfragezeitpunkt gültig.'
);
```

#### EU member states availability

[](#eu-member-states-availability)

```
$states = Evatr::getAvailability(); // array map of code => available
// Example: [ 'DE' => true, 'AT' => false, ... ]

// Only not available:
$notAvailable = Evatr::getAvailability(onlyNotAvailable: true); // [ 'AT' => false, ... ]
```

Error Handling
--------------

[](#error-handling)

All public API methods throw exceptions on failure, and return only DTOs on success.

- ErrorResponse: thrown for transport, server, or JSON/response parsing errors.
- InputError: thrown when the error is caused by invalid input, and can be potentially fixed by the user.

```
use Rechtlogisch\Evatr\Exception\ErrorResponse;
use Rechtlogisch\Evatr\Exception\InputError;
use Rechtlogisch\Evatr\Enum\Status;

try {
    $result = checkVatId('DE123456789', 'ATU12345678');
    // handle result
} catch (InputError|ErrorResponse $e) {
    // Log/handle error: $e->getMessage()
    // Get original exception: $e->getException()
}
```

### ErrorResponse exception

[](#errorresponse-exception)

Thrown when a request fails due to transport or response parsing issues.

Fields:

- httpCode: int HTTP status or 0 for client-side failures
- error: string short description
- exception: Throwable the underlying/previous exception; if no underlying Throwable existed, a RuntimeException is used
- raw: ?string raw response body if available
- meta: array&lt;string,mixed&gt; additional context (e.g., endpoint, errorType)

Example:

```
use Rechtlogisch\Evatr\Exception\ErrorResponse;

try {
    $result = checkVatId('DE123456789', 'ATU12345678');
} catch (ErrorResponse $e) {
    $code = $e->getHttpCode();
    $msg  = $e->getError();
    $previous = $e->getException(); // underlying Throwable (e.g., JsonException, GuzzleException, or RuntimeException)
    $raw  = $e->getRaw();   // may be null
    $meta = $e->getMeta();  // ['endpoint' => ..., 'errorType' => ...]
    // Handle/log accordingly
}
```

Testing
-------

[](#testing)

### Running Tests

[](#running-tests)

```
composer test
```

### Test Data

[](#test-data)

The library includes test VAT-IDs that can be used for development and testing:

```
// Simple validation test
$testRequest = [
  'vatIdOwn' => 'DE123456789',
  'vatIdForeign' => 'ATU12345678',
];

// Qualified confirmation test
$qualifiedTestRequest = [
  'vatIdOwn' => 'DE123456789',
  'vatIdForeign' => 'ATU12345678',
  'company' => 'Musterhaus GmbH & Co KG',
  'street' => 'Musterstrasse 22',
  'zip' => '12345',
  'location' => 'Musterort',
];
```

### Environment Variables

[](#environment-variables)

For testing with real VAT-IDs, you can set environment variables:

```
# .env
VATID_OWN=DE123456789
VATID_FOREIGN=ATU12345678
```

Rate Limits and Best Practices
------------------------------

[](#rate-limits-and-best-practices)

- The API has rate limits. Implement appropriate delays between requests
- Cache results when possible to reduce API calls
- Handle all possible status codes in your application
- Always validate VAT-ID formats before making API calls

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/spatie/.github/blob/main/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

If you discover any security-related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Krzysztof Tomasz Zembrowski](https://github.com/zembrowski)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance64

Regular maintenance activity

Popularity20

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 83.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

3

Last Release

278d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/4f60f360e9d79540ea00427585d1b0063f2c1125ef8d22be6939428ffb68ccc1?d=identicon)[rechtlogisch](/maintainers/rechtlogisch)

---

Top Contributors

[![zembrowski](https://avatars.githubusercontent.com/u/2451083?v=4)](https://github.com/zembrowski "zembrowski (15 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (3 commits)")

---

Tags

wrapperVAT IDgermanyrechtlogischevatrbzst

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/rechtlogisch-evatr/health.svg)

```
[![Health](https://phpackages.com/badges/rechtlogisch-evatr/health.svg)](https://phpackages.com/packages/rechtlogisch-evatr)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.7k509.9M17.0k](/packages/laravel-framework)[netflie/whatsapp-cloud-api

The first PHP SDK to send and receive messages using a cloud-hosted version of the WhatsApp Business Platform

640431.7k4](/packages/netflie-whatsapp-cloud-api)[tempest/framework

The PHP framework that gets out of your way.

2.1k23.1k9](/packages/tempest-framework)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[descope/descope-php

Descope SDK for PHP

3814.0k](/packages/descope-descope-php)[dariusiii/tmdb-laravel

Laravel Package for TMDB ( The Movie Database ) API. Provides easy access to the wtfzdotnet/php-tmdb-api library.

1821.1k](/packages/dariusiii-tmdb-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
