Skip to content

Attribute payment-modal deep links (#payment-pro) to their entry source in checkout_started #1892

Description

@kfarr

Problem

The marketing site pricing page's "Go Pro" CTA links to 3dstreet.app/#payment-pro. On app load, firstModal() in src/store.js opens the payment modal directly from that hash — but:

  1. No modal_opened event fires for hash-opened payment modals (the paywall path via startCheckout() does fire one).
  2. EditorUpgradeModal.jsx passes source={postCheckout || 'editor'}. Deep-link entry never sets postCheckout, so checkout_started and downstream payment_completed report source=editor.

Result: pricing-page conversions are indistinguishable from generic in-editor upgrades in PostHog. A recent verified conversion trail confirmed this — the user entered via #payment-pro and the funnel recorded checkout_started source=editor. We can't measure our highest-intent acquisition surface (the marketing pricing page) at all.

Proposed fix

EditorUpgradeModal already parses the payment hash once at mount (parsePaymentHash). Extend that to record whether the mount hash was a payment deep link, and pass it through:

  • source='payment_deeplink' (or similar) instead of the 'editor' fallback when the modal was opened by the hash
  • keep the existing tier/cycle parsing unchanged
  • optionally fire modal_opened { modal: 'payment', source: 'payment_deeplink' } on hash-open for funnel completeness

Note the deep link is consumed on close/success (consumeDeepLink), so the source flag should follow the same lifecycle — a later in-session paywall trigger must not inherit the deeplink attribution.

Files

  • src/editor/components/EditorUpgradeModal.jsx (source prop, ~line 143; parsePaymentHash)
  • src/store.js (firstModal() hash handling)
  • src/shared/components/UpgradeModal/UpgradeModal.jsx (checkout_started capture, ~line 163)
  • Pricing CTA that emits the link: 3dstreet-docs src/pages/pricing.js

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions