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
Installation
Section titled “Installation”composer require b2brouter/b2brouter-phpQuick start
Section titled “Quick start”<?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";Configuration
Section titled “Configuration”$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.
Identifying your application
Section titled “Identifying your application”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 ],]);Invoices
Section titled “Invoices”Create
Section titled “Create”$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,]);Retrieve, update, delete
Section titled “Retrieve, update, delete”$invoice = $client->invoices->retrieve($invoiceId);
$invoice = $client->invoices->update($invoiceId, [ 'invoice' => ['extra_info' => 'Payment terms: 30 days net']]);
$client->invoices->delete($invoiceId);List with pagination
Section titled “List with pagination”$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";Download
Section titled “Download”$pdf = $client->invoices->downloadPdf($invoiceId);file_put_contents('invoice.pdf', $pdf);$xml = $client->invoices->downloadAs($invoiceId, 'xml.facturae.3.2.2');$xml = $client->invoices->downloadAs($invoiceId, 'xml.ubl.invoice.bis3');Send and acknowledge
Section titled “Send and acknowledge”$client->invoices->send($invoiceId);
$client->invoices->acknowledge($invoiceId, ['ack' => true]);Accounts and contacts
Section titled “Accounts and contacts”$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);$contacts = $client->contacts->all($accountId, ['limit' => 25]);$contact = $client->contacts->create($accountId, ['contact' => [/* ... */]]);$contact = $client->contacts->update($contactId, ['contact' => [/* ... */]]);$client->contacts->delete($contactId);Tax reports
Section titled “Tax reports”Tax reports are generated automatically when you send invoices, provided you have configured TaxReportSettings for the account. See Tax Report Settings for setup instructions.
Configure settings
Section titled “Configure settings”$client->taxReportSettings->create($accountId, [ 'tax_report_setting' => [ 'code' => 'verifactu', 'start_date' => '2025-01-01', 'auto_generate' => true, 'auto_send' => true, ]]);Retrieve and download
Section titled “Retrieve and download”$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);Correction and annullation
Section titled “Correction and annullation”$client->taxReports->update($taxReportId, [ 'tax_report' => ['tax_inclusive_amount' => 133.1, /* ... */]]);$client->taxReports->delete($taxReportId);States
Section titled “States”| State | Meaning |
|---|---|
processing | Chaining and submission in progress |
registered | Accepted by the tax authority |
registered_with_errors | Submitted with warnings |
error | Submission failed |
annulled | Cancelled |
Error handling
Section titled “Error handling”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.