Les notifications d’expédition réduisent les tickets de support et renforcent la confiance des clients. Voici comment concevoir des emails d’expédition efficaces tout au long du parcours de livraison.
Séquence d’emails d’expédition
Commande expédiée
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)
}
});
En cours de livraison
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
}
});
Confirmation de livraison
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`
}
});
Gestion des exceptions
Exception de livraison
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`
}
});
}
Échec de livraison
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'
}
});
Commandes multi-colis
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`
}
});
Intégration avec le transporteur
Gestion des webhooks
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);
}
}
Bonnes pratiques
- —Mises à jour en temps réel - Envoyer dès que le statut change
- —Liens de suivi clairs - Un clic vers le suivi du transporteur
- —Fixer les attentes - Fenêtres de livraison estimées
- —Gérer les exceptions - Communication proactive en cas de retards
- —Inclure les détails de la commande - Rappeler ce qui arrive
- —Optimisé pour mobile - La plupart consultent le suivi sur leur téléphone
De bons emails d’expédition réduisent les tickets de support « où est ma commande ? » et renforcent la confiance des clients.