emailr_
Todos os artigos
usecase·8 min

E-mails de fatura e recibo: o que incluir

billingtransactionalreceipts

E-mails de fatura e recibo têm finalidade jurídica, contábil e de atendimento ao cliente. Veja como projetá-los de forma eficaz.

Recibo vs. fatura

  • Recibo: confirma o recebimento do pagamento
  • Fatura: solicita pagamento (pode ser pré-paga)

Ambos precisam de informações semelhantes, mas cumprem propósitos diferentes.

Elementos essenciais

E-mail de recibo

interface ReceiptEmail {
  customer: {
    name: string;
    email: string;
    billingAddress?: Address;
  };
  transaction: {
    id: string;
    date: Date;
    paymentMethod: string;
    last4?: string;
  };
  items: Array<{
    description: string;
    quantity: number;
    unitPrice: number;
    total: number;
  }>;
  totals: {
    subtotal: number;
    tax: number;
    discount?: number;
    total: number;
    currency: string;
  };
  business: {
    name: string;
    address: string;
    taxId?: string;
  };
}


await sendEmail({
  to: customer.email,
  subject: `Receipt for your purchase - $${totals.total}`,
  template: 'receipt',
  data: receipt,
  attachments: [
    {
      filename: `receipt-${transaction.id}.pdf`,
      content: await generateReceiptPDF(receipt)
    }
  ]
});

E-mail de fatura

interface InvoiceEmail {
  customer: {
    name: string;
    email: string;
    billingAddress: Address;
  };
  invoice: {
    number: string;
    issueDate: Date;
    dueDate: Date;
    status: 'draft' | 'sent' | 'paid' | 'overdue';
  };
  items: InvoiceItem[];
  totals: {
    subtotal: number;
    tax: number;
    total: number;
    currency: string;
    amountDue: number;
  };
  paymentOptions: PaymentOption[];
}

await sendEmail({
  to: customer.email,
  subject: `Invoice #${invoice.number} - $${totals.amountDue} due ${formatDate(invoice.dueDate)}`,
  template: 'invoice',
  data: invoiceData,
  attachments: [
    {
      filename: `invoice-${invoice.number}.pdf`,
      content: await generateInvoicePDF(invoiceData)
    }
  ]
});

Lembretes de pagamento

Vencimento próximo

const reminderSequence = [
  { daysBefore: 7, template: 'invoice-reminder-7d' },
  { daysBefore: 3, template: 'invoice-reminder-3d' },
  { daysBefore: 1, template: 'invoice-reminder-1d' },
  { daysAfter: 1, template: 'invoice-overdue-1d' },
  { daysAfter: 7, template: 'invoice-overdue-7d' }
];

async function sendInvoiceReminder(invoice: Invoice, reminder: Reminder) {
  await sendEmail({
    to: invoice.customer.email,
    subject: reminder.daysBefore 
      ? `Invoice #${invoice.number} due in ${reminder.daysBefore} days`
      : `Invoice #${invoice.number} is overdue`,
    template: reminder.template,
    data: {
      invoice,
      payNowUrl: `${baseUrl}/invoices/${invoice.id}/pay`,
      amountDue: invoice.amountDue
    }
  });
}

Boas práticas de formatação

Exibição de moeda

function formatMoney(amount: number, currency: string, locale: string): string {
  return new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency
  }).format(amount);
}

// $1,234.56 (en-US, USD)
// €1.234,56 (de-DE, EUR)
// ¥1,235 (ja-JP, JPY)

Tabela de itens

<table>
  <thead>
    <tr>
      <th>Description</th>
      <th>Qty</th>
      <th>Unit Price</th>
      <th>Total</th>
    </tr>
  </thead>
  <tbody>
    &#123;&#123;#each items&#125;&#125;
    <tr>
      <td>&#123;&#123;this.description&#125;&#125;</td>
      <td>&#123;&#123;this.quantity&#125;&#125;</td>
      <td>&#123;&#123;formatMoney this.unitPrice&#125;&#125;</td>
      <td>&#123;&#123;formatMoney this.total&#125;&#125;</td>
    </tr>
    &#123;&#123;/each&#125;&#125;
  </tbody>
  <tfoot>
    <tr>
      <td colspan="3">Subtotal</td>
      <td>&#123;&#123;formatMoney totals.subtotal&#125;&#125;</td>
    </tr>
    <tr>
      <td colspan="3">Tax</td>
      <td>&#123;&#123;formatMoney totals.tax&#125;&#125;</td>
    </tr>
    <tr>
      <td colspan="3"><strong>Total</strong></td>
      <td><strong>&#123;&#123;formatMoney totals.total&#125;&#125;</strong></td>
    </tr>
  </tfoot>
</table>

Requisitos legais

Elementos obrigatórios

const requiredReceiptElements = {
  business: ['name', 'address', 'taxId'],
  transaction: ['date', 'id', 'paymentMethod'],
  items: ['description', 'quantity', 'price'],
  totals: ['subtotal', 'tax', 'total']
};

// Validate before sending
function validateReceipt(receipt: ReceiptEmail): boolean {
  // Check all required fields present
  for (const [section, fields] of Object.entries(requiredReceiptElements)) {
    for (const field of fields) {
      if (!receipt[section]?.[field]) {
        throw new Error(`Missing required field: ${section}.${field}`);
      }
    }
  }
  return true;
}

Boas práticas

  1. Anexar PDF - os clientes precisam de registros imprimíveis
  2. Totais claros - detalhar subtotal, impostos e descontos
  3. Informações de pagamento - mostrar como pagaram ou como pagar
  4. Dados da empresa - razão social, endereço, ID fiscal
  5. Identificadores únicos - números de fatura/recibo para referência
  6. Compatível com mobile - tabelas que funcionem em telas pequenas

E-mails de fatura e recibo são documentos legais. Faça-os da forma correta e você reduzirá dúvidas de contabilidade e construirá confiança.

e_

Escrito pela equipe emailr

Construindo infraestrutura de email para desenvolvedores

Pronto para começar a enviar?

Obtenha sua chave API e envie seu primeiro email em menos de 5 minutos. Não é necessário cartão de crédito.