Mehrsprachige E-Mails aus Stripe-Webhooks

Die globale Skalierung eines SaaS birgt versteckte Fallen. Wir haben eine in unseren Stripe-Webhooks entdeckt.

Unser System versendete Kaufbestätigungen, Verlängerungen und Fehlermeldungen auf Japanisch an englischsprachige Nutzer. Dieser Bug bestand monatelang, weil er unauffällig blieb.

Wir haben das Problem gelöst, indem wir die Sprache aus der Währung ableiten.

Wir haben uns drei Design-Optionen angesehen:

  • Option A: Die Sprache in der Datenbank speichern. Dies erfordert Migrationen und Backfills für bestehende Nutzer.
  • Option B: Daten über die Stripe-API abrufen. Dies führt zu zusätzlichen API-Aufrufen, und viele Kunden legen keine bevorzugte Sprache (Locale) fest.
  • Option C: Die Währung im Webhook-Payload verwenden. Dies ist kostenlos, erfordert keine Datenbankänderungen und funktioniert sofort auch für bestehende Nutzer.

Wir haben uns für Option C entschieden. Die Währung ist zum Zeitpunkt des Kaufs ein eindeutiges Signal. Wenn ein Nutzer in USD zahlt, erhält er Englisch. Wenn er in JPY zahlt, erhält er Japanisch.

Die Logik ist einfach:

function lang_from_currency(string $currency): string {
    $en_currencies = ['usd'];
    return in_array(strtolower($currency), $en_currencies, true) ? 'en' : 'ja';
}

Dies funktioniert für alle vier wichtigen Stripe-Events:

  • checkout.session.completed
  • invoice.payment_succeeded
  • invoice.payment_failed
  • customer.subscription.updated

Wir haben zudem eine technische Falle bei PHP entdeckt.

Die Verwendung von mb_language('Japanese') kodiert Betreffzeilen in ISO-2022-JP. Wenn Sie mit dieser Einstellung eine englische Betreffzeile senden, erkennen Gmail und Outlook eine ungewöhnliche Kodierung. Dies erhöht Ihren Spam-Score.

Die Lösung besteht darin, die Kodierung basierend auf der Sprache zu wechseln:

mb_language($lang === 'en' ? 'uni' : 'Japanese');

Die Verwendung von 'uni' nutzt UTF-8 Base64. So landen Ihre E-Mails nicht im Spam-Ordner.

Drei Lehren aus diesem Fix:

  • Nutzen Sie den Event-Payload. Wenn die Daten bereits im Webhook enthalten sind, greifen Sie nicht auf Ihre Datenbank zu. Das reduziert Risiko und Wartungsaufwand.
  • Achten Sie auf die Kodierung. Wenn Sie mehrere Sprachen unterstützen, stellen Sie sicher, dass die Kodierung der Betreffzeile mit dem Inhalt übereinstimmt, um Spam-Filter zu vermeiden.
  • Überprüfen Sie hartcodierte Werte. Wenn Sie international expandieren, prüfen Sie, ob Ihre Benachrichtigungsfunktionen fest eingestellte Spracheinstellungen haben.

Ein zustandsloses (stateless) Design macht Ihr System wartungsfreundlicher und weniger fehleranfällig.

Quelle: https://dev.to/susumun/multilingual-emails-from-a-stripe-webhook-inferring-language-from-currency-i99