Error toasts surfaced the raw English backend message. Added an errors namespace (fa/ar/en) keyed by error code + a useApiError() resolver that maps ApiClientError.code to the localized message (fallback to a localized generic). Wired into menu, tables, demo banner, and subscription checkout; hardened getErrorMessage so it never returns the raw backend message.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Previously the subscribe mutation had no onError handler, so any
payment initiation failure (wrong merchant ID, ZarinPal API error,
disabled payment method) would silently re-enable the button with
no user feedback. Now errors are shown below the Pay button.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Insert a factor/invoice page between plan selection and payment showing
billing-period choice, line items, and totals before redirecting to the
gateway, moving payment-method selection to where the charge happens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>