Multilingual Emails From Stripe Webhooks
Skalowanie SaaS na skalę globalną wiąże się z ukrytymi pułapkami. Jedną z nich znaleźliśmy w naszych webhookach Stripe.
Nasz system wysyłał potwierdzenia zakupu, odnowienia i powiadomienia o niepowodzeniach w języku japońskim do użytkowników anglojęzycznych. Ten błąd trwał miesiącami, ponieważ nie rzucał się w oczy.
Rozwiązaliśmy to, wnioskując o języku na podstawie waluty.
Rozważyliśmy trzy opcje projektowe:
- Opcja A: Przechowywanie języka w bazie danych. Wymaga to migracji i uzupełnienia danych (backfill) dla starych użytkowników.
- Opcja B: Pobieranie danych z API Stripe. Dodaje to dodatkowe wywołania API, a wielu klientów nie ustawia preferowanego regionu (locale).
- Opcja C: Wykorzystanie waluty w ładunku (payload) webhooka. Jest to rozwiązanie bezpłatne, nie wymaga zmian w bazie danych i działa natychmiast dla obecnych użytkowników.
Wybraliśmy Opcję C. Waluta jest stałym sygnałem w momencie zakupu. Jeśli użytkownik płaci w USD, otrzymuje język angielski. Jeśli płaci w JPY, otrzymuje język japoński.
Logika jest prosta:
function lang_from_currency(string $currency): string {
$en_currencies = ['usd'];
return in_array(strtolower($currency), $en_currencies, true) ? 'en' : 'ja';
}
To rozwiązanie działa dla wszystkich czterech głównych zdarzeń Stripe:
- checkout.session.completed
- invoice.payment_succeeded
- invoice.payment_failed
- customer.subscription.updated
Znaleźliśmy również techniczną pułapkę związaną z PHP.
Użycie mb_language('Japanese') koduje tematy wiadomości w formacie ISO-2022-JP. Jeśli wyślesz angielski temat przy tym ustawieniu, Gmail i Outlook uznają to za nietypowe kodowanie. Zwiększa to ryzyko trafienia do spamu.
Rozwiązaniem jest przełączanie kodowania w zależności od języka:
mb_language($lang === 'en' ? 'uni' : 'Japanese');
Użycie 'uni' wykorzystuje UTF-8 Base64. Dzięki temu Twoje e-maile nie trafią do folderu spam.
Trzy lekcje płynące z tego rozwiązania:
- Korzystaj z ładunku zdarzenia (event payload). Jeśli dane są już w webhooku, nie dotykaj bazy danych. Zmniejsza to ryzyko i nakłady na utrzymanie.
- Zwracaj uwagę na kodowanie. Jeśli obsługujesz wiele języków, upewnij się, że kodowanie tematu wiadomości jest zgodne z treścią, aby uniknąć filtrów antyspamowych.
- Audytuj wartości wpisane na sztywno (hardcoded). Wchodząc na rynek międzynarodowy, sprawdź, czy funkcje powiadomień nie mają na sztywno ustawionych języków.
Projekt bezstanowy (stateless) sprawia, że system jest łatwiejszy w utrzymaniu i trudniejszy do uszkodzenia.
