3.5 Connecting Stripe customers to PostHog persons/groups is confusing
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 39.9k
- Forks
- 3.4k
- Avg merge
- 6h 51m
- Merged PRs (30d)
- 232
Description
Problem: The customer-to-person matching workflow is unclear, manual, and limited in SQL expression support. Users expect this to work automatically since they've connected Stripe.
Idea: Standardize the way we link persons to revenue data, by requiring distinctId to be passed into Stripe metadata field and doing the join ourselves, always using this field.
Implementation
Persons
- Create the join automatically on first Stripe sync - https://github.com/PostHog/posthog/pull/52943
- Create the join automatically on Revenue analytics enablement - https://github.com/PostHog/posthog/pull/53886
- In case the Stripe source already exists, this covers the gap
- Update docs to guide users to update their Stripe calls - https://github.com/PostHog/posthog.com/pull/16167
- Write skill to configure revenue analytics - https://github.com/PostHog/context-mill/pull/106
Groups
For groups, things get a bit trickier. We cannot use the coalescing idea we did for persons because one person may perform events with more than one group. Put simply, person identity is who, group identity is for whom. Here's an example of why coalescing wouldn't work:
Let's think the group maps to an instance of the application us/eu.
- Person P subscribes passing in group US.
- In the future, P moves to Europe and subscribes again with the same account.
- Now, the group passed in is EU
If we'd coalesce the group key by the latest subscription, all revenue from P would be attributed to EU (regardless of the first sub being with US). This suggests that the logical path forward is to assign revenue to groups for each transaction (charge/subscription/invoice) instead of linking persons to groups.
Doing so solves the path forward (once users instrument their Stripe calls with the metadata), but not the historical data.
Backfill
Backfill will be necessary both for persons and groups.
For persons, as customers that churned before Stripe calls got instrumented will have orphaned revenue (it won't be attributed to anyone, as no payments happened after instrumentation, so no distinct id was populated).
For groups, as we're not coalescing metadata, all revenue previous to instrumentation will be lingering. So backfilling here is even more important.
Persons
- Stripe customer < email > PostHog person
Users will have the option to backfill the distinct id for persons matching by email. We have the customer email on Stripe and usually have a similar field in PostHog. The user would pick what person property is the email and trigger the backfill.
Groups
- Stripe customers -> PostHog persons < related groups > groups
- Stripe customers < user defined property > groups
Group backfill can be done through persons, where we'd calculate the related groups for the person that represents the Stripe customer and consider those as the groups for all historical transactions.
Another option is to let the user define a group property/Stripe customer property to do the backfill. This is similar to the joins we currently have in place where the user picks arbitrary properties to connect both tables.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No files, tests, or entry points are named. Review the completed PRs linked under Persons and the unresolved Groups and Backfill sections first; the work is done only when the remaining group attribution and historical backfill design is agreed and implemented.
Written by the indexing model from the issue text.
Assessment
- Domain
- analytics, backend-api-design, payments
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100