aade/afm-lookup

PHP client for querying Greek VAT/AFM numbers via AADE's official SOAP service

Maintainers

Package info

github.com/klipitkas/aade-public-search-afm

pkg:composer/aade/afm-lookup

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.1 2026-01-17 06:24 UTC

This package is auto-updated.

Last update: 2026-03-17 06:59:59 UTC


README

PHP library for querying Greek VAT (AFM) numbers via AADE's official SOAP service.

PHP Version License

Quick Start

composer require aade/afm-lookup
use Aade\AfmLookup\AadeClient;

$client = new AadeClient('your_username', 'your_password');
$response = $client->getVatInfo('094014201');

if ($response->success) {
    echo $response->basic->name;        // Business name
    echo $response->basic->afm;         // VAT number
    echo $response->basic->isActive;    // true/false
}

Note: You need AADE credentials. Register here.

Table of Contents

Requirements

Requirement Version
PHP >= 8.1
ext-soap *
ext-dom *

Installation

composer require aade/afm-lookup

Usage Guide

Creating a Client

Basic:

use Aade\AfmLookup\AadeClient;

$client = new AadeClient('your_username', 'your_password');

With options:

$client = new AadeClient(
    username: 'your_username',
    password: 'your_password',
    callerAfm: '123456789',  // Your AFM (for AADE logging)
    timeout: 60,             // Seconds (default: 30)
    verifySsl: true,         // Default: true
);

Looking Up an AFM

$response = $client->getVatInfo('094014201');

if ($response->success) {
    $info = $response->basic;

    // Business identity
    echo $info->afm;                    // "094014201"
    echo $info->name;                   // "ΔΗΜΟΣΙΑ ΕΠΙΧΕΙΡΗΣΗ ΗΛΕΚΤΡΙΣΜΟΥ Α.Ε."
    echo $info->commercialTitle;        // "ΔΕΗ Α.Ε."

    // Tax office
    echo $info->doyCode;                // "1159"
    echo $info->doyDescription;         // "Φ.Α.Ε. ΑΘΗΝΩΝ"

    // Address
    echo $info->postalAddress;          // "ΧΑΛΚΟΚΟΝΔΥΛΗ"
    echo $info->postalAddressNumber;    // "30"
    echo $info->postalZipCode;          // "10432"
    echo $info->postalCity;             // "ΑΘΗΝΑ"

    // Status
    echo $info->isActive;               // true
    echo $info->isNormalVat;            // true
    echo $info->legalStatusDescription; // "ΑΕ"

    // Dates (DateTimeImmutable or null)
    echo $info->registrationDate?->format('d/m/Y');  // "01/01/1950"
    echo $info->stopDate;                            // null (if active)
}

Validating AFM Format

Validate locally before making an API call:

use Aade\AfmLookup\AadeClient;

// Static method - no API call
if (AadeClient::validateAfm('094014201')) {
    // Valid format (9 digits, correct check digit)
}

// Invalid examples:
AadeClient::validateAfm('12345678');   // false - only 8 digits
AadeClient::validateAfm('000000000');  // false - all zeros
AadeClient::validateAfm('094014202');  // false - wrong check digit

Historical Lookups

Query business information as it was on a specific date:

use DateTimeImmutable;

// Get info as of January 15, 2023
$date = new DateTimeImmutable('2023-01-15');
$response = $client->getVatInfo('094014201', $date);

Date format: The library accepts any DateTimeInterface implementation. Internally, dates are sent to AADE in Y-m-d format (e.g., 2023-01-15).

Business Activities

Each business can have multiple registered activities (KAD codes):

$response = $client->getVatInfo('094014201');

// Get main activity
$main = $response->getMainActivity();
if ($main !== null) {
    echo $main->code;           // "35.11"
    echo $main->description;    // "Παραγωγή ηλεκτρικής ενέργειας"
}

// Iterate all activities
foreach ($response->firmActivities as $activity) {
    echo $activity->code;            // KAD code
    echo $activity->description;     // Activity description
    echo $activity->kind;            // 1 = main, 2+ = secondary
    echo $activity->kindDescription; // "ΚΥΡΙΑ" or "ΔΕΥΤΕΡΕΥΟΥΣΑ"
    echo $activity->isMainActivity(); // true/false
}

Error Handling

use Aade\AfmLookup\AadeClient;
use Aade\AfmLookup\Exception\InvalidAfmException;
use Aade\AfmLookup\Exception\AuthenticationException;
use Aade\AfmLookup\Exception\RateLimitException;
use Aade\AfmLookup\Exception\SoapException;
use Aade\AfmLookup\Exception\AadeException;

try {
    $response = $client->getVatInfo('094014201');
} catch (InvalidAfmException $e) {
    // AFM format is invalid (checked locally before API call)
} catch (AuthenticationException $e) {
    // Wrong username/password or account not authorized
} catch (RateLimitException $e) {
    // Daily call limit exceeded
} catch (SoapException $e) {
    // Network error or SOAP fault
} catch (AadeException $e) {
    // Other AADE service errors
    $errorCode = $e->getErrorCode(); // ErrorCode enum or null
}

Checking error types via ErrorCode:

if ($e->getErrorCode()?->isAuthenticationError()) { /* ... */ }
if ($e->getErrorCode()?->isRateLimitError()) { /* ... */ }
if ($e->getErrorCode()?->isNotFoundError()) { /* ... */ }
if ($e->getErrorCode()?->isBlockedError()) { /* ... */ }

API Reference

AadeClient

public function __construct(
    string $username,
    string $password,
    ?string $callerAfm = null,
    int $timeout = 30,
    bool $verifySsl = true,
)
Method Returns Description
getVatInfo(string $afm, ?DateTimeInterface $asOnDate = null) AfmInfoResponse Query AFM information
getVersion() string Get AADE service version
validateAfm(string $afm) bool Validate AFM format (static)

Response Objects

AfmInfoResponse

Property Type Description
success bool true if lookup succeeded
callSequenceId ?string AADE call tracking ID
basic ?BasicInfo Business information
firmActivities FirmActivity[] List of activities
error ?ErrorInfo Error details (if failed)
Method Returns Description
getMainActivity() ?FirmActivity Get primary business activity

BasicInfo

Property Type Description
afm ?string VAT number
name ?string Legal business name
commercialTitle ?string Commercial/trade name
doyCode ?string Tax office code
doyDescription ?string Tax office name
legalStatusCode ?string Legal form code
legalStatusDescription ?string Legal form (ΑΕ, ΕΠΕ, etc.)
postalAddress ?string Street name
postalAddressNumber ?string Street number
postalZipCode ?string Postal code
postalCity ?string City
registrationDate ?DateTimeImmutable Registration date
stopDate ?DateTimeImmutable Deactivation date
isNormalVat bool Normal VAT regime
isActive bool Currently active

FirmActivity

Property Type Description
code ?string KAD activity code
description ?string Activity description
kind ?int 1 = main, 2+ = secondary
kindDescription ?string Kind label
Method Returns Description
isMainActivity() bool Check if primary activity

ErrorInfo

Property Type Description
code ?ErrorCode Error code enum
description ?string Error message from AADE

AADE Error Codes

Code Description Exception Type
RG_WS_PUBLIC_TOKEN_USERNAME_NOT_AUTHENTICATED Invalid credentials AuthenticationException
RG_WS_PUBLIC_TOKEN_USERNAME_NOT_DEFINED Username missing AuthenticationException
RG_WS_PUBLIC_TOKEN_USERNAME_NOT_ACTIVE Account inactive AuthenticationException
RG_WS_PUBLIC_TOKEN_AFM_NOT_AUTHORIZED AFM not authorized AuthenticationException
RG_WS_PUBLIC_MAX_DAILY_CALLS_EXCEEDED Daily limit reached RateLimitException
RG_WS_PUBLIC_MAX_DAILY_USERNAME_CALLS_EXCEEDED User daily limit RateLimitException
RG_WS_PUBLIC_EPIT_NF AFM not found AadeException
RG_WS_PUBLIC_WRONG_AFM Invalid AFM InvalidAfmException
RG_WS_PUBLIC_AFM_CALLED_BY_BLOCKED Caller AFM blocked AadeException
RG_WS_PUBLIC_SERVICE_NOT_ACTIVE Service unavailable AadeException

See ErrorCode.php for the complete list.

License

MIT License. See LICENSE for details.