✅ Estrutura base implementada:
- Interface de providers
- Classe abstrata base
- Provider ABRASF v2 (genérico)
- Provider específico Joinville
- Registry para carregar providers
- Arquivo de configuração de municípios
- Exemplo funcional
src/Contracts/
├── NFSeProviderInterface.php # Interface base (emitir, consultar, cancelar)
└── NFSeProviderConfigInterface.php # Interface estendida (config auxiliares)
src/Providers/NFSe/
├── AbstractNFSeProvider.php # ⭐ Classe base - IMPLEMENTE AQUI
├── AbrasfV2Provider.php # ⭐ Provider genérico ABRASF - IMPLEMENTE montarXmlRps()
└── JoinvilleProvider.php # Exemplo de provider específico
src/Support/
└── ProviderRegistry.php # Registry para carregar providers via config
config/
└── nfse-municipios.json # ⭐ ADICIONE NOVOS MUNICÍPIOS AQUI
scripts/
└── exemplo-providers-nfse.php # Exemplo completo de uso
Arquivo: src/Providers/NFSe/AbrasfV2Provider.php
protected function montarXmlRps(array $dados): string
{
// TODO: Implementar estrutura XML conforme ABRASF v2
// Referência: Manual ABRASF v2.02/2.03
$xml = new \DOMDocument('1.0', 'UTF-8');
$rps = $xml->createElement('Rps');
// ... montar estrutura completa
return $xml->saveXML();
}Arquivo: src/Providers/NFSe/AbstractNFSeProvider.php
public function emitir(array $dados): string
{
$this->validarDados($dados);
$xml = $this->montarXmlRps($dados);
// TODO: Adicionar aqui:
// 1. Assinar XML com certificado
// 2. Criar cliente SOAP
// 3. Enviar para webservice
// 4. Retornar XML de resposta
$soapClient = new \SoapClient($this->getWsdlUrl());
$resposta = $soapClient->GerarNfse(['xmlEnvio' => $xml]);
return $resposta;
}Arquivo: src/Providers/NFSe/AbrasfV2Provider.php
protected function processarResposta(string $xmlResposta): array
{
// TODO: Parser XML de resposta
// Extrair: número NFSe, código verificação, erros, etc.
$dom = new \DOMDocument();
$dom->loadXML($xmlResposta);
// Extrair dados...
return [
'sucesso' => true,
'numero_nfse' => '...',
'codigo_verificacao' => '...'
];
}// TODO: Integrar com CertificateManager
$certManager = CertificateManager::getInstance();
$xmlAssinado = $certManager->assinarXml($xml);Edite: config/nfse-municipios.json
{
"nome_municipio": {
"provider": "AbrasfV2Provider",
"codigo_municipio": "1234567",
"wsdl": "https://url-do-webservice",
"wsdl_homologacao": "https://url-homologacao",
"wsdl_producao": "https://url-producao",
"aliquota_format": "decimal",
"versao": "2.02",
"ambiente": "homologacao"
}
}- Crie novo provider:
# Copie JoinvilleProvider.php como template
cp src/Providers/NFSe/JoinvilleProvider.php \
src/Providers/NFSe/SeuMunicipioProvider.php- Edite o provider:
<?php
namespace freeline\FiscalCore\Providers\NFSe;
class SeuMunicipioProvider extends AbrasfV2Provider
{
// Sobrescreva apenas métodos que diferem
protected function montarXmlRps(array $dados): string
{
$xml = parent::montarXmlRps($dados);
// Adicionar campos específicos
return $xml;
}
}- Registre no config:
{
"seu_municipio": {
"provider": "SeuMunicipioProvider",
// ... resto da config
}
}use freeline\FiscalCore\Support\ProviderRegistry;
// Carregar provider
$registry = ProviderRegistry::getInstance();
$provider = $registry->get('curitiba');
// Emitir NFSe
$dados = [
'prestador' => [ /* ... */ ],
'tomador' => [ /* ... */ ],
'servico' => [ /* ... */ ],
'valor_servicos' => 1000.00
];
$xmlNFSe = $provider->emitir($dados);
// Consultar
$xmlConsulta = $provider->consultar('numero-nfse');
// Cancelar
$sucesso = $provider->cancelar('numero-nfse', 'Motivo do cancelamento');// TODO: Atualizar NFSeAdapter para usar ProviderRegistry
class NFSeAdapter {
public function emitir(string $municipio, array $dados): string
{
$registry = ProviderRegistry::getInstance();
$provider = $registry->get($municipio);
return $provider->emitir($dados);
}
}# Rodar exemplo completo
php scripts/exemplo-providers-nfse.php
# Rodar testes (quando implementar)
vendor/bin/phpunit tests/Providers/NFSeProviderTest.php- Manual ABRASF: Estrutura XML padrão NFSe
- Documentação municípios: Verifique particularidades de cada prefeitura
- NFePHP Sped-NFSe: Pode servir de referência (mas não depende dele)
- Implementar
montarXmlRps()emAbrasfV2Provider - Implementar
processarResposta()emAbrasfV2Provider - Adicionar cliente SOAP em
AbstractNFSeProvider::emitir() - Integrar assinatura digital com
CertificateManager - Implementar consulta e cancelamento
- Adicionar tratamento de erros
- Criar testes unitários
- Documentar DTOs de entrada/saída
- Adicionar mais municípios em
config/nfse-municipios.json - Integrar com
NFSeAdapterexistente
ProviderRegistry (singleton)
↓ carrega config de
nfse-municipios.json
↓ instancia
AbstractNFSeProvider (base)
↓ herdam
AbrasfV2Provider | JoinvilleProvider | OutrosProviders
↓ implementam
NFSeProviderConfigInterface
Um sistema onde você:
- Adiciona município em JSON (sem código)
- Se padrão ABRASF, reutiliza provider existente
- Se tem particularidades, cria provider específico herdando do ABRASF
- Zero duplicação de código
✨ Sistema está pronto para desenvolvimento! Comece por AbrasfV2Provider::montarXmlRps()