potelo / nfse-ssa
萨尔瓦多-BA 电子服务发票(NFS-e)的发行
Requires
- robrichards/xmlseclibs: ^3.0
README
简介
NfseSsa 是一个 Laravel 包,提供了在萨尔瓦多 - BA 发行电子服务发票(NFS-e)的接口。
安装 Laravel 5.x
使用 composer 安装此包
composer require potelo/nfse-ssa
如果您不使用 自动发现,请将 ServiceProvider 添加到 config/app.php
Potelo\NfseSsa\NfseSsaServiceProvider::class,
生成证书文件
您应该已经收到了一个扩展名为 pfx 的证书,它用于生产环境和测试环境。我们需要将此文件转换为 pem 扩展名并提取公钥。为了提取两个密钥,我们将使用终端(Windows 中的 cmd)命令,并在请求时输入密码。
openssl pkcs12 -in Certificado.pfx -out priv.pem -nodes
openssl pkcs12 -in Certificado.pfx -clcerts -nokeys -out public.pem
请保存生成的两个文件,priv.pem 和 public.pem。
配置
使用 publish 命令将包的配置文件复制到本地环境
php artisan vendor:publish --provider="Potelo\NfseSsa\NfseSsaServiceProvider"
在 config 文件夹中会创建一个 nfse-ssa.php 文件,您需要编辑它并放入之前生成的两个文件的路径。
'homologacao' => env('NFSESSA_HOMOLOGACAO', true),
'certificado_privado_path' => storage_path('app/priv.pem'),
'certificado_publico_path' => storage_path('app/public.pem'),
在您的 env 文件中添加变量
NFSESSA_HOMOLOGACAO=true
只有当您准备上线时,才将其更改为 false。
在开发时,使用测试环境的 Web 控制面板释放登记和发票发行非常重要:[https://notahml.salvador.ba.gov.br/](https://notahml.salvador.ba.gov.br/)
请使用此面板来跟踪发票是否正确生成。在此面板上的登记需要批准,通过电话联系市政府可以激活登记。
常见问题解答:[https://nfse.sefaz.salvador.ba.gov.br/OnLine/Institucional/FaqTecnologia.aspx](https://nfse.sefaz.salvador.ba.gov.br/OnLine/Institucional/FaqTecnologia.aspx)
服务收据(RPS)的发行
要生成发票,我们需要向市政府的 API 发送一个 RPS,它将自动从 RPS 中生成一个发票。我们在 Controller 的方法中通过依赖注入实例化了 NfseSsa 对象,并通过 enviarLoteRps 方法发送了 RPS。
<?php namespace App\Http\Controllers; use Illuminate\Routing\Controller as BaseController; use Potelo\NfseSsa\NfseSsa; class Controller extends BaseController{ public function enviarRPS(NfseSsa $nfsa) { // ou $nfsa = app(NfseSsa::class); $result = $nfsa->enviarLoteRps([ 'numero_lote' => 1, 'id' => '001', 'cnpj' => '50453974000107', 'inscricao_municipal' => '51515151515', 'rps' => [ 'id' => 'rpsId001', 'identificacao' => [ 'numero' => 1, 'serie' => 'A', 'tipo' => 1 // 1 - RPS, 2 – Nota Fiscal Conjugada (Mista), 3 – Cupom ], 'data_emissao' => '2018-08-01T16:45:14', 'natureza_operacao' => 1, /* Código de natureza da operação 1 – Tributação no município 2 - Tributação fora do município 3 - Isenção 4 - Imune 5 –Exigibilidade suspensa por decisão judicial 6 – Exigibilidade */ 'regime_especial_tributacao' => 1, /* Código de identificação do regime especial de tributação 1 – Microempresa municipal 2 - Estimativa 3 – Sociedade de profissionais 4 – Cooperativa 5 - Microempresário Individual (MEI) 6 - Microempresário e Empresa de Pequeno Porte (ME EPP) */ 'optante_simples_nacional' => 1, // 1 - Sim, 2 - Não 'incentivador_cultural' => 2, // 1 - Sim, 2 - Não 'status' => 1, // 1 - Normal, 2 - Cancelado 'servico' => [ 'valores' => [ 'valor_servicos' => 340.26, 'valor_deducoes' => 0, 'valor_pis' => 0, 'valor_cofins' => 0, 'valor_ir' => 0, 'valor_csll' => 0, 'iss_retido' => 1, // 1 - Sim, 2 - Não 'valor_iss' => 6.81, 'valor_iss_retido' => 6.81, 'outras_retencoes' => 0, 'base_calculo' => 340.26, 'aliquota' => 0.02, 'valor_liquido_nfse' => 3345.45, 'desconto_incondicionado' => 0, 'desconto_condicionado' => 0, ], 'item_lista_servico' => 1001, 'codigo_cnae' => 6622300, 'discriminacao' => 'vendas de seguro', 'codigo_municipio' => 2927408, 'codigo_tributacao_municipio' => '0103001' ], 'prestador' => [ 'cnpj' => '50453974000107', 'inscricao_municipal' => '51515151515', ], 'tomador' => [ 'identificacao_tomador' => [ 'cpf_cnpj' => [ 'cnpj' => '48109110000899', // 'cpf' => null // OU CPF ], 'inscricao_municipal' => '51559500163', ], 'razao_social' => 'RAZAO SOCIAL DO CLIENTE S/A', 'endereco' => [ 'endereco' => 'R MANOEL DIAS DA SILVA', 'numero' => '1515', 'bairro' => 'PITUBA', 'codigo_municipio' => 2927408, 'uf' => 'BA', 'cep' => '41000000', ], 'contato' => [ 'telefone' => '71999999999', 'email' => 'email@gmail.com' ] ] ] ]); // Sucesso if ($result->getStatus()) { return $result->getData(); } return $result->getErrors(); } }
如果成功生成,则在 $result->getData() 方法中将获得协议号,它将用于其他查询。
成功返回示例
{
NumeroLote: "1",
DataRecebimento: "01/08/2018 17:38:35",
Protocolo: "41512"
}
错误返回示例
[
{
codigo: "E10",
mensagem: "RPS já informado. ",
correcao: "Para essa Inscrição Municipal/CNPJ já existe um RPS informado com o mesmo número, série e tipo."
}
]
注意:此包在每个批次中仅发送 1 个 RPS。
查询
查询已发送批次 RPS 的状态
通过 consultarSituacaoLoteRps 方法进行查询
public function consultarSituacaoLoteRps(NfseSsa $nfsa) { $result = $nfsa->consultarSituacaoLoteRps([ 'prestador' => [ 'cnpj' => '50453974000107', 'inscricao_municipal' => '51515151515' ], 'protocolo' => '41111' ]); // Sucesso if ($result->getStatus()) { return $result->getData(); } return $result->getErrors(); }
成功返回示例
{
NumeroLote: "1",
Situacao: "4" // 1 – Não Recebido, 2 – Não Processado, 3 – Processado com Erro, 4 – Processado com Sucesso
}
通过 RPS 查询发票
通过 consultarNfseRps 方法查询从 RPS 生成的发票
public function consultarNfseRps(NfseSsa $nfsa) { $result = $nfsa->consultarNfseRps([ 'prestador' => [ 'cnpj' => '50453974000107', 'inscricao_municipal' => '51515151515' ], 'identificacao_rps' => [ 'numero' => 1, 'serie' => 'A', 'tipo' => 1 ] ]); // Sucesso if ($result->getStatus()) { return $result->getData(); } return $result->getErrors(); }
查询发票
public function consultarNfse(NfseSsa $nfsa) { $result = $nfsa->consultarNfse([ 'prestador' => [ 'cnpj' => '50453974000107', 'inscricao_municipal' => '51515151515' ], 'numero_nfse' => 1, // opcional 'periodo_emissao' => [ 'data_inicial' => '2018-01-01', 'data_final' => '2018-08-01', ] ]); // Sucesso if ($result->getStatus()) { return $result->getData(); } return $result->getErrors(); }