When the bug is live, every plan upgrade in your customer base looks like a new trial conversion. Channel ROAS gets inflated by 30–80%, lookalike seeds become contaminated with existing customers, and the platforms’ algorithms start optimizing toward upgrades instead of new acquisition.
The right trigger
Use Stripe’s `customer.subscription.updated` event, filtered to records where `previous_attributes.status = 'trialing'` and `current.status = 'active'`. That filter only fires on real trial-to-paid conversions, not on plan changes.
Tag plan upgrades and downgrades as their own events (Upgrade, Downgrade, Plan Changed). That way the attribution doesn’t collide with the new-customer events, and you can build separate expansion-revenue reports for upgrades.
- Trigger: `customer.subscription.updated`
- Filter: `previous_attributes.status` = 'trialing' AND `status` = 'active'
- Tag plan changes (`previous_attributes.plan` ≠ current `plan`) as Upgrade/Downgrade
- Audit monthly against Stripe’s native trial-conversion count
Auditing the setup
Run a monthly audit: count Stripe trial-to-paid conversions in the last 30 days from Stripe’s native dashboard, then count Cometly Trial Converted events in the same window. They should match within 1–2%. A 10%+ delta means something is misfiring — either the filter is too loose (counting upgrades) or too tight (missing real conversions).
What to watch for.
- Using payment amount as a trial-conversion filter
Plan upgrades match payment-amount filters. Always use the status-transition filter instead.
- Letting upgrades and new customers share an event
Expansion revenue and new acquisition are different problems. Separate them at the event level.
- Skipping the monthly audit
These bugs are silent. You only catch them with a routine reconciliation against Stripe’s native dashboard.
Recap.
- Use `subscription.updated` with the `previous_attributes.status = trialing` filter
- Tag plan upgrades and downgrades as their own events for accurate expansion-revenue reporting
- Never use simple payment-amount filters as a trial-conversion signal — they capture upgrades too
- Audit historical trials monthly to catch silent regressions in event firing
- Keep a 'No Source' bucket visible so you can spot tracking gaps fast