verifacturapi/php-sdk

Official framework-agnostic PHP SDK for Verifacturapi - Spain's AEAT Verifactu e-invoicing API

Maintainers

Package info

bitbucket.org/APPYWEB/verifacturapi-php-sdk

Homepage

Issues

pkg:composer/verifacturapi/php-sdk

Transparency log

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

v0.1.1 2026-07-30 20:23 UTC

This package is auto-updated.

Last update: 2026-07-30 20:23:10 UTC


README

Official, framework-agnostic PHP SDK for Verifacturapi — a wrapper around Spain's AEAT Verifactu e-invoicing system.

  • PHP 8.2+
  • Thin HTTP client over the /api/v1 REST API (does not re-implement AEAT)
  • Typed exceptions, multi-CIF, provisioning, webhook signature verification
  • Pluggable transport (Guzzle by default) — trivial to fake in tests

Installation

composer require verifacturapi/php-sdk

Quick start

use Verifacturapi\Client;

$client = Client::make('your-api-token');
// Custom host: Client::make('token', 'https://api.verifacturapi.com')

// Health check
$client->system()->ping();

// Create an invoice (see API docs for the full payload)
$result = $client->invoices()->create([
    'series' => 'F',
    'number' => '2026-000123',
    // ...issuer, lines, taxes...
]);

echo $result['uuid'], ' -> ', $result['status'];

Resources

AccessorCovers
$client->invoices()create, correct, cancel, rectify, list, find, status, listPresented, export
$client->catalogs()invoiceTypes, taxCodes, regimeCodes, operationQualifications, exemptions, validateNif
$client->cifs()multi-CIF: list, selector, create, find, update, setDefault, toggleActive, uploadCertificate, delete
$client->webhooks()list, create, find, update, delete, deliveries
$client->analytics()dashboard, monthlyComparison, successRate, responseTime, dailyTrend, statusDistribution
$client->provisioning()userExists, provisionUser (service token)
$client->system()ping, user, testConnection

Every method returns the decoded JSON body as an associative array. invoices()->export() returns the raw Response (e.g. CSV).

Licensing (M2M) endpoints are intentionally out of scope: this SDK targets the user API token surface only.

Multi-CIF certificate upload

$client->cifs()->uploadCertificate($cifId, '/path/cert.p12', 'cert-password');

Provisioning (host applications)

Provisioning requires a service token (abilities users:read, users:write). It lets a host app create Verifacturapi accounts for its own users transparently.

$service = Client::make('service-master-token');

if (! ($service->provisioning()->userExists('user@host.com')['exists'] ?? false)) {
    $tenant = $service->provisioning()->provisionUser('Acme SL', 'user@host.com', 'perfex_module');
    $tenantToken = $tenant['token']; // store it; shown once
}

Webhooks: verify the signature

Deliveries are signed with HMAC-SHA256 over "{timestamp}.{rawJsonBody}" and travel in the headers X-Webhook-Signature and X-Webhook-Timestamp.

use Verifacturapi\Webhooks\SignatureVerifier;

$verifier = new SignatureVerifier($webhookSecret);

$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';

if (! $verifier->verify($raw, $signature, $timestamp)) {
    http_response_code(400);
    exit;
}

$event = json_decode($raw, true);

Error handling

Non-2xx responses raise typed exceptions (all extend Verifacturapi\Exceptions\ApiException):

StatusException
401AuthenticationException
404NotFoundException
422ValidationException (->errors())
429RateLimitException (->retryAfter())
otherApiException (->status(), ->body())

Network failures raise TransportException.

use Verifacturapi\Exceptions\ValidationException;

try {
    $client->invoices()->create([]);
} catch (ValidationException $e) {
    foreach ($e->errors() as $field => $messages) {
        // ...
    }
}

Testing without network

Inject FakeTransport: queue responses, assert on the requests made.

use Verifacturapi\Client;
use Verifacturapi\Config;
use Verifacturapi\Http\FakeTransport;

$transport = (new FakeTransport)->pushJson(['uuid' => 'abc', 'status' => 'register']);
$client = new Client(new Config('token', 'https://api.test'), $transport);

$client->invoices()->create(['series' => 'F']);

$transport->lastRequest(); // ['method' => 'POST', 'uri' => 'verifactu/create', 'options' => [...]]

Live smoke test

A ready-to-run, read-only example lives in examples/smoke.php. It reads the token from the environment — never hardcode credentials:

VERIFACTURAPI_TOKEN=your-token \
VERIFACTURAPI_BASE_URL=https://api.verifacturapi.com \
php examples/smoke.php

Configuration

Config lets you tune the host, API prefix, timeouts and extra headers:

use Verifacturapi\Client;
use Verifacturapi\Config;

$client = new Client(new Config(
    token: 'your-token',
    baseUrl: 'https://api.verifacturapi.com',
    apiPrefix: '/api/v1',
    timeout: 30.0,
));

Development

composer install
composer quality   # pint (test) + phpstan + pest

License

MIT