Automatizando Geração de Faturas com Node.js — TongoRender Blog
Voltar ao Blog
tutorialsinvoicenodejsautomation

Automatizando Geração de Faturas com Node.js

Aprenda a construir um pipeline automatizado de geração de faturas com Node.js. Cobre integração com Stripe, processamento em lote, entrega por email e criação de PDF via API.

TongoRender Team20 de fevereiro de 202611 min

Criar faturas manualmente é tedioso e propenso a erros. Seja cobrando clientes mensalmente, processando pedidos de e-commerce ou gerenciando pagamentos de assinatura, automatizar seu pipeline de faturas economiza tempo, reduz erros e garante branding consistente. Neste tutorial, vamos construir um sistema completo de automação de faturas com Node.js que integra com o Stripe, gera PDFs profissionais via TongoRender e entrega por email.

Arquitetura do Sistema

Nosso pipeline automatizado tem quatro componentes:

  1. Fonte de dados — API do Stripe para dados de pagamento (adaptável a qualquer sistema de cobrança)
  2. Motor de templates — Template de fatura HTML/CSS com injeção dinâmica de dados
  3. Renderizador PDF — API do TongoRender para converter HTML em PDF profissional
  4. Entrega — Nodemailer para entrega por email com PDF anexado

Passo 1: Buscar Dados de Pagamento do Stripe

const Stripe = require('stripe');
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

async function getMonthlyInvoices(year, month) {
  const startTimestamp = Math.floor(new Date(year, month - 1, 1).getTime() / 1000);
  const endTimestamp = Math.floor(new Date(year, month, 0, 23, 59, 59).getTime() / 1000);

  const charges = await stripe.charges.list({
    created: { gte: startTimestamp, lte: endTimestamp },
    limit: 100,
    expand: ['data.customer'],
  });

  return charges.data
    .filter(charge => charge.status === 'succeeded')
    .map(charge => ({
      id: charge.id,
      amount: charge.amount / 100,
      currency: charge.currency.toUpperCase(),
      customerName: charge.customer?.name || 'Desconhecido',
      customerEmail: charge.customer?.email,
      description: charge.description || 'Cobrança de serviço',
      date: new Date(charge.created * 1000).toISOString().split('T')[0],
    }));
}

Passo 2: Design do Template de Fatura

function invoiceHTML(invoice, companyInfo) {
  return `
  <!DOCTYPE html>
  <html lang="pt-BR">
  <head>
    <style>
      body { font-family: 'Segoe UI', sans-serif; color: #333; padding: 40px; }
      .header { display: flex; justify-content: space-between; margin-bottom: 40px; }
      .company-name { font-size: 24px; font-weight: 700; color: #1a1a2e; }
      .invoice-title { font-size: 32px; color: #e63946; text-align: right; }
      table { width: 100%; border-collapse: collapse; margin: 30px 0; }
      th { background: #1a1a2e; color: white; padding: 12px 15px; text-align: left; }
      td { padding: 12px 15px; border-bottom: 1px solid #eee; }
      .total-row td { font-weight: 700; border-top: 2px solid #1a1a2e; }
    </style>
  </head>
  <body>
    <div class="header">
      <div>
        <div class="company-name">${companyInfo.name}</div>
        <div>${companyInfo.address}</div>
        <div>CNPJ: ${companyInfo.taxId}</div>
      </div>
      <div>
        <div class="invoice-title">FATURA</div>
        <div>Número: ${invoice.number}</div>
        <div>Data: ${invoice.date}</div>
        <div>Vencimento: ${invoice.dueDate}</div>
      </div>
    </div>

    <table>
      <thead>
        <tr><th>Descrição</th><th>Qtd</th><th>Preço Unit.</th><th>Valor</th></tr>
      </thead>
      <tbody>
        ${invoice.items.map(item => \`
          <tr>
            <td>${item.description}</td>
            <td>${item.quantity}</td>
            <td>R$ ${item.unitPrice.toFixed(2)}</td>
            <td>R$ ${(item.quantity * item.unitPrice).toFixed(2)}</td>
          </tr>
        \`).join('')}
        <tr class="total-row">
          <td colspan="3" style="text-align:right">Total</td>
          <td>R$ ${invoice.total.toFixed(2)}</td>
        </tr>
      </tbody>
    </table>
  </body>
  </html>`;
}

Passo 3: Gerar PDF e Enviar por Email

async function generateInvoicePDF(invoice, companyInfo) {
  const html = invoiceHTML(invoice, companyInfo);
  const response = await fetch('https://api.tongorender.io/v1/pdf', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': process.env.TONGORENDER_API_KEY,
    },
    body: JSON.stringify({ html, format: 'A4', printBackground: true }),
  });
  return Buffer.from(await response.arrayBuffer());
}

async function sendInvoiceEmail(to, invoice, pdfBuffer) {
  await transporter.sendMail({
    from: '"Faturamento" <faturamento@empresa.com>',
    to,
    subject: `Fatura #${invoice.number}`,
    text: `Segue em anexo a fatura #${invoice.number} no valor de R$ ${invoice.total.toFixed(2)}.`,
    attachments: [{ filename: `fatura-${invoice.number}.pdf`, content: pdfBuffer }],
  });
}

Boas Práticas

  • Idempotência — Rastreie quais faturas foram geradas para evitar enviar duplicatas ao tentar novamente.
  • Tratamento de erros — Envolva cada fatura em try-catch. Uma falha não deve parar o lote inteiro.
  • Rate limiting — Espaçe chamadas de API com um pequeno atraso para ficar dentro dos limites.
  • Armazenamento — Sempre salve uma cópia do PDF antes de enviá-lo por email.
  • Conformidade fiscal — Inclua todos os campos legalmente necessários: CNPJ, número sequencial, valores discriminados e impostos.

A renderização confiável de PDF do TongoRender garante que suas faturas fiquem profissionais sempre. Sem mais layouts quebrados ou fontes faltando.

Automatize suas faturas com o TongoRender — 100 renderizações gratuitas por mês, sem necessidade de cartão de crédito.

Compartilhe este artigoCompartilhar no Twitter