> For the complete AppRefer docs index, see https://apprefer.com/llms.txt (every page as markdown) or https://apprefer.com/llms-full.txt (all docs in one file).

# RevenueCat integration

If your app sells through RevenueCat, AppRefer reads RevenueCat’s webhooks to tie each purchase to its ad click and send it to your ad networks, with no purchase tracking code in the app.

> **New apps: use AppRefer Billing**
>
> RevenueCat stays supported for apps that use it. AppRefer Billing does the same job itself for the App Store, Google Play and Stripe (purchases, entitlements, offerings, experiments and conversions), with no data export needed to move over, and this webhook keeps working for old app versions during the switch. See [Billing](https://apprefer.com/docs/billing.md) and [Moving from RevenueCat](https://apprefer.com/docs/billing.md#moving-from-revenuecat). For prices and what each does that the other doesn't, see [AppRefer vs RevenueCat](https://apprefer.com/revenuecat-alternative).

## Why webhooks

-   Renewals, cancellations, billing issues and expiries arrive even when the app is closed.
-   No purchase events to track in the app.
-   One source for the whole subscription lifecycle.

## Set up

1.  In AppRefer, open the app’s Settings → Integrations → RevenueCat and click **Generate** to create a webhook secret. The app’s webhook URL is shown there too.
2.  In RevenueCat → Project settings → Integrations → Webhooks, add a webhook with the URL `https://apprefer.com/api/webhook/revenuecat/{appId}` (your own domain if you host AppRefer yourself).
3.  Set the **Authorization header** value to `Bearer <your secret>`. Any other value gets 401.
4.  Send **all event types**. Sandbox events are accepted, recorded as sandbox and never sent to ad networks.
5.  Send a test event from RevenueCat and check that it shows up in the app’s Live events page.

## Link the AppRefer device id

> **Required for attribution**
>
> Set the `appreferId` subscriber attribute in RevenueCat to the AppRefer device id. It is the surest way for AppRefer to find the install, and its ad click, behind each RevenueCat event.

Call this right after configuring AppRefer, before the user can buy anything:

**Swift**

```swift
await AppRefer.configure(apiKey: "pk_live_...")
if let deviceId = await AppRefer.getDeviceId() {
    Purchases.shared.attribution.setAttributes(["appreferId": deviceId])
}
```

**Kotlin**

```kotlin
AppRefer.configure(context, apiKey = "pk_live_...")
AppRefer.getDeviceId()?.let { deviceId ->
    Purchases.sharedInstance.setAttributes(mapOf("appreferId" to deviceId))
}
```

**Dart**

```dart
await AppReferSDK.configure(AppReferConfig(apiKey: 'pk_live_...'));
final deviceId = await AppReferSDK.getDeviceId();
if (deviceId != null) {
  await Purchases.setAttributes({'appreferId': deviceId});
}
```

**TypeScript**

```typescript
await AppRefer.configure({ apiKey: 'pk_live_...' });
const deviceId = await AppRefer.getDeviceId();
if (deviceId) {
  Purchases.setAttributes({ appreferId: deviceId });
}
```

For each event, AppRefer looks for the install’s attribution in this order:

1.  The `appreferId` attribute (`$appreferId` is also read).
2.  The RevenueCat app user id, original app user id and aliases, matched to the user id you set with AppRefer’s `setUserId`.
3.  The `$idfa` or `$gpsAdId` attribute.
4.  The hashed `$email` attribute.

With no match the event is still recorded (as unattributed), and paid purchases are still sent to your connected ad networks (Meta, TikTok and ChatGPT Ads, and Google when a gclid is known), which credit only what they can match. RevenueCat’s `$ip`, `$email`, `$phoneNumber` and `$displayName` attributes are used for matching quality when present.

## Event mapping

| RevenueCat event | AppRefer event |
| --- | --- |
| INITIAL\_PURCHASE | startTrial (trial period), intro\_purchase (intro offer), promo\_purchase (promotional), otherwise purchase |
| RENEWAL | purchase (trial conversions are flagged is\_trial\_conversion) |
| PRODUCT\_CHANGE | subscribe |
| NON\_RENEWING\_PURCHASE | purchase |
| CANCELLATION | cancellation |
| UNCANCELLATION | reactivation |
| BILLING\_ISSUE | billing\_issue |
| SUBSCRIPTION\_PAUSED | pause |
| SUBSCRIPTION\_EXTENDED | subscription\_extended |
| EXPIRATION | expiration |
| TRANSFER | transfer |
| Anything else | The RevenueCat type in lower case |

## What is sent to ad networks

| Event | Sent? |
| --- | --- |
| INITIAL\_PURCHASE, paid | Yes |
| INITIAL\_PURCHASE, free trial | Only as StartTrial when [qualified trials](https://apprefer.com/docs/qualified-trials.md) are on for an attributed install (held for the delay, dropped if cancelled) |
| RENEWAL, paid | Yes. Trial conversions always; ordinary renewals unless renewal forwarding is off for the app |
| NON\_RENEWING\_PURCHASE | Yes |
| PRODUCT\_CHANGE, CANCELLATION, UNCANCELLATION, BILLING\_ISSUE, SUBSCRIPTION\_PAUSED, EXPIRATION, TRANSFER and others | No (recorded only) |
| Any sandbox event | No |

Meta follows RevenueCat’s recommended mapping: a subscription’s first payment, its trial conversion and every renewal are Subscribe, one-time purchases are Purchase and trial starts are StartTrial. You can change the names in the app’s Meta integration settings. Forwarding also follows each install’s tracking consent (see [Privacy](https://apprefer.com/docs/privacy.md)). Qualified trials keep the purchase surface and the user’s IP and user agent through the delay and retries, so web-funnel trials still go to the web-funnel Meta dataset.

## Duplicates

RevenueCat may deliver an event more than once. AppRefer processes each event id once and remembers processed ids for 30 days.

## Alongside AppRefer Billing

When an app runs AppRefer Billing in `primary` mode, keep this webhook connected while old app versions still buy through RevenueCat. For each store AppRefer Billing is connected to, RevenueCat’s events are no longer forwarded from here: AppRefer saves which app user owns the purchase so later store notifications find them, and money events share AppRefer Billing’s transaction-based id, so each purchase is forwarded once. Stores not connected to AppRefer Billing keep the full RevenueCat path. Once AppRefer’s own Stripe webhook is set up, RevenueCat’s Stripe events are skipped so web purchases aren’t counted twice.

---

Source: https://apprefer.com/docs/integrations/revenuecat · Last updated: 2026-10-19
