Los correos de facturas y recibos cumplen funciones legales, contables y de atención al cliente. Así es como diseñarlos eficazmente.
Recibo vs factura
- —Recibo: confirma el pago recibido
- —Factura: solicita el pago (puede estar prepagada)
Ambos necesitan información similar, pero cumplen objetivos distintos.
Elementos esenciales
Correo 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)
}
]
});
Correo de factura
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)
}
]
});
Recordatorios de pago
Próxima fecha de vencimiento
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
}
});
}
Mejores prácticas de formato
Visualización de moneda
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)
Tabla de partidas
<table>
<thead>
<tr>
<th>Description</th>
<th>Qty</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{{#each items}}
<tr>
<td>{{this.description}}</td>
<td>{{this.quantity}}</td>
<td>{{formatMoney this.unitPrice}}</td>
<td>{{formatMoney this.total}}</td>
</tr>
{{/each}}
</tbody>
<tfoot>
<tr>
<td colspan="3">Subtotal</td>
<td>{{formatMoney totals.subtotal}}</td>
</tr>
<tr>
<td colspan="3">Tax</td>
<td>{{formatMoney totals.tax}}</td>
</tr>
<tr>
<td colspan="3"><strong>Total</strong></td>
<td><strong>{{formatMoney totals.total}}</strong></td>
</tr>
</tfoot>
</table>
Requisitos legales
Elementos obligatorios
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;
}
Mejores prácticas
- —Adjunta el PDF - Los clientes necesitan registros imprimibles
- —Totales claros - Desglosa subtotal, impuestos, descuentos
- —Información de pago - Muestra cómo pagaron o cómo pagar
- —Detalles del negocio - Nombre legal, dirección, ID fiscal
- —Identificadores únicos - Números de factura/recibo para referencia
- —Adaptado a móviles - Tablas que funcionen en pantallas pequeñas
Los correos de facturas y recibos son documentos legales. Si los haces bien, reducirás las preguntas contables y generarás confianza.