Skip to content
Log in

SDKs

The B2Brouter PHP SDK lets you integrate electronic invoicing and tax reporting into your PHP application without dealing with raw HTTP requests.

  • Zero dependencies — PHP 7.4+ with standard extensions (cURL, JSON, mbstring)
  • Automatic retries — network failures handled with exponential backoff
  • Pagination support — Iterator and Countable for large result sets
  • Full tax report support — Verifactu, TicketBAI, SDI, KSeF, ZATCA, and more
Terminal window
composer require b2brouter/b2brouter-php
<?php
require_once 'vendor/autoload.php';
use B2BRouter\B2BRouterClient;
$client = new B2BRouterClient('your-api-key');
$accountId = 'your-account-id';
$invoice = $client->invoices->create($accountId, [
'invoice' => [
'number' => 'INV-2025-001',
'date' => '2025-01-15',
'due_date' => '2025-02-15',
'currency' => 'EUR',
'contact' => [
'name' => 'Acme Corporation',
'tin_value' => 'ESB12345678',
'country' => 'ES',
'email' => 'billing@acme.com',
],
'invoice_lines_attributes' => [
[
'description' => 'Professional Services',
'quantity' => 10,
'price' => 100.00,
'taxes_attributes' => [
['name' => 'IVA', 'category' => 'S', 'percent' => 21.0]
]
]
]
]
]);
echo "Invoice created: {$invoice['id']}\n";
$client = new B2BRouterClient('your-api-key', [
// 'api_base' => 'https://api.b2brouter.net', // Sandbox & Production (default)
// 'api_base' => 'https://api-staging.b2brouter.net', // Staging
'api_version' => '2026-04-20',
'timeout' => 80,
'max_retries' => 3,
]);

The SDK defaults to https://api.b2brouter.net. Use a test_ key for sandbox or a production key for production. Set api_base to https://api-staging.b2brouter.net only if you need the staging environment.

Integrators and plugins can append their identity to the User-Agent header:

$client = new B2BRouterClient('your-api-key', [
'app_info' => [
'name' => 'MyApp', // required
'version' => '1.0.0', // optional
'url' => 'https://myapp.com', // optional
],
]);
$invoice = $client->invoices->create($accountId, [
'invoice' => [
'number' => 'INV-2025-001',
'date' => '2025-01-15',
'currency' => 'EUR',
'contact' => [
'name' => 'Customer Name',
'tin_value' => 'ESB12345678',
'country' => 'ES',
],
'invoice_lines_attributes' => [
[
'description' => 'Service',
'quantity' => 1,
'price' => 1000.00,
'taxes_attributes' => [
['name' => 'IVA', 'category' => 'S', 'percent' => 21.0]
]
]
]
],
'send_after_import' => false,
]);
$invoice = $client->invoices->retrieve($invoiceId);
$invoice = $client->invoices->update($invoiceId, [
'invoice' => ['extra_info' => 'Payment terms: 30 days net']
]);
$client->invoices->delete($invoiceId);
$invoices = $client->invoices->all($accountId, [
'limit' => 25,
'offset' => 0,
'date_from' => '2025-01-01',
'date_to' => '2025-12-31',
]);
foreach ($invoices as $invoice) {
echo "{$invoice['number']}: €{$invoice['total']}\n";
}
echo "Total: {$invoices->getTotal()}, has more: " . ($invoices->hasMore() ? 'yes' : 'no') . "\n";
$pdf = $client->invoices->downloadPdf($invoiceId);
file_put_contents('invoice.pdf', $pdf);
$client->invoices->send($invoiceId);
$client->invoices->acknowledge($invoiceId, ['ack' => true]);
$accounts = $client->accounts->all(['limit' => 25]);
$account = $client->accounts->retrieve($accountId);
$account = $client->accounts->create(['account' => [/* ... */]]);
$account = $client->accounts->update($accountId, ['account' => [/* ... */]]);
$client->accounts->delete($accountId);
$client->accounts->unarchive($accountId);

Tax reports are generated automatically when you send invoices, provided you have configured TaxReportSettings for the account. See Tax Report Settings for setup instructions.

$client->taxReportSettings->create($accountId, [
'tax_report_setting' => [
'code' => 'verifactu',
'start_date' => '2025-01-01',
'auto_generate' => true,
'auto_send' => true,
]
]);
$taxReportId = $invoice['tax_report_ids'][0];
$taxReport = $client->taxReports->retrieve($taxReportId);
echo "State: {$taxReport['state']}\n";
if (!empty($taxReport['qr'])) {
file_put_contents('qr.png', base64_decode($taxReport['qr']));
}
$xml = $client->taxReports->download($taxReportId);
$client->taxReports->update($taxReportId, [
'tax_report' => ['tax_inclusive_amount' => 133.1, /* ... */]
]);
StateMeaning
processingChaining and submission in progress
registeredAccepted by the tax authority
registered_with_errorsSubmitted with warnings
errorSubmission failed
annulledCancelled
use B2BRouter\Exception\ApiErrorException;
use B2BRouter\Exception\AuthenticationException;
use B2BRouter\Exception\PermissionException;
use B2BRouter\Exception\ResourceNotFoundException;
use B2BRouter\Exception\InvalidRequestException;
use B2BRouter\Exception\ApiConnectionException;
try {
$invoice = $client->invoices->create($accountId, ['invoice' => [/* ... */]]);
} catch (AuthenticationException $e) {
// 401 — invalid API key
} catch (PermissionException $e) {
// 403 — insufficient permissions
} catch (ResourceNotFoundException $e) {
// 404
} catch (InvalidRequestException $e) {
// 400 / 422 — validation errors
$details = $e->getJsonBody();
} catch (ApiConnectionException $e) {
// network error
} catch (ApiErrorException $e) {
// any other API error
error_log("Request ID: {$e->getRequestId()}");
}

Always log the Request ID when reporting issues to support — it uniquely identifies the failed request.