## Problem Audit of the billing module surfaced 5 high/medium UX reliability issues: 1. `paused` and `unpaid` subscription statuses fall through to default grey chip with no action button — user silently stuck 2. Stripe redirect URLs validated only for HTTPS, no host whitelist — malicious/misconfigured API response could redirect off-Stripe 3. `useMeter` silent `.catch(() => {})` on refresh and initial fetch — errors swallowed, no visibility 4. Checkout poll (pollSubscription) has no abort flag — recursive setTimeout chain continues for one tick after beforeUnmount 5. All French diacritics stripped from billing lang/fr.js — rendering broken for FR locale users ## Expected behaviour - paused → warning chip + Reactivate CTA; unpaid → error chip + Update payment method CTA - All Stripe redirect URLs validated against hostname whitelist (checkout.stripe.com, billing.stripe.com) - useMeter errors logged and exposed via reactive meterError ref - Poll aborted cleanly when component unmounts - All French strings render correctly with proper accents
Activity
fix(billing): billing UX hardening — 5 reliability fixes (#4079)
fix(billing): billing UX hardening — 5 reliability fixes
chore(release): 2.1.0