[2026-07-09] eagle: work/projects/ios-subscription-day7-promo-pixels.md

This commit is contained in:
Alexey Martemyanov
2026-07-09 16:42:00 +06:00
parent 6f30079712
commit 9e596e145b
@@ -6,11 +6,11 @@
- **Project:** [iOS: Show subscription half-sheet promo to new installers who don't see it during onboarding](https://app.asana.com/1/137249556945/project/1202406491309510/task/1214798984829406)
- **Android counterpart:** [Grow active subscriptions by increasing paywall impressions with a day 7 promo half-sheet](https://app.asana.com/1/137249556945/project/72649045549333/task/1210994036696114) — the iOS implementation follows the same approach and target audience as Android
- **Origin request:** [Request origin for iOS subscription promo half-sheet entry point](https://app.asana.com/1/137249556945/task/1214800683792174) — origin value `funnel_modal_ios__subscriptionnudge` (Android equivalent: `funnel_newusermodal_android`)
- **Origin request:** [Request origin for iOS subscription promo half-sheet entry point](https://app.asana.com/1/137249556945/task/1214800683792174) — **origin not yet formally approved**; placeholder in code is `funnel_modal_ios__subscriptionnudge`. Android equivalent (formally approved, post-unification): `funnel_browsermodal_android` ([origin definition](https://app.asana.com/1/137249556945/task/1214454966691411), [unify origins task](https://app.asana.com/1/137249556945/task/1214440762354001))
- We are adding a new half-sheet modal for existing users (7+ days since install) who have never seen any subscription offer. The modal reuses the pre-existing `SubscriptionPromoLaunchView` UI.
- Existing subscription promo pixels already cover related audiences:
- `m_privacy-pro_onboarding_promotion_impression/tap/dismiss` — users who see the promo during onboarding
- `m_privacy-pro_skipped_onboarding_promotion_impression/tap/dismiss` — reinstallers who skipped onboarding (7+ days)
- `m_privacy-pro_onboarding_promotion_[impression|tap|dismiss]` — users who see the promo during onboarding
- `m_privacy-pro_skipped_onboarding_promotion_[impression|tap|dismiss]` — reinstallers who skipped onboarding (7+ days)
## Objective
@@ -20,12 +20,13 @@
## Android reference
Android uses a **single shared pixel** (`AppPixelName.ONBOARDING_DAX_CTA_SHOWN`, ctaId `DAX_INTRO_PRIVACY_PRO`) for both the reinstaller promo and the day-7 promo, with **no `origin` pixel parameter** — origin is only embedded in the subscription purchase URL (`https://duckduckgo.com/pro?origin=…`) for downstream funnel attribution:
Android uses **shared pixels** for both the reinstaller promo and the day-7 promo, with **no `origin` pixel parameter** — origin is only embedded in the subscription purchase URL (`https://duckduckgo.com/pro?origin=…`) for downstream funnel attribution:
| Android audience | Pixel name | `origin` in URL |
| Event | Android pixel string | `origin` in URL |
|---|---|---|
| Reinstaller / skipped onboarding | `ONBOARDING_DAX_CTA_SHOWN` | `funnel_skippedonboarding_android` |
| Day-7 existing users (new) | `ONBOARDING_DAX_CTA_SHOWN` | `funnel_newusermodal_android` |
| Shown (both audiences) | `m_odc_s` | `funnel_browsermodal_android` (unified; was `funnel_skippedonboarding_android` / `funnel_newusermodal_android` before unification) |
| CTA tapped (both audiences) | `m_odc_ok` | same as above |
| Dismissed (both audiences) | `m_onboarding_dax_cta_dismiss` | same as above |
The two audiences are **indistinguishable at the pixel level** on Android — analysis relies on the origin flowing to downstream purchase pixels. Source: [Android PR #8369](https://github.com/duckduckgo/Android/pull/8369), `BrowserTabViewModel.kt` + `CtaViewModel.kt`.
@@ -57,13 +58,12 @@ Define three new pixels exclusively for the day-7 audience. Provides direct per-
### Testing
- Feature is implemented in: `iOS/DuckDuckGo/SubscriptionPromo/SubscriptionPromoExistingUserCoordinator.swift`
- Test paths:
- Install app, complete or skip onboarding
- Wait 1 minute (1-min override active — revert to 7 days before shipping)
- Background and re-foreground app → promo half-sheet should appear
- Verify `m_privacy-pro_existing_user_promotion_impression` fires on display
- Tap CTA → verify `m_privacy-pro_existing_user_promotion_tap` fires and subscription flow opens with origin `funnel_modal_ios__subscriptionnudge`
- Tap CTA → verify `m_privacy-pro_existing_user_promotion_tap` fires and subscription flow opens with the approved origin (placeholder: `funnel_modal_ios__subscriptionnudge`)
- Re-install and dismiss instead → verify `m_privacy-pro_existing_user_promotion_dismiss` fires
### Pixel definitions
@@ -108,4 +108,4 @@ Define three new pixels exclusively for the day-7 audience. Provides direct per-
- Option A pixels are already defined in `subscription.json5` as `m_privacy-pro_skipped_onboarding_promotion_[impression|tap|dismiss]`; reusing them for this audience requires no code changes to pixel definitions.
- If Option B is chosen, new definitions must be added to `subscription.json5` and a privacy triage opened.
- Privacy triage (for Option B): [Insert Privacy Triage link]
- Origin `funnel_modal_ios__subscriptionnudge` needs formal approval via the [Origin Proposal form](https://form.asana.com/?k=Wy3aY17vglr2bihpUHoyBA&d=137249556945) — tracked in the origin request subtask above — regardless of which option is selected.
- The iOS origin in the code (`funnel_modal_ios__subscriptionnudge`) is a **placeholder** — it has not been submitted through the origin form and is not yet approved. The final string may differ. This must be resolved before shipping, regardless of which pixel option is selected. Android equivalent post-unification is `funnel_browsermodal_android`. Origin Proposal form: [https://form.asana.com/?k=Wy3aY17vglr2bihpUHoyBA&d=137249556945](https://form.asana.com/?k=Wy3aY17vglr2bihpUHoyBA&d=137249556945)