Skip to content

Purchase celebration ​

Use the existing smiling and standing Mushie artwork for a warm confirmation after a pack, card subscription, WeChat membership, or paid plan upgrade. Keep the app's dark card and Inter typography, with gold taken from the mascot's wand. Center the art, thank-you message, actual delivery amount, and one "Have fun!" action. Use one short sparkle entrance, disabled for reduced motion. Use the standard accessible dialog with keyboard dismissal and focus trapping. Pack celebrations vary the existing artwork by base pack size: one mascot for 1,000/3,000, two for 10,000/20,000/44,000, and three for 116,000 Mushies. Member bonuses do not change the artwork group. Memberships keep the single mascot.

Mushies are delivered to the wallet, not an inbox. Show the credited amount from the ledger, including the actual member bonus, and the next scheduled drop when applicable. A paid upgrade shows its confirmed balance; never infer a purchase grant by subtracting two changing wallet balances. Preserve existing plan-change confirmation and delayed-downgrade behavior.

Implementation and verification ​

  • [x] Pure checkout-receipt policy tests: ownership, payment pending, fulfillment pending, credited pack bonus, subscription first drop, gift-plan baseline, duplicate refunds, failed and expired payments.
  • [x] Authenticated read-only receipt endpoint using Stripe session ownership and the user's ledger. Include {CHECKOUT_SESSION_ID} in Checkout return URLs.
  • [x] Checkout return polls for delivery, with cancellation on navigation, bounded waits and a check-again action. Mark displayed receipts locally to avoid repeating celebrations on refresh; remove the return parameters on close.
  • [x] Shared celebration dialog for checkout and confirmed in-app upgrades. Translate all user-facing copy in the five supported locales.
  • [x] Behavioral tests for pending-to-ready, errors/retry, dismissal, and suppression of already displayed receipts. Reduced-motion styles inspected.
  • [x] Billing regression tests, app tests, root typecheck/build, and OSS export verification. Independent review before updating the draft PR.

No live charges or refunds are needed for verification. Browser previews use example receipt data and block external requests. No schema changes or extra notifications.

Pack checkout ​

Packs use one Buy button and Stripe's standard one-time Checkout, which chooses its available payment methods. There is no pack-specific WeChat button, currency label, or payment-method/currency override. The separate WeChat membership option remains restricted to Chinese-language UI.

Verified on September 24, 2026 ​

  • 102 focused server tests pass (receipts, single subscription enforcement, webhook routing, account deletion, plan changes, billing coverage, free-credit policy, and scheduled plan drops).
  • 14 app tests pass (receipt polling/storage, dialog behavior, plan-change math).
  • pnpm build and pnpm typecheck pass.
  • pnpm oss:verify passed export checks, dependency installation, typechecking, build, and the exported test suites for the original release. The subsequent pack-button removal only touches hosted files excluded from the export; node scripts/oss-export.mjs --no-lockfile rechecked the export tree.
  • Independent review completed; the unpaid-upgrade false-success finding was fixed and regression-tested before final verification.

The production React/Radix component was rendered with the real styles and artwork in Chromium. All three mascot groups were checked, including a 320px-wide viewport, reduced motion, and dismissal. No overflow or page errors were observed. No live payment was performed. Automated dialog tests use JSDOM with a lightweight dialog shell.