Revenue Expansion beta
Send Stripe metadata that Revenue Linter can read.
Add stable user IDs and UTM-style attribution to Stripe Checkout, Subscriptions, Customers, or PaymentIntents. Revenue Linter reads the metadata later to group active subscriptions, silent churn, and upgrade-ready accounts by campaign.
Recommended fields
Use consistent keys before the customer pays.
Metadata should be stable and non-sensitive. Do not store ad platform tokens, session cookies, raw IP addresses, personal notes, or secrets in Stripe metadata.
Subscription Checkout
Attach attribution to the Checkout Session and Subscription.
The Checkout Session metadata helps Revenue Linter tie acquisition context to the first checkout. The Subscription metadata helps that context stay available during later billing-state scans.
await stripe.checkout.sessions.create({
mode: "subscription",
customer: stripeCustomerId,
line_items: [{ price: priceId, quantity: 1 }],
success_url: successUrl,
cancel_url: cancelUrl,
metadata: {
appUserId: user.id,
utm_source: attribution.utmSource,
utm_medium: attribution.utmMedium,
utm_campaign: attribution.utmCampaign,
utm_content: attribution.utmContent,
utm_term: attribution.utmTerm,
landing_page: attribution.landingPage,
referrer: attribution.referrer,
signup_source: attribution.signupSource
},
subscription_data: {
metadata: {
appUserId: user.id,
utm_source: attribution.utmSource,
utm_medium: attribution.utmMedium,
utm_campaign: attribution.utmCampaign,
landing_page: attribution.landingPage,
signup_source: attribution.signupSource
}
}
});Customer metadata
Keep the stable app identity on the Stripe Customer.
Customer metadata is useful when a workspace has subscriptions or payments that are missing Checkout Session metadata.
await stripe.customers.update(stripeCustomerId, {
metadata: {
appUserId: user.id,
signup_source: attribution.signupSource,
first_utm_source: attribution.utmSource,
first_utm_campaign: attribution.utmCampaign
}
});One-time payments
Use PaymentIntent metadata for non-subscription revenue.
Revenue Expansion currently focuses on active subscriptions, but consistent PaymentIntent metadata helps later reconciliation and campaign cohorting.
await stripe.paymentIntents.create({
amount: amountCents,
currency: "usd",
customer: stripeCustomerId,
metadata: {
appUserId: user.id,
utm_source: attribution.utmSource,
utm_campaign: attribution.utmCampaign,
landing_page: attribution.landingPage
}
});How Revenue Linter uses it
Campaign cohorts
Groups active subscription MRR and signal counts by UTM source and campaign when metadata exists.
Silent churn context
Shows which acquisition source produced active-billing accounts with no recent app or product usage.
Expansion exports
Adds attribution columns to the CSV export for team-reviewed customer-success or upgrade follow-up.