nfephp-org/sped-common
Biblioteca PHP com classes utilitárias compartilhadas para os projetos SPED da nfephp-org: NFe, CTe, MDFe, e-Financeira, eSfinge e eSocial. Reúne componentes comuns para facilitar integrações e reutilização de código.
Wrap core classes in Laravel’s DI container for reusable access:
// app/Providers/SpedServiceProvider.php
use NFePHP\Common\Validator;
use NFePHP\Common\Keys;
class SpedServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Validator::class, function ($app) {
return new Validator();
});
$this->app->singleton(Keys::class, function ($app) {
return new Keys();
});
}
public function boot()
{
$this->app->make(Validator::class)->setXsdPath(
storage_path('app/xsd/nfe_v4.00.xsd')
);
}
}
Create facades to simplify usage in controllers/views:
// app/Facades/Sped.php
use Illuminate\Support\Facades\Facade;
class Sped extends Facade
{
protected static function getFacadeAccessor()
{
return 'sped.validator';
}
}
Register in SpedServiceProvider:
$this->app->bind('sped.validator', function ($app) {
return $app->make(Validator::class);
});
Usage:
use App\Facades\Sped;
$isValid = Sped::isValid($xmlContent, 'nfe');
Generate keys or validate XML via CLI:
php artisan sped:generate-key --cnpj=12345678901234 --mod=55 --serie=1
php artisan sped:validate-xml --file=path/to/nfe.xml --schema=nfe
Command example:
// app/Console/Commands/GenerateNFeKey.php
use NFePHP\Common\Keys;
class GenerateNFeKey extends Command
{
protected $signature = 'sped:generate-key
{--cnpj= : CNPJ number}
{--mod= : Model number}
{--serie= : Series number}
{--nro= : Invoice number}';
public function handle(Keys $keys)
{
$key = $keys->build(
$this->option('cnpj'),
$this->option('mod'),
$this->option('serie'),
$this->option('nro')
);
$this->info("Generated key: {$key}");
}
}
Validate SPED XML in incoming requests:
// app/Http/Middleware/ValidateSpedXml.php
use NFePHP\Common\Validator;
class ValidateSpedXml
{
public function handle($request, Closure $next)
{
if ($request->isXml() && $request->hasHeader('x-sped-type')) {
$type = $request->header('x-sped-type');
$xsdPath = $this->getXsdPathForType($type);
if (!Validator::isValid($request->getContent(), $xsdPath)) {
return response()->json(['error' => 'Invalid SPED XML'], 400);
}
}
return $next($request);
}
protected function getXsdPathForType($type)
{
return match ($type) {
'nfe' => storage_path('app/xsd/nfe_v4.00.xsd'),
'cte' => storage_path('app/xsd/cte_v3.00.xsd'),
default => throw new \InvalidArgumentException("Unsupported SPED type"),
};
}
}
Offload validation to queues for large XML files:
// Dispatch validation job
ValidateSpedXmlJob::dispatch($xmlContent, 'nfe');
// Job class
class ValidateSpedXmlJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle(Validator $validator)
{
$isValid = $validator->isValid($this->xmlContent, $this->schema);
// Store result or notify user
}
}
Centralize certificate handling with Laravel’s filesystem:
// app/Services/CertificateService.php
use NFePHP\Common\Certificate\PrivateKey;
use Illuminate\Support\Facades\Storage;
class CertificateService
{
public function getPrivateKey($certificateId)
{
$path = storage_path("app/certificates/{$certificateId}.pem");
return new PrivateKey(file_get_contents($path));
}
public function signXml($xml, $certificateId)
{
$privateKey = $this->getPrivateKey($certificateId);
return $privateKey->sign($xml);
}
}
Load XSD schemas dynamically based on configuration:
// config/sped.php
return [
'schemas' => [
'nfe' => 'nfe_v4.00.xsd',
'cte' => 'cte_v3.00.xsd',
],
'paths' => [
'base' => storage_path('app/xsd'),
],
];
// Usage in Validator
$xsdPath = config("sped.paths.base") . '/' . config("sped.schemas.nfe");
Validator::isValid($xml, $xsdPath);
Use accessors/mutators for SPED-related fields:
// app/Models/NFe.php
use NFePHP\Common\Keys;
class NFe extends Model
{
public function getKeyAttribute()
{
return Keys::build(
$this->cnpj,
$this->mod,
$this->serie,
$this->nro
);
}
public function setXmlAttribute($value)
{
$this->attributes['xml'] = Strings::clearXml($value);
}
}
Transform SPED data for API responses:
// app/Http/Resources/NFeResource.php
use NFePHP\Common\Validator;
class NFeResource extends JsonResource
{
public function toArray($request)
{
return [
'key' => $this->key,
'is_valid' => Validator::isValid($this->xml, 'nfe'),
'data' => $this->xml,
];
}
}
Trigger events for SPED operations (e.g., validation success/failure):
// app/Providers/EventServiceProvider.php
protected $listen = [
'sped.validated' => [
SendSpedValidationNotification::class,
],
'sped.invalid' => [
LogSpedValidationError::class,
],
];
// Dispatch events in Validator
Validator::isValid($xml, $schema) ? event(new SpedValidated($xml)) : event(new SpedInvalid($xml));
Create factories for SPED XML generation:
// database/factories/NFeFactory.php
use NFePHP\Common\Keys;
$factory->define(NFe::class, function (Faker $faker) {
$cnpj = '58716523000119';
$mod = '55';
$serie = '1';
$nro = $faker->unique()->numberBetween(1, 1000);
return [
'cnpj' => $cnpj,
'mod' => $mod,
'serie' => $serie,
'nro' => $nro,
'key' => Keys::build($cnpj, $mod, $serie, $nro),
'xml' => file_get_contents(__DIR__ . '/stubs/nfe.xml'),
];
});
Cache validation results to avoid redundant checks:
// app/Services/SpedCacheService.php
use Illuminate\Support\Facades\Cache;
class SpedCacheService
{
public function getCachedValidation($xmlHash, $schema)
{
return Cache::remember(
"sped.validation.{$xmlHash}.{$schema}",
now()->addHours(1),
fn() => Validator::isValid($xml, $schema)
);
}
}
Support multiple tenants with different SPED configurations:
// app/Services/TenantSpedService.php
use NFePHP\Common\Validator;
class TenantSpedService
{
public function validateForTenant($tenant, $xml, $type)
{
$config = config("sped.tenants.{$tenant}");
$validator = new Validator();
$validator->setXsdPath($config['schemas'][$type]);
return $validator->isValid($xml);
}
}
Process SEFAZ webhook responses with SPED validation:
// app/Http/Controllers/WebhookController.php
use NFePHP\Common\Validator;
class WebhookController extends Controller
{
public function handleS
How can I help you explore Laravel packages today?