Integration

RevenueCat in-app purchase attribution

App Store and Play purchases can't be verified from inside your app — a public mobile credential can report that a conversion happened, but it can't authenticate an amount. RevenueCat's webhook can. There's one configuration detail that decides whether this works at all, and it's in step three.

Start a 14-day trialLast reviewed August 2026
  1. Point a RevenueCat webhook at Revtrail

    In RevenueCat, add a webhook with the Revtrail endpoint as its URL and set an Authorization header value of your choosing.

    RevenueCat → Project settings → Integrations → Webhooks
    https://revtrail.pyln.dev/api/fn/revenueCatRevenue
  2. Save the same Authorization value in your site settings

    Paste the value you set in RevenueCat into the site's settings in Revtrail. Every delivery is checked against it server-side before anything is recorded.

  3. Make the app_user_id match the Revtrail visitor id

    This is the step that matters. Purchases attribute by app_user_id, so RevenueCat's appUserID must be the SAME string your app sends as its Revtrail visitorId. Set both from one stable anonymous UUID you generate on first launch. Get this wrong and the purchase lands on a visitor who has no journey, the funnel doesn't join, and everything looks broken for reasons that aren't visible anywhere.

    app startup
    const visitorId = await getOrCreateStableAnonymousId(); // your own UUID
    
    Purchases.configure({ apiKey: RC_KEY, appUserID: visitorId });
    revtrail.configure({ site: SITE_KEY, visitorId });
  4. Carry the web visitor across the install

    An app-store install carries no referrer, so a store-direct install has no channel of its own. If users arrive from your website, pass the web visitor id into the app through the rt_vid deep-link parameter and adopt it on first launch — then the web-captured source attributes the eventual purchase. For store-direct installs, capture the OS install referrer once and send it as utmSource on the first event.

Which RevenueCat events become what

INITIAL_PURCHASE maps to a trial start where the purchase is a trial, and to a payment otherwise. RENEWAL maps to a payment, so subscription lifetime accumulates on the original journey. Events with store=STRIPE are skipped, because those arrive through the Stripe integration instead and counting both would double your revenue. PROMOTIONAL grants are skipped too — they're not money.

No IDFA, no ATT prompt

The visitor id is a first-party UUID your app generates. It isn't the advertising identifier, it isn't shared across apps, and it doesn't trigger an App Tracking Transparency prompt. That's a deliberate design choice: attribution that costs you a permission dialog costs more than it returns for most apps.

Where mobile attribution honestly stops

If someone hears about your app on a podcast and searches the App Store two days later, no analytics product on earth will attribute that to the podcast without a link they clicked. The rt_vid path covers web-to-app, and the install referrer covers store-direct where the platform provides it. Everything else attributes as direct, and a tool that claims otherwise is guessing.

Questions people actually ask

Do I need RevenueCat, or can I send purchases directly?
You need a verified server-side source for amounts, and RevenueCat's webhook is the supported one for App Store and Play purchases. Your app can report conversion events for counts, but not amounts.
What if I use both Stripe (web) and RevenueCat (mobile)?
That's the expected setup and both can be connected to the same site. RevenueCat deliveries with store=STRIPE are skipped so a payment can't be counted twice.
Which SDKs are available?
Drop-in clients for Swift and React Native, plus a plain HTTP endpoint — any platform that can POST JSON can send events.

Integrations

All integrations