kowts/efatura-cv

Biblioteca PHP para validação e emissão de documentos fiscais electrónicos e-Fatura de Cabo Verde.

Maintainers

Package info

github.com/Kowts/efatura-cv-php

pkg:composer/kowts/efatura-cv

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.3.0 2026-07-11 21:51 UTC

This package is auto-updated.

Last update: 2026-07-21 16:55:43 UTC


README

e-Fatura CV para PHP

Testes Cobertura PHPStan PHP Licença Packagist Aikido package health Status

Biblioteca PHP independente de frameworks para validar documentos fiscais, gerar XML DFE v11, validar com os XSD oficiais, assinar com XAdES-BES, criar pacotes ZIP e comunicar com serviços e-Fatura de Cabo Verde.

Important

Este projecto não é oficial da DNRE. A utilização em produção exige homologação do software, credenciais válidas e testes nos ambientes oficiais.

Funcionalidades

  • nove tipos de documento: FTE, FRE, TVE, RCE, NCE, NDE, DTE, DVE e NLE;
  • geração, validação e interpretação de IUD;
  • validação de NIF, entidades, linhas, impostos e reconciliação de totais;
  • emissão online e em contingência;
  • geração de XML compacto DFE v11;
  • ciclo de eventos FDC e UDN, incluindo XML, ZIP e submissão;
  • validação com os XSD oficiais de 27 de Maio de 2024;
  • assinatura XAdES-BES com RSA-SHA256;
  • validação de certificados e correspondência da chave privada;
  • pacotes ZIP Deflate com nomes {IUD}.xml;
  • sequências e idempotência em memória ou transaccionais por PDO;
  • submissão por middleware e directamente à plataforma;
  • consultas fiscais, repetição segura e reconciliação através de PSR-18;
  • cálculos monetários com representação decimal exacta;
  • DFA em PDF com QR Code;
  • DTOs imutáveis e tipados, sem retirar a API por arrays;
  • integrações opcionais com Laravel, Symfony e Yii2;
  • CLI para inspeccionar IUDs e validar XML;
  • respostas JSON/XML normalizadas;
  • nenhuma dependência de Laravel, Symfony ou outro framework.

Fluxo de emissão

O fluxo completo, com decisões de contingência, validação, assinatura, submissão e reconciliação, está documentado em Arquitectura.

Requisitos

  • PHP 8.1 ou superior;
  • extensões curl, dom, json, libxml, openssl e zip.

Instalação

composer require kowts/efatura-cv

Para instalar directamente do ramo de desenvolvimento, pode declarar o repositório Git:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/Kowts/efatura-cv-php"
        }
    ],
    "require": {
        "kowts/efatura-cv": "dev-main"
    }
}

Utilização rápida

<?php

use Kowts\Efatura\Config\EfaturaConfig;
use Kowts\Efatura\Domain\DocumentType;
use Kowts\Efatura\Domain\Environment;
use Kowts\Efatura\Efatura;

$efatura = new Efatura(new EfaturaConfig(
    transmitterNif: '123456789',
    transmitterLed: '001',
    softwareCode: 'MEUSOFT',
    softwareName: 'Meu Software',
    softwareVersion: '1.0.0',
    middlewareBaseUrl: 'https://middleware.exemplo.cv',
    transmitterKey: getenv('EFATURA_TRANSMITTER_KEY') ?: null,
    defaultSerie: 'SER-F',
    emitter: [
        'taxId' => ['countryCode' => 'CV', 'value' => '123456789'],
        'name' => 'Empresa, Lda.',
        'address' => ['countryCode' => 'CV', 'addressDetail' => 'Praia'],
        'contacts' => ['email' => 'facturacao@exemplo.cv', 'telephone' => '2600000'],
    ],
    environment: Environment::Test
));

$invoice = $efatura->document()
    ->type(DocumentType::ElectronicInvoice)
    ->issueDate('2026-07-08')
    ->issueTime('10:30:00')
    ->receiver([
        'taxId' => ['countryCode' => 'CV', 'value' => '987654321'],
        'name' => 'Cliente',
    ])
    ->line([
        'quantity' => ['value' => 1, 'unitCode' => 'UN'],
        'price' => 1000,
        'priceExtension' => 1000,
        'netTotal' => 1000,
        'taxes' => [[
            'taxTypeCode' => 'IVA',
            'taxPercentage' => 15,
            'taxTotal' => 150,
        ]],
        'item' => [
            'description' => 'Serviço',
            'emitterIdentification' => 'SERV-1',
        ],
    ])
    ->totals([
        'priceExtensionTotalAmount' => 1000,
        'netTotalAmount' => 1000,
        'taxTotalAmount' => 150,
        'payableAmount' => 1150,
    ])
    ->validate();

$number = $efatura->nextDocumentNumber($invoice['issueDate'], $invoice['type']);
$iud = $efatura->buildIud($invoice['issueDate'], $invoice['type'], $number);
$xml = $efatura->buildDfeXml($iud, $invoice);

$xsd = $efatura->validateXml($xml);
if (!$xsd['valid']) {
    throw new RuntimeException(json_encode($xsd['errors'], JSON_THROW_ON_ERROR));
}

$signed = $efatura->signXml(
    $xml,
    file_get_contents('/segredos/certificado.pem'),
    file_get_contents('/segredos/chave-privada.pem'),
    getenv('EFATURA_KEY_PASSWORD') ?: null
);

$zip = $efatura->buildDfeZip([['iud' => $iud, 'xml' => $signed['xml']]]);
$result = $efatura->submitDfeZip($zip);

Integração com Yii2

Instale também o Yii2 na aplicação consumidora:

composer require yiisoft/yii2

Para arranque local, testes ou ambientes sem submissão fiscal real, pode registar o componente apenas com config:

use Kowts\Efatura\Bridge\Yii2\EfaturaComponent;

return [
    'components' => [
        'efatura' => [
            'class' => EfaturaComponent::class,
            'config' => [
                'transmitter_nif' => '100200300',
                'transmitter_led' => '001',
                'software_code' => 'MEUSOFT',
                'software_name' => 'Meu Software',
                'software_version' => '1.0.0',
                'environment' => 'TEST',
            ],
        ],
    ],
];

Warning

Em produção, configure o componente Yii2 através da propriedade factory, utilizando PdoSequenceStore e PdoSubmissionRegistry. O armazenamento em memória destina-se apenas a desenvolvimento e testes.

Consulte docs/yii2.md para a configuração completa.

Depois use a biblioteca sem duplicar regras fiscais:

use Kowts\Efatura\Domain\DocumentType;

$iud = Yii::$app->efatura->buildSequentialIud('2026-07-08', DocumentType::ElectronicInvoice);
$xml = Yii::$app->efatura->buildDfeXml($iud, $documento);

Em produção, construa o cliente com uma factory e stores persistentes:

use Kowts\Efatura\Bridge\Yii2\EfaturaComponent;
use Kowts\Efatura\Config\EfaturaConfig;
use Kowts\Efatura\Efatura;
use Kowts\Efatura\Infrastructure\Sequence\PdoSequenceStore;
use Kowts\Efatura\Infrastructure\Submission\PdoSubmissionRegistry;

return [
    'components' => [
        'efatura' => [
            'class' => EfaturaComponent::class,
            'config' => [
                // Mesma configuração fiscal do exemplo anterior.
            ],
            'factory' => static function (EfaturaComponent $component): Efatura {
                $pdo = Yii::$app->db->pdo;
                $prefix = Yii::$app->db->tablePrefix;

                return new Efatura(
                    EfaturaConfig::fromArray($component->config),
                    sequenceStore: new PdoSequenceStore($pdo, $prefix . 'efatura_sequences'),
                    submissionRegistry: new PdoSubmissionRegistry($pdo, $prefix . 'efatura_submissions'),
                );
            },
        ],
    ],
];

As tabelas de sequência e submissão devem ser criadas por migrações Yii2.

Sequências em produção

O armazenamento predefinido existe apenas em memória. Em produção, use uma base de dados para impedir números duplicados entre processos. A implementação PDO suporta SQLite, MySQL/MariaDB, PostgreSQL e SQL Server:

use Kowts\Efatura\Infrastructure\Sequence\PdoSequenceStore;

$pdo = new PDO('mysql:host=localhost;dbname=faturacao', 'utilizador', 'senha');
$sequences = new PdoSequenceStore($pdo);
$sequences->createTable(); // Execute uma vez, ou converta para uma migração.

$efatura = new Efatura($config, $sequences);

A sequência é independente por NIF transmissor, ano, LED e tipo documental. Guarde sempre o IUD, XML, ZIP e resposta de transporte. Uma falha de rede não autoriza a reutilização ou substituição automática do número fiscal.

Consulte Persistência PDO para detalhes de motores suportados, migrações, idempotência e limites conhecidos.

Segurança

  • nunca envie chaves, certificados, tokens ou credenciais para o navegador;
  • não guarde segredos no repositório;
  • valide o certificado antes da emissão;
  • use TLS e armazenamento cifrado;
  • registe respostas técnicas sem expor dados pessoais ou segredos;
  • fixe uma versão exacta do pacote em sistemas de produção.

Consulte Assinatura e certificados e Segurança.

Documentação

Estado do projecto

O pacote está em desenvolvimento activo. Os XSD oficiais estão incluídos, mas não foram publicados vectores oficiais para comparar byte a byte IUD, ZIP e assinaturas. Os testes internos não devem ser confundidos com certificação oficial.

Origem dos artefactos

Os XSD incluídos são os artefactos do sistema e-Fatura de Cabo Verde.

Licença

MIT © 2026 Kowts.