taxora/sdk-php

Official PHP SDK for the Taxora VAT API (sandbox & production).

Installs: 615

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/taxora/sdk-php

v1.3.0 2025-12-14 14:59 UTC

This package is auto-updated.

Last update: 2025-12-15 12:24:03 UTC


README

Taxora Logo

Taxora PHP SDK

Official PHP SDK for the Taxora VAT Validation API Validate EU VAT numbers, generate compliance certificates, and integrate VAT checks seamlessly into your systems — all with clean, modern PHP.

Build

🚀 Overview

The Taxora SDK provides an elegant, PSR-compliant interface to the Taxora API, supporting:

  • ✅ Secure API-Key and Bearer Token authentication
  • ✅ Single & multiple VAT validation with AI-based company matching
  • ✅ VAT state history and search endpoints
  • ✅ Certificate generation (PDF) and bulk/list exports (ZIP or PDF)
  • ✅ Full test coverage & PSR-18 compatible HTTP client
  • ✅ PHP 8.3, 8.4, and (soon) 8.5 ready

🔒 The SDK itself is free to use, but a Taxora API subscription is required. You can obtain your x-api-key from your Taxora account developer settings.

ðŸ§Ū Installation

Install via Composer:

composer require taxora/sdk-php

The package supports all PSR-18 clients (e.g. Guzzle, Symfony, Buzz) and PSR-17/PSR-7 factories.

Example dependencies for Guzzle:

composer require guzzlehttp/guzzle http-interop/http-factory-guzzle

⚙ïļ Quick Start

use Taxora\Sdk\TaxoraClientFactory;
use Taxora\Sdk\Enums\Environment;

$client = TaxoraClientFactory::create(
    apiKey: 'YOUR_X_API_KEY',
    environment: Environment::SANDBOX // or PRODUCTION
);

// 1ïļâƒĢ Authenticate
$client->auth()->login('user@example.com', 'superSecret');

// 2ïļâƒĢ Validate a VAT number
$vat = $client->vat()->validate('ATU12345678', 'Example GmbH');
echo $vat->state->value;        // valid / invalid
echo $vat->company_name; // Official company name
echo $vat->score;        // Overall confidence score (float)

foreach ($vat->breakdown ?? [] as $step) {
    echo $step->stepName.' gave '.$step->scoreContribution.PHP_EOL;
}

// 3ïļâƒĢ Access company info
$company = $client->company()->get();

// 4ïļâƒĢ Export certificates (returns a VatCertificateExport object)
$export = $client->vat()->certificatesBulkExport('2024-01-01', '2024-12-31');
$pdfZip = $client->vat()->downloadBulkExport($export->exportId);
file_put_contents('certificates.zip', $pdfZip);

vat()->validate() returns a VatResource object that includes the canonical VAT number, status, requested company name echo, and optional scoring data. The score reflects the overall confidence (higher is better), while breakdown provides an array of ScoreBreakdown objects describing every validation step, its score contribution, and any metadata (e.g. matched addresses or mismatched fields).

Need to plug in your own PSR-18 client or PSR-17 factories (e.g. to add logging or retries)? Call the constructor directly or pass them as optional overrides to the factory:

use GuzzleHttp\Client as GuzzleAdapter;
use Http\Factory\Guzzle\RequestFactory;
use Http\Factory\Guzzle\StreamFactory;
use Taxora\Sdk\TaxoraClientFactory;

$client = TaxoraClientFactory::create(
    apiKey: 'YOUR_X_API_KEY',
    http: new GuzzleAdapter(),
    requestFactory: new RequestFactory(),
    streamFactory: new StreamFactory()
);

ðŸ§Đ Architecture

The SDK follows clean separation of concerns:

TaxoraClient
 ├── auth()     → AuthEndpoint     (login, refresh)
 ├── company()  → CompanyEndpoint  (company info)
 └── vat()      → VatEndpoint      (validate, history, search, certificate)

Each endpoint handles:

  • Request signing with x-api-key
  • Bearer token refresh if expired or unauthorized
  • PSR-7 response parsing into DTOs

ðŸ“Ķ DTOs

Class Description
VatResource Represents a single VAT validation result (normalized VAT UID, state, score, breakdown, company data)
ScoreBreakdown Scoring fragment with validation step name, score contribution, and metadata context for the decision
VatCollection Iterable list of VatResource objects
Token Auth token with expiry & type

Example:

$dto = $client->vat()->validate('ATU12345678');
print_r($dto->toArray());

🔄 Authentication Flow

  1. Login

    $client->auth()->login('email', 'password', device: 'my-server-01');
    // Passing device is optional; omitted value falls back to a generated host-based identifier.

    Need to authenticate with a technical client_id instead of an email?

    $client->auth()->loginWithClientId('client_abc123', 'client-secret', device: 'integration-box');

    Advanced: you can still pass loginIdentifier: LoginIdentifier::CLIENT_ID into login() if you prefer an explicit enum instead of the helper.

    → Stores and returns a Token DTO (valid for ~3600 seconds).

  2. Auto-refresh The client automatically refreshes the token on 401 responses.

  3. Manual refresh (optional)

    $client->auth()->refresh();
  4. Token storage By default, tokens are stored in memory. You can provide a PSR-16 cache adapter for persistence:

    use Symfony\Component\Cache\Adapter\FilesystemAdapter;
    use Symfony\Component\Cache\Psr16Cache;
    use Taxora\Sdk\Http\Psr16TokenStorage;
    
    $cache = new Psr16Cache(new FilesystemAdapter());
    $storage = new Psr16TokenStorage($cache);
    $client = new TaxoraClient($http, $reqF, $strF, 'YOUR_KEY', $storage);

ðŸĪŠ Testing

Run the test suite locally:

composer test

CI runs on PHP 8.3, 8.4, and (soon) 8.5, verifying:

  • PHPUnit 12
  • Psalm static analysis
  • Code style checks

🗟ïļ Environments

Environment Base URL
Sandbox https://sandbox.taxora.io/v1
Production https://api.taxora.io/v1

Need sandbox sample data? Known VAT UIDs with deterministic responses live in tests/Fixtures/SandboxVatFixtures.php.

Switch easily via the constructor:

$client = new TaxoraClient(..., environment: Environment::PRODUCTION);

⚠ïļ Deprecations

So fresh there aren't even any deprecated features yet. Check back in a few months when we're on v47 and have made some regrettable decisions. 🎉

🊊 License

Licensed under the MIT License ÂĐ 2025 theconcept technologies. The SDK is open-source, but API usage requires a valid Taxora subscription.

ðŸĪ Contributing

Contributions and pull requests are welcome!

  • Follow PSR-12 coding style (composer fix).
  • Run composer test before submitting a PR.
  • Ensure new endpoints include DTOs + tests.

💎 Support

Need help or enterprise support? 📧 support@taxora.io 🌐 https://taxora.io