From 324ab5618c4506dfa07b9fcdf7efa7812595c3de Mon Sep 17 00:00:00 2001 From: Spinsirr Date: Sat, 18 Apr 2026 01:12:41 -0700 Subject: [PATCH] fix: force Stripe checkout/portal locale to English Stripe's `locale: "auto"` default combines browser `Accept-Language` with IP geolocation, and for Billing Portal the Portal configuration's default language in the Stripe Dashboard also applies. Result: users were seeing a Chinese checkout/portal even from English browsers. The app UI is English-only, so hardcode `locale: "en"` on both the Checkout Session and Billing Portal Session to match. Co-Authored-By: Claude Opus 4.7 (1M context) --- supabase/functions/billing/index.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/supabase/functions/billing/index.ts b/supabase/functions/billing/index.ts index cee38b8..068add5 100644 --- a/supabase/functions/billing/index.ts +++ b/supabase/functions/billing/index.ts @@ -113,6 +113,10 @@ Deno.serve(async (req) => { const session = await stripe.checkout.sessions.create({ customer: customerId, mode: "subscription", + // Force English. Stripe's "auto" locale combines Accept-Language with + // IP geolocation, which served a zh checkout even on English browsers. + // Our UI is English-only, so the checkout should match. + locale: "en", line_items: [{ price: priceId, quantity: 1 }], success_url: `${frontendUrl}/settings?checkout=success`, cancel_url: `${frontendUrl}/settings?checkout=canceled`, @@ -137,6 +141,10 @@ Deno.serve(async (req) => { const session = await stripe.billingPortal.sessions.create({ customer: profile.stripe_customer_id, return_url: `${frontendUrl}/settings`, + // Same reason as checkout above. Note this also overrides the + // Billing Portal configuration's default language set in the Stripe + // Dashboard, which would otherwise win over Accept-Language. + locale: "en", }) return jsonResponse({ url: session.url }, req, { status: 200 })