E-mails multilingues à partir des webhooks Stripe
Développer un SaaS à l'échelle mondiale comporte des pièges cachés. Nous en avons trouvé un dans nos webhooks Stripe.
Notre système envoyait des confirmations d'achat, des renouvellements et des avis d'échec en japonais à des utilisateurs anglophones. Ce bug a persisté pendant des mois car il passait inaperçu.
Nous l'avons résolu en déduisant la langue à partir de la devise.
Nous avons examiné trois options de conception :
- Option A : Stocker la langue dans la base de données. Cela nécessite des migrations et des remplissages de données (backfills) pour les anciens utilisateurs.
- Option B : Récupérer l'information via l'API Stripe. Cela ajoute des appels API supplémentaires et de nombreux clients ne définissent pas de locale préférée.
- Option C : Utiliser la devise dans la charge utile du webhook. C'est gratuit, ne nécessite aucun changement de base de données et fonctionne immédiatement pour les utilisateurs existants.
Nous avons choisi l'Option C. La devise est un signal fixe au moment de l'achat. Si un utilisateur paie en USD, il reçoit de l'anglais. S'il paie en JPY, il reçoit du japonais.
La logique est simple :
function lang_from_currency(string $currency): string { $en_currencies = ['usd']; return in_array(strtolower($currency), $en_currencies, true) ? 'en' : 'ja'; }
Cela fonctionne pour les quatre principaux événements Stripe :
- checkout.session.completed
- invoice.payment_succeeded
- invoice.payment_failed
- customer.subscription.updated
Nous avons également découvert un piège technique avec PHP.
L'utilisation de mb_language('Japanese') encode les objets en ISO-2022-JP. Si vous envoyez un objet en anglais avec ce paramètre, Gmail et Outlook le perçoivent comme un encodage étrange. Cela augmente votre score de spam.
La solution consiste à changer l'encodage en fonction de la langue :
mb_language($lang === 'en' ? 'uni' : 'Japanese');
L'utilisation de 'uni' utilise l'UTF-8 Base64. Cela permet d'éviter que vos e-mails ne finissent dans le dossier spam.
Trois leçons à tirer de ce correctif :
- Utilisez la charge utile de l'événement. Si les données sont déjà présentes dans le webhook, ne touchez pas à votre base de données. Cela réduit les risques et la maintenance.
- Surveillez votre encodage. Si vous prenez en charge plusieurs langues, assurez-vous que l'encodage de l'objet correspond au contenu pour éviter les filtres anti-spam.
- Auditez les valeurs codées en dur. Lorsque vous vous développez à l'international, vérifiez si vos fonctions de notification contiennent des paramètres de langue codés en dur.
Une conception sans état rend votre système plus facile à maintenir et plus difficile à casser.
