Biblioteca PHP independente de frameworks para construir faturas, calcular totais monetários com segurança, renderizar templates HTML e gerar documentos PDF através de motores substituíveis.
O projeto usa um core em PHP puro e bridges oficiais para Laravel, Symfony e Yii2, mantendo as regras de domínio fora dos frameworks.
Important
Este projeto gera documentos PDF de faturação, mas não substitui validação fiscal, certificação de software, comunicação com autoridades tributárias ou requisitos legais específicos de cada país.
- core PHP puro, sem Laravel, Symfony, Yii2, Carbon, Blade, Twig ou facades;
- package Composer unico com bridges opcionais;
- domínio tipado para fatura, linhas, entidades, moradas, percentagens e moeda;
- builders fluentes para
Invoice,InvoiceItemeParty; - cálculos monetários sem
floatcomo representação principal; - valores monetários em unidades mínimas, como cêntimos;
- quantidades fracionadas representadas em milésimos;
- descontos por linha e desconto global;
- impostos por linha, incluídos ou excluídos;
- múltiplas taxas por linha;
- retenções;
- validação básica de faturas antes da geração;
- templates PHP nativos
minimal,modernebranded; - tradução base em inglês e português de Portugal;
- formatação monetária simples e substituível;
- armazenamento local seguro contra path traversal básico;
- contrato
PdfEngineInterfacepara motores PDF; - engines opcionais para Dompdf, mPDF, TCPDF e Browsershot;
- preview HTML para testes e desenvolvimento;
- bridges oficiais para Laravel, Yii2 e Symfony;
- responses de download nos bridges;
- testes PHPUnit preparados para o core;
- documentação técnica em português.
Aplicações PHP / Laravel / Yii2 / Symfony
↓
Bridges e adaptadores
↓
kowts/pdf-invoices
↓
PHP 8.2+ e contratos independentes
O core não conhece os bridges. Os bridges integram containers, tradutores, filesystems, responses e configuração de cada framework.
Consulte Arquitetura para a organização completa.
O package publicavel e kowts/pdf-invoices. O core vive em src/ e as
integracoes opcionais vivem em src/Bridge/Laravel, src/Bridge/Yii2 e
src/Bridge/Symfony.
- PHP 8.2 ou superior;
- Composer 2;
- extensão
json; - um driver PDF opcional:
dompdf/dompdf,mpdf/mpdf,tecnickcom/tcpdfouspatie/browsershot.
Para desenvolvimento do package:
- PHPUnit 11;
- PHPStan;
- PHP-CS-Fixer;
- Rector.
Quando o package for publicado:
composer require kowts/pdf-invoicesPara usar Dompdf:
composer require dompdf/dompdfDrivers alternativos:
composer require mpdf/mpdf
composer require tecnickcom/tcpdf
composer require spatie/browsershotPara testar antes da publicação no Packagist, clone este repositorio e aponte a
aplicação consumidora para ele com um repositório path:
{
"repositories": [
{
"type": "path",
"url": "../pdf-invoices-php/.",
"options": {
"symlink": true
}
}
],
"require": {
"kowts/pdf-invoices": "^0.1"
}
}<?php
use PdfInvoices\Core\Builder\InvoiceBuilder;
use PdfInvoices\Core\Builder\ItemBuilder;
use PdfInvoices\Core\Builder\PartyBuilder;
use PdfInvoices\Core\InvoiceGenerator;
use PdfInvoices\Core\Storage\LocalStorage;
use PdfInvoices\Core\ValueObject\Money;
use PdfInvoices\Core\ValueObject\Percentage;
use PdfInvoices\Core\ValueObject\Quantity;
require __DIR__ . '/vendor/autoload.php';
$seller = PartyBuilder::create()
->name('Empresa Exemplo, Lda.')
->taxNumber('NIF 123456789')
->email('faturacao@example.test')
->build();
$buyer = PartyBuilder::create()
->name('Cliente Exemplo')
->taxNumber('NIF 987654321')
->email('cliente@example.test')
->build();
$invoice = InvoiceBuilder::create()
->seller($seller)
->buyer($buyer)
->number('FT 2026/001')
->currency('CVE')
->locale('pt_PT')
->addItem(
ItemBuilder::create()
->description('Serviços profissionais')
->unitPrice(Money::fromDecimal('1500.00', 'CVE'))
->quantity(Quantity::fromDecimal('2.5'))
->tax(Percentage::fromBasisPoints(1500))
->build()
)
->notes('Pagamento a 30 dias.')
->build();
$document = InvoiceGenerator::defaultHtmlPreview()
->generate($invoice, 'modern');
$document->store(
new LocalStorage(__DIR__ . '/build'),
'invoice-preview.html'
);O exemplo completo está em examples/plain-php/generate.php.
O core gera documentos através de PdfEngineInterface.
Para produção, instale um driver e injete a engine pretendida no
InvoiceGenerator. Exemplo com Dompdf:
use PdfInvoices\Core\Calculation\InvoiceCalculator;
use PdfInvoices\Core\Formatting\SimpleCurrencyFormatter;
use PdfInvoices\Core\InvoiceGenerator;
use PdfInvoices\Core\Localization\ArrayTranslator;
use PdfInvoices\Core\Pdf\DompdfEngine;
use PdfInvoices\Core\Template\FilesystemTemplateResolver;
use PdfInvoices\Core\Template\NativePhpTemplateRenderer;
use PdfInvoices\Core\Validation\DefaultInvoiceValidator;
$generator = new InvoiceGenerator(
new DompdfEngine(),
new NativePhpTemplateRenderer(FilesystemTemplateResolver::default()),
new InvoiceCalculator(),
ArrayTranslator::default(),
new SimpleCurrencyFormatter(),
new DefaultInvoiceValidator()
);
$pdf = $generator->generate($invoice, 'branded');
$pdf->save(__DIR__ . '/invoice.pdf');Drivers disponiveis:
| Driver | Package | Engine |
|---|---|---|
| Dompdf | dompdf/dompdf |
DompdfEngine |
| mPDF | mpdf/mpdf |
MpdfEngine |
| TCPDF | tecnickcom/tcpdf |
TcpdfEngine |
| Browsershot | spatie/browsershot + Puppeteer/Chromium |
BrowsershotEngine |
Recursos remotos e JavaScript ficam restritos por defeito nos drivers onde o package consegue aplicar essa politica. Ative-os apenas com uma politica de seguranca adequada.
Instale o bridge na aplicação Laravel:
composer require kowts/pdf-invoicesPublique a configuração:
php artisan vendor:publish --tag=pdf-invoices-configUse a API principal por injeção de dependências:
use PdfInvoices\Core\InvoiceGenerator;
final class InvoiceController
{
public function download(InvoiceGenerator $generator)
{
$document = $generator->generate($invoice, config('pdf-invoices.template'));
return response()->streamDownload(
fn () => print $document->contents(),
'invoice.pdf',
['Content-Type' => $document->mimeType()]
);
}
}A facade existe apenas como conveniência. O uso por container continua a ser a API recomendada.
Instale o bridge na aplicação Yii2:
composer require kowts/pdf-invoicesConfiguração mínima em config/web.php:
use PdfInvoices\Core\Bridge\Yii2\PdfInvoicesComponent;
return [
'components' => [
'pdfInvoices' => [
'class' => PdfInvoicesComponent::class,
'template' => 'modern',
'locale' => 'pt_PT',
],
],
];Depois use o componente:
$document = Yii::$app->pdfInvoices->generate($invoice);O bridge pode ser usado em aplicações web e console.
Instale o bridge na aplicação Symfony:
composer require kowts/pdf-invoicesConfiguração mínima:
pdf_invoices:
template: modernUse por injeção de dependências:
use PdfInvoices\Core\InvoiceGenerator;
use Symfony\Component\HttpFoundation\Response;
final readonly class InvoiceController
{
public function __construct(private InvoiceGenerator $generator)
{
}
public function __invoke(): Response
{
$document = $this->generator->generate($invoice);
return new Response($document->contents(), 200, [
'Content-Type' => $document->mimeType(),
]);
}
}O MVP usa Money com unidades mínimas inteiras. Exemplo: 10.24 EUR é
representado como 1024.
As percentagens são representadas em basis points. Exemplo: 1500 representa
15%.
As quantidades usam milésimos para suportar valores como 1.5 ou 2.375.
Consulte Regras financeiras para detalhes de subtotal, descontos, impostos, retenções, arredondamento e notas de crédito.
- escape de HTML nos templates oficiais;
- recursos remotos desativados por defeito;
- JavaScript desativado por defeito no Dompdf e no Browsershot;
- storage local com bloqueio básico contra path traversal;
- validação da fatura antes da renderização;
- sem logging automático de dados fiscais;
- templates personalizados devem ser tratados como código confiável.
Consulte Segurança.
composer validate --no-check-lock --strict
composer cs
composer analyse
composer test
composer rectorO CI executa a matriz em Linux e Windows para PHP 8.2, 8.3 e 8.4.
- Arquitetura
- Utilização
- Regras financeiras
- Segurança
- Compatibilidade
- Changelog
- Análise do repositório de referência
- Packagist
- Roadmap
- Security Policy
- Checklist de implementação
- ADR 0001 - Package unico
- ADR 0002 - Dinheiro
- Exemplos completos
O projeto está em fase beta e pronto para a primeira release 0.1.0. O core,
os templates, os exemplos e os bridges iniciais já existem, com CI em Linux e
Windows para PHP 8.2, 8.3 e 8.4.
Antes de declarar estabilidade 1.0, ainda faltam validações em aplicações
reais Laravel, Yii2 e Symfony, snapshots visuais/PDF e uma política mais
completa para assets externos.
- validar o package publicado no Packagist após cada release;
- adicionar snapshots HTML/PDF por template e por driver principal;
- testar os bridges em aplicações reais Laravel, Symfony e Yii2;
- adicionar allowlist de assets remotos por domínio/MIME/tamanho;
- preparar a próxima release beta
0.2.0com melhorias de templates.
MIT © 2026 Kowts.