Les emails de renouvellement d’abonnement ont un impact direct sur la rétention et le chiffre d’affaires. Des communications claires, envoyées au bon moment, réduisent le churn et les paiements échoués. Voici comment concevoir un flux de renouvellement efficace par email.
Séquence d’emails de renouvellement
Chronologie
const renewalSequence = [
{ daysBefore: 14, template: 'renewal-reminder-14d' },
{ daysBefore: 7, template: 'renewal-reminder-7d' },
{ daysBefore: 3, template: 'renewal-reminder-3d' },
{ daysBefore: 0, template: 'renewal-processed' },
{ daysAfter: 1, template: 'renewal-failed', condition: 'payment_failed' }
];
Email de rappel
interface RenewalReminder {
user: User;
subscription: {
plan: string;
amount: number;
currency: string;
renewsAt: Date;
paymentMethod: string;
};
}
await sendEmail({
to: user.email,
subject: `Your ${subscription.plan} plan renews in ${daysUntil} days`,
template: 'renewal-reminder',
data: {
user,
subscription,
updatePaymentUrl: `${baseUrl}/billing/payment-method`,
changePlanUrl: `${baseUrl}/billing/plans`,
cancelUrl: `${baseUrl}/billing/cancel`
}
});
Confirmation de renouvellement
await sendEmail({
to: user.email,
subject: `Your ${subscription.plan} plan has renewed`,
template: 'renewal-confirmation',
data: {
user,
subscription,
invoice: {
id: invoice.id,
amount: invoice.amount,
pdfUrl: invoice.pdfUrl
},
nextRenewal: subscription.nextRenewalDate,
usageSummary: await getUsageSummary(user.id)
}
});
Récupération en cas d’échec de paiement
Séquence de dunning
const dunningSequence = [
{
attempt: 1,
delay: 0,
template: 'payment-failed-1',
subject: 'Payment failed - please update your card'
},
{
attempt: 2,
delay: 3, // days
template: 'payment-failed-2',
subject: 'Second attempt failed - action required'
},
{
attempt: 3,
delay: 7,
template: 'payment-failed-3',
subject: 'Final notice - your account will be suspended'
},
{
attempt: 4,
delay: 10,
template: 'account-suspended',
subject: 'Your account has been suspended'
}
];
Email d’échec de paiement
await sendEmail({
to: user.email,
subject: 'Payment failed - please update your card',
template: 'payment-failed',
data: {
user,
subscription,
failureReason: getReadableFailureReason(payment.failureCode),
retryDate: payment.nextRetryAt,
updateCardUrl: `${baseUrl}/billing/payment-method`,
gracePeriodEnds: subscription.gracePeriodEnds
},
priority: 'high'
});
function getReadableFailureReason(code: string): string {
const reasons = {
'card_declined': 'Your card was declined',
'insufficient_funds': 'Insufficient funds',
'expired_card': 'Your card has expired',
'incorrect_cvc': 'Incorrect security code',
'processing_error': 'Processing error - we\'ll retry'
};
return reasons[code] || 'Payment could not be processed';
}
Notifications de changement de plan
Confirmation de mise à niveau
await sendEmail({
to: user.email,
subject: `Welcome to ${newPlan.name}!`,
template: 'plan-upgraded',
data: {
user,
previousPlan: oldPlan.name,
newPlan: {
name: newPlan.name,
features: getNewFeatures(oldPlan, newPlan),
price: newPlan.price
},
prorated: {
credit: proratedCredit,
charged: proratedCharge
},
gettingStartedUrl: `${baseUrl}/getting-started/${newPlan.slug}`
}
});
Confirmation de passage à un plan inférieur
await sendEmail({
to: user.email,
subject: `Your plan change to ${newPlan.name}`,
template: 'plan-downgraded',
data: {
user,
currentPlan: oldPlan.name,
newPlan: newPlan.name,
effectiveDate: downgrade.effectiveDate,
lostFeatures: getLostFeatures(oldPlan, newPlan),
dataRetention: 'Your data will be preserved',
upgradeUrl: `${baseUrl}/billing/plans`
}
});
Flux d’annulation
Confirmation d’annulation
await sendEmail({
to: user.email,
subject: 'Your subscription has been cancelled',
template: 'subscription-cancelled',
data: {
user,
subscription: {
plan: subscription.plan,
endsAt: subscription.currentPeriodEnd,
// Access continues until period end
accessUntil: subscription.currentPeriodEnd
},
dataExport: {
available: true,
exportUrl: `${baseUrl}/settings/export`
},
feedback: {
url: `${baseUrl}/feedback/cancellation`,
incentive: 'Help us improve and get 1 month free if you return'
},
reactivateUrl: `${baseUrl}/billing/reactivate`
}
});
Reconquête après annulation
// Send 7 days before access ends
await sendEmail({
to: user.email,
subject: 'Your access ends in 7 days',
template: 'access-ending-soon',
data: {
user,
endsAt: subscription.currentPeriodEnd,
whatYouLose: [
`${usage.projectCount} projects`,
`${usage.teamMembers} team members`,
'All integrations'
],
specialOffer: {
discount: '30% off for 3 months',
code: 'COMEBACK30',
expiresAt: subscription.currentPeriodEnd
},
reactivateUrl: `${baseUrl}/billing/reactivate?offer=COMEBACK30`
}
});
Gestion du renouvellement annuel
Rappel de renouvellement annuel
// 30 days before annual renewal
await sendEmail({
to: user.email,
subject: 'Your annual subscription renews soon',
template: 'annual-renewal-reminder',
data: {
user,
subscription: {
plan: subscription.plan,
amount: subscription.annualPrice,
renewsAt: subscription.renewsAt,
savings: calculateAnnualSavings(subscription)
},
yearInReview: {
// Show value received
emailsSent: usage.totalEmails,
uptime: '99.99%',
supportTickets: usage.supportTickets
},
options: {
continueAnnual: 'Continue annual billing',
switchMonthly: 'Switch to monthly',
cancel: 'Cancel subscription'
},
manageUrl: `${baseUrl}/billing`
}
});
Bonnes pratiques
- —Rappelez tôt - Laissez aux utilisateurs le temps de mettre à jour leurs moyens de paiement
- —Soyez précis - Indiquez les montants et les dates exacts
- —Expliquez les échecs - Indiquez aux utilisateurs pourquoi le paiement a échoué
- —Proposez des corrections simples - Mise à jour du paiement en un clic
- —Montrez la valeur - Rappelez aux utilisateurs ce pour quoi ils paient
- —Périodes de grâce - Ne coupez pas l’accès immédiatement
- —Canaux multiples - Envisagez le SMS pour les paiements échoués
Les emails de renouvellement visent à réduire les frictions et à prévenir le churn involontaire. Facilitez la vie des utilisateurs pour qu’ils restent abonnés.