อีเมลหลายภาษาจาก Stripe Webhooks
การขยายธุรกิจ SaaS ไปทั่วโลกมีกับดักที่ซ่อนอยู่ เราพบกับดักหนึ่งใน Stripe webhooks ของเรา
ระบบของเราส่งการยืนยันการซื้อ การต่ออายุ และการแจ้งเตือนความล้มเหลวเป็นภาษาญี่ปุ่นให้กับผู้ใช้ที่พูดภาษาอังกฤษ บั๊กนี้คงอยู่มานานหลายเดือนเพราะมันไม่แสดงอาการให้เห็นชัดเจน
เราแก้ปัญหานี้ด้วยการอนุมานภาษาจากสกุลเงิน
เราพิจารณาทางเลือกในการออกแบบสามทาง:
- ทางเลือก A: เก็บภาษาไว้ในฐานข้อมูล วิธีนี้ต้องมีการทำ migrations และ backfills สำหรับผู้ใช้เก่า
- ทางเลือก B: ดึงข้อมูลจาก Stripe API วิธีนี้จะเพิ่มการเรียก API และลูกค้าหลายรายไม่ได้ตั้งค่า locale ที่ต้องการไว้
- ทางเลือก C: ใช้สกุลเงินใน webhook payload วิธีนี้ไม่มีค่าใช้จ่าย ไม่ต้องเปลี่ยนฐานข้อมูล และใช้งานกับผู้ใช้ปัจจุบันได้ทันที
เราเลือกทางเลือก C เพราะสกุลเงินเป็นสัญญาณที่แน่นอน ณ ขณะที่ทำการซื้อ หากผู้ใช้ชำระเงินเป็น USD พวกเขาจะได้รับภาษาอังกฤษ หากชำระเป็น JPY พวกเขาจะได้รับภาษาญี่ปุ่น
ตรรกะนั้นง่ายมาก:
function lang_from_currency(string $currency): string {
$en_currencies = ['usd'];
return in_array(strtolower($currency), $en_currencies, true) ? 'en' : 'ja';
}
วิธีนี้ใช้ได้กับ Stripe events หลักทั้งสี่รายการ:
- checkout.session.completed
- invoice.payment_succeeded
- invoice.payment_failed
- customer.subscription.updated
นอกจากนี้ เรายังพบกับดักทางเทคนิคใน PHP อีกด้วย
การใช้ mb_language('Japanese') จะเข้ารหัสหัวข้ออีเมลเป็น ISO-2022-JP หากคุณส่งหัวข้อภาษาอังกฤษด้วยการตั้งค่านี้ Gmail และ Outlook จะมองว่าเป็นการเข้ารหัสที่ผิดปกติ ซึ่งจะทำให้คะแนนสแปมของคุณสูงขึ้น
วิธีแก้ไขคือการสลับการเข้ารหัสตามภาษา:
mb_language($lang === 'en' ? 'uni' : 'Japanese');
การใช้ 'uni' จะใช้ UTF-8 Base64 ซึ่งช่วยให้คุณไม่ถูกส่งอีเมลไปยังโฟลเดอร์สแปม
สามบทเรียนจากการแก้ไขนี้:
- ใช้ event payload หากข้อมูลอยู่ใน webhook อยู่แล้ว ก็ไม่จำเป็นต้องแตะต้องฐานข้อมูลของคุณ ซึ่งจะช่วยลดความเสี่ยงและภาระในการดูแลรักษา
- ระวังเรื่องการเข้ารหัส หากคุณรองรับหลายภาษา ต้องแน่ใจว่าการเข้ารหัสหัวข้ออีเมลตรงกับเนื้อหาเพื่อหลีกเลี่ยงตัวกรองสแปม
- ตรวจสอบค่าที่ hardcoded เมื่อคุณขยายธุรกิจไปต่างประเทศ ให้ตรวจสอบว่าฟังก์ชันการแจ้งเตือนของคุณมีการตั้งค่าภาษาแบบ hardcoded ไว้หรือไม่
การออกแบบแบบ stateless ช่วยให้ระบบของคุณดูแลรักษาง่ายขึ้นและพังได้ยากขึ้น
