diff --git a/README.md b/README.md index 4df5ed8..a90326c 100644 --- a/README.md +++ b/README.md @@ -13,32 +13,14 @@ SPDX-License-Identifier: AGPL-3.0-or-later [![CI](https://github.com/LibreCodeCoop/nfse-php/actions/workflows/phpunit.yml/badge.svg)](https://github.com/LibreCodeCoop/nfse-php/actions/workflows/phpunit.yml) [![codecov](https://codecov.io/gh/LibreCodeCoop/nfse-php/branch/main/graph/badge.svg)](https://codecov.io/gh/LibreCodeCoop/nfse-php) ---- +## Scope -## Why nfse-php? - -Emitting NFS-e in Brazil involves XML signing with ICP-Brasil certificates, SOAP/REST calls to multiple municipal gateways, and safe credential management — all of which most accounting software gets wrong. - -**nfse-php** handles all of it correctly: - -- **XML signing** with PFX/PKCS#12 certificates (native PHP first, CLI repack fallback for OpenSSL legacy format) -- **Credential isolation** — PFX passwords are never stored in your database; they live in [OpenBao](https://openbao.org/) / HashiCorp Vault KV v2 -- **Pluggable secret store** — swap OpenBao for any `SecretStoreInterface` implementation -- **Tier-1 tests always run** via `donatj/mock-webserver` (no real cert required in CI) -- **Strict PHP 8.2+ types** throughout - ---- - -## Requirements - -| Dependency | Version | -|---|---| -| PHP | ^8.2 | -| ext-openssl | * | -| ext-dom | * | -| ext-soap | * | - ---- +- Emit NFS-e (`emit`) +- Query NFS-e (`query`) +- Cancel NFS-e (`cancel`) +- Retrieve DANFSE bytes (`getDanfse`) +- Sign DPS XML with PFX credentials +- Read secrets from OpenBao/Vault or an in-memory store ## Installation @@ -46,17 +28,24 @@ Emitting NFS-e in Brazil involves XML signing with ICP-Brasil certificates, SOAP composer require librecodeoop/nfse-php ``` ---- - ## Quick Start ```php +use LibreCodeCoop\NfsePHP\Config\CertConfig; +use LibreCodeCoop\NfsePHP\Config\EnvironmentConfig; +use LibreCodeCoop\NfsePHP\Dto\DpsData; use LibreCodeCoop\NfsePHP\Http\NfseClient; use LibreCodeCoop\NfsePHP\SecretStore\OpenBaoSecretStore; -use LibreCodeCoop\NfsePHP\Dto\DpsData; $store = new OpenBaoSecretStore(addr: 'http://localhost:8200', token: getenv('VAULT_TOKEN')); -$client = new NfseClient(secretStore: $store, sandboxMode: true); +$env = new EnvironmentConfig(sandboxMode: true); +$cert = new CertConfig( + cnpj: '11222333000181', + pfxPath: '/secure/path/certificate.pfx', + vaultPath: 'pfx/11222333000181', +); + +$client = new NfseClient(environment: $env, cert: $cert, secretStore: $store); $dps = new DpsData( cnpjPrestador: '11222333000181', // Example only: configure with your provider CNPJ @@ -68,13 +57,9 @@ $receipt = $client->emit($dps); echo $receipt->nfseNumber; // NFS-e number returned by the SEFIN gateway ``` ---- - ## Secret Storage with OpenBao -PFX passwords are **never** persisted in application databases. They are stored in OpenBao (or Vault) KV v2 under a path like `nfse/pfx/{cnpj}`. - -The CNPJ values below are **fictitious examples**. Configure your own values through your application settings/environment. +PFX passwords are stored in OpenBao (or Vault) KV v2, for example in `nfse/pfx/{cnpj}`. ```php use LibreCodeCoop\NfsePHP\SecretStore\OpenBaoSecretStore; @@ -93,48 +78,13 @@ $store->put('pfx/11222333000181', ['password' => 'secret']); $password = $store->get('pfx/11222333000181')['password']; ``` -For development/CI without OpenBao, use `NoOpSecretStore` which reads directly from constructor arguments and never touches any server. - ---- - -## Roadmap - -- [x] DPS issuance via SEFIN Nacional REST API -- [x] XML signing (PFX, ICP-Brasil) -- [x] OpenBao / Vault KV v2 secret store -- [x] Mock webserver for CI-friendly testing -- [ ] NFS-e query (GET /dps/{id}) -- [ ] NFS-e cancellation -- [ ] Webhook / event polling -- [ ] Municipal gateway adapters beyond Niterói - ---- - -## Commercial Support - -This library is the foundation of the [akaunting-nfse](https://github.com/LibreCodeCoop/akaunting-nfse) module for [Akaunting](https://akaunting.com/). - -Need SLA-backed support, custom municipal adapters, or managed hosting? -Contact us: **comercial@librecodecoop.org.br** - ---- +For development/CI without OpenBao, use `NoOpSecretStore` (in-memory only, no server calls). ## Contributing -We welcome issues and pull requests. Please read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a PR. - All commits must use [Conventional Commits](https://www.conventionalcommits.org/) and be signed off (`git commit -s`). ---- - ## Give us a star! If this library saves you hours of integration pain, please ⭐ the repository. It helps other developers discover the project and motivates the team to keep improving it. - ---- - -## License - -GNU Affero General Public License v3.0 or later — see [LICENSES/AGPL-3.0-or-later.txt](LICENSES/AGPL-3.0-or-later.txt). -© 2026 LibreCode Coop and contributors.