Notificações de envio reduzem chamados de suporte e aumentam a confiança do cliente. Veja como projetar emails de envio eficazes ao longo de toda a jornada de entrega.
Sequência de emails de envio
Pedido enviado
interface ShippingNotification {
order: {
id: string;
items: OrderItem[];
};
shipping: {
carrier: string;
trackingNumber: string;
trackingUrl: string;
estimatedDelivery: Date;
shippedAt: Date;
};
customer: {
name: string;
email: string;
};
address: ShippingAddress;
}
await sendEmail({
to: customer.email,
subject: `Your order has shipped! 📦`,
template: 'order-shipped',
data: {
customer,
order,
shipping,
trackingUrl: shipping.trackingUrl,
estimatedDelivery: formatDate(shipping.estimatedDelivery)
}
});
Saiu para entrega
await sendEmail({
to: customer.email,
subject: 'Your order is out for delivery! 🚚',
template: 'out-for-delivery',
data: {
customer,
order,
estimatedWindow: '2:00 PM - 6:00 PM',
trackingUrl: shipping.trackingUrl
}
});
Confirmação de entrega
await sendEmail({
to: customer.email,
subject: 'Your order has been delivered ✓',
template: 'order-delivered',
data: {
customer,
order,
deliveredAt: shipping.deliveredAt,
deliveryPhoto: shipping.proofOfDelivery,
reviewUrl: `${baseUrl}/orders/${order.id}/review`,
supportUrl: `${baseUrl}/support`
}
});
Tratamento de exceções
Exceção de entrega
const exceptionTemplates = {
'address_issue': {
subject: 'Delivery issue - address update needed',
template: 'delivery-exception-address'
},
'recipient_unavailable': {
subject: 'Delivery attempted - no one home',
template: 'delivery-exception-unavailable'
},
'weather_delay': {
subject: 'Shipping delay due to weather',
template: 'delivery-exception-weather'
}
};
async function sendExceptionNotification(order: Order, exception: DeliveryException) {
const config = exceptionTemplates[exception.type];
await sendEmail({
to: order.customer.email,
subject: config.subject,
template: config.template,
data: {
order,
exception,
newEstimate: exception.newEstimatedDelivery,
actionRequired: exception.requiresAction,
updateUrl: `${baseUrl}/orders/${order.id}/update-address`
}
});
}
Entrega não realizada
await sendEmail({
to: customer.email,
subject: 'Delivery unsuccessful - action required',
template: 'delivery-failed',
data: {
customer,
order,
reason: exception.reason,
options: [
{ label: 'Reschedule delivery', url: rescheduleUrl },
{ label: 'Update address', url: updateAddressUrl },
{ label: 'Hold at facility', url: holdUrl }
],
deadline: 'Package will be returned after 5 days'
}
});
Pedidos com múltiplos pacotes
interface MultiPackageShipment {
order: Order;
packages: Array<{
packageNumber: number;
totalPackages: number;
trackingNumber: string;
items: OrderItem[];
status: string;
}>;
}
await sendEmail({
to: customer.email,
subject: `Package 1 of 3 shipped - Order #${order.number}`,
template: 'multi-package-shipped',
data: {
customer,
order,
package: packages[0],
remainingPackages: packages.slice(1),
allTrackingUrl: `${baseUrl}/orders/${order.id}/tracking`
}
});
Integração com transportadora
Tratamento de Webhook
async function handleCarrierWebhook(event: CarrierEvent) {
const order = await getOrderByTracking(event.trackingNumber);
const eventMap = {
'shipped': sendShippedNotification,
'in_transit': sendTransitUpdate,
'out_for_delivery': sendOutForDeliveryNotification,
'delivered': sendDeliveredNotification,
'exception': sendExceptionNotification
};
const handler = eventMap[event.status];
if (handler) {
await handler(order, event);
}
}
Boas práticas
- —Atualizações em tempo real - Envie assim que o status mudar
- —Links de tracking claros - Um clique para o tracking da transportadora
- —Defina expectativas - Janelas de entrega estimadas
- —Trate exceções - Comunicação proativa sobre atrasos
- —Inclua detalhes do pedido - Relembre o que está chegando
- —Compatível com mobile - A maioria confere o envio pelo celular
Bons emails de envio reduzem chamados de suporte de "cadê meu pedido?" e aumentam a confiança do cliente.