Skip to content

Keep card-payment loading out of model settings ​

A signed-in, read-only PvZ phone-rotation check preserved the reply draft, held the question clock, reopened the model picker and resumed combat, but reported an uncaught Failed to load Stripe.js. The shared tip controls called loadStripe during module evaluation. Importing the app's routes was enough to start payment loading even when the player only opened AI settings. The SDK's default entry point also injects its script on import.

The tip controls now retain the configured availability of money tips while loading the pure SDK entry point only after explicit card checkout. Failed loads use the existing inline retryable error and create no payment intent. A closed or unmounted dialog discards the pending continuation. Amount/type controls remain disabled during checkout so the visible quote cannot change under the request. Successful initialization is reused. Mushie gifts remain independent of Stripe. This changes neither PvZ dialogue/pacing nor AI, save, billing or payment-confirmation endpoints.

Evidence ​

  • The initial import regression failed on the old code because an actual Stripe script appeared in JSDOM without any payment interaction.
  • Fourteen focused tip/model-picker tests pass: real SDK loading with simulated script failure/success; cancellation, retry and reuse; gift-only operation; account identity, selected private/computer models and saved pins. Payment iframe presentation and API responses are fixtures, with no real charge.
  • The first build/typecheck caught a test-only TypeScript narrowing error after an empty-array assertion. Correcting the assertion preserved the runtime check; subsequent build and typecheck passed.
  • Final full build/typecheck, edition-boundary validation and pnpm oss:verify pass. The hosted-only tip files are excluded from the generated local edition.
  • The compiled hosted UI passes the signed-in English phone-rotation journey over the current public game. Held questions keep their clock, typed drafts survive rotation and model settings, simulated keyboard geometry fits, and an authored answer resumes combat. Stripe requests and page errors are zero; normal account save/config hashes are unchanged. All API mutations are blocked.

Compiled browser verification and deployment receipts are recorded separately in the PvZ campaign repository. The original phone-rotation failure remains under output/phone-rotation-dialogue/en/; successful follow-ups must use new output directories. Emulated viewport/keyboard checks do not certify physical phone behavior.