Skip to main content

Descrição

Este webhook é acionado automaticamente sempre que uma nota fiscal eletrônica (NF-e) ou nota fiscal de consumidor eletrônica (NFC-e) for emitida e autorizada pela SEFAZ.

Quando é Acionado

  • Autorização de NF-e pela SEFAZ
  • Autorização de NFC-e pela SEFAZ
  • Emissão de NFS-e (Nota Fiscal de Serviço)
  • Cancelamento de nota fiscal
  • Carta de correção emitida

Estrutura da Notificação

{
  "evento": "envio_nota_fiscal",
  "data_hora": "20/05/2024 18:30:20",
  "notas": [
    {
      "id": 654321,
      "tipo": "nfe",
      "numero": "12345",
      "serie": "1",
      "data_emissao": "20/05/2024",
      "chave_acesso": "35240512345678901234550010000123451234567890",
      "numero_protocolo": "135240000123456",
      "data_autorizacao": "20/05/2024 18:29:45",
      "situacao": "autorizado",
      "xml_url": "https://cdn.tiny.com.br/nfe/xml/123456.xml",
      "danfe_url": "https://cdn.tiny.com.br/nfe/pdf/123456.pdf",
      "pedido_id": 789456,
      "pedido_numero": "PED-12345",
      "cliente": {
        "nome": "Cliente Exemplo Ltda",
        "cpf_cnpj": "12345678000190",
        "email": "contato@cliente.com.br"
      },
      "valor_total": 1599.90,
      "valor_produtos": 1450.00,
      "valor_frete": 49.90,
      "valor_desconto": 0.00,
      "valor_icms": 174.00,
      "valor_ipi": 0.00
    }
  ]
}

Campos da Notificação

CampoTipoDescrição
eventostringSempre “envio_nota_fiscal”
data_horastringData e hora do evento (dd/mm/yyyy hh:mm:ss)
notas[]arrayLista de notas fiscais emitidas
notas[].idintID da nota fiscal no Olist ERP
notas[].tipostring”nfe”, “nfce” ou “nfse”
notas[].numerostringNúmero da nota fiscal
notas[].seriestringSérie da nota fiscal
notas[].data_emissaostringData de emissão (dd/mm/yyyy)
notas[].chave_acessostringChave de acesso de 44 dígitos
notas[].numero_protocolostringNúmero do protocolo de autorização
notas[].data_autorizacaostringData/hora da autorização SEFAZ
notas[].situacaostring”autorizado”, “cancelado”, “denegado”
notas[].xml_urlstringURL do arquivo XML da NF-e
notas[].danfe_urlstringURL do PDF do DANFE
notas[].pedido_idintID do pedido de origem
notas[].pedido_numerostringNúmero do pedido de origem
notas[].cliente.nomestringNome do cliente
notas[].cliente.cpf_cnpjstringCPF ou CNPJ do cliente
notas[].cliente.emailstringE-mail do cliente
notas[].valor_totaldecimalValor total da nota
notas[].valor_produtosdecimalValor dos produtos
notas[].valor_fretedecimalValor do frete
notas[].valor_descontodecimalValor de desconto
notas[].valor_icmsdecimalValor do ICMS
notas[].valor_ipidecimalValor do IPI

Exemplo de Implementação

PHP

<?php
$json = file_get_contents('php://input');
$data = json_decode($json, true);

if ($data['evento'] === 'envio_nota_fiscal') {
    foreach ($data['notas'] as $nota) {
        // Salva nota no sistema
        salvarNotaFiscal([
            'id' => $nota['id'],
            'numero' => $nota['numero'],
            'serie' => $nota['serie'],
            'chave_acesso' => $nota['chave_acesso'],
            'situacao' => $nota['situacao']
        ]);

        // Baixa e armazena XML
        $xml_content = file_get_contents($nota['xml_url']);
        salvarArquivo("nfe_{$nota['numero']}.xml", $xml_content);

        // Baixa e armazena PDF
        $pdf_content = file_get_contents($nota['danfe_url']);
        salvarArquivo("danfe_{$nota['numero']}.pdf", $pdf_content);

        // Envia e-mail para o cliente com DANFE anexo
        if ($nota['situacao'] === 'autorizado') {
            enviarEmailComNFE(
                $nota['cliente']['email'],
                $nota['cliente']['nome'],
                $nota['numero'],
                $nota['danfe_url']
            );
        }

        // Atualiza ERP externo
        sincronizarERPExterno($nota);

        echo "Nota fiscal {$nota['numero']} processada\n";
    }

    http_response_code(200);
    echo json_encode(['status' => 'processado']);
}
?>

Python

from flask import Flask, request, jsonify
import requests
import os

app = Flask(__name__)

@app.route('/webhook/nfe', methods=['POST'])
def webhook_nfe():
    data = request.get_json()

    if data.get('evento') == 'envio_nota_fiscal':
        for nota in data.get('notas', []):
            # Salva no banco de dados
            salvar_nota_fiscal({
                'id': nota['id'],
                'numero': nota['numero'],
                'chave_acesso': nota['chave_acesso'],
                'situacao': nota['situacao'],
                'pedido_id': nota['pedido_id']
            })

            # Download do XML
            xml_response = requests.get(nota['xml_url'])
            salvar_arquivo(f"xml/nfe_{nota['numero']}.xml", xml_response.content)

            # Download do PDF
            pdf_response = requests.get(nota['danfe_url'])
            salvar_arquivo(f"pdf/danfe_{nota['numero']}.pdf", pdf_response.content)

            # Envia e-mail
            if nota['situacao'] == 'autorizado':
                enviar_email_nfe(
                    destinatario=nota['cliente']['email'],
                    numero=nota['numero'],
                    danfe_url=nota['danfe_url']
                )

            # Integra com contador
            enviar_para_contador(nota['xml_url'], nota['chave_acesso'])

        return jsonify({'status': 'processado'}), 200

    return jsonify({'status': 'erro'}), 400

Node.js

const express = require('express');
const axios = require('axios');
const fs = require('fs').promises;
const app = express();

app.use(express.json());

app.post('/webhook/nfe', async (req, res) => {
    const data = req.body;

    if (data.evento === 'envio_nota_fiscal') {
        for (const nota of data.notas) {
            // Salva nota no banco
            await salvarNotaFiscal({
                id: nota.id,
                numero: nota.numero,
                chaveAcesso: nota.chave_acesso,
                situacao: nota.situacao
            });

            // Download e armazenamento do XML
            const xmlResponse = await axios.get(nota.xml_url, { responseType: 'arraybuffer' });
            await fs.writeFile(`storage/xml/nfe_${nota.numero}.xml`, xmlResponse.data);

            // Download e armazenamento do PDF
            const pdfResponse = await axios.get(nota.danfe_url, { responseType: 'arraybuffer' });
            await fs.writeFile(`storage/pdf/danfe_${nota.numero}.pdf`, pdfResponse.data);

            // Envia e-mail se autorizado
            if (nota.situacao === 'autorizado') {
                await enviarEmailNFE({
                    email: nota.cliente.email,
                    nome: nota.cliente.nome,
                    numero: nota.numero,
                    danfeUrl: nota.danfe_url,
                    valorTotal: nota.valor_total
                });
            }

            // Notifica sistemas integrados
            await notificarSistemasIntegrados(nota);

            console.log(`NF-e ${nota.numero} processada com sucesso`);
        }

        res.status(200).json({ status: 'processado' });
    } else {
        res.status(400).json({ status: 'erro' });
    }
});

app.listen(3000);

Configuração

Para ativar este webhook:
  1. Acesse Configurações > Integrações > Webhooks
  2. Clique em Novo Webhook
  3. Selecione o evento Envio de Nota Fiscal
  4. Informe a URL do seu endpoint
  5. Salve as configurações

Casos de Uso

  • E-mail automático: Envie NF-e automaticamente para clientes
  • Backup de XMLs: Armazene XMLs em servidores próprios ou cloud
  • Integração contábil: Envie notas para sistema do contador
  • Dashboard financeiro: Atualize dashboards com vendas faturadas
  • Compliance: Mantenha histórico completo de notas emitidas
  • Integração com ERP: Sincronize com sistemas de gestão externos

Boas Práticas

  • Armazene XMLs: Guarde os XMLs por no mínimo 5 anos (obrigação fiscal)
  • Backup redundante: Mantenha cópias em múltiplos locais
  • Validação de chave: Valide o formato da chave de acesso (44 dígitos)
  • E-mail profissional: Use templates bem formatados para envio ao cliente
  • Consulta SEFAZ: Implemente consulta periódica do status na SEFAZ
  • Tratamento de erros: Prepare-se para notas denegadas ou rejeitadas

Situações Possíveis

SituaçãoDescriçãoAção Recomendada
autorizadoNF-e autorizada pela SEFAZEnviar ao cliente
canceladoNF-e canceladaNotificar cliente
denegadoNF-e denegada pela SEFAZRevisar dados e reemitir
rejeitadoNF-e rejeitada por erroCorrigir e reenviar

Observações

  • O XML e PDF ficam disponíveis por 90 dias nas URLs fornecidas
  • Após 90 dias, utilize a API para obter novamente os arquivos
  • A chave de acesso é única e permite consulta na SEFAZ
  • Notas canceladas também geram webhook com situação “cancelado”
  • Para NFC-e, o campo danfe_url aponta para o DANFCE
  • NFS-e tem estrutura similar mas sem chave de acesso