Tracking Custom Paywall Impressions
Track paywall impressions for custom paywalls to power analytics
If you're building a custom paywall (i.e., not using RevenueCat Paywalls), you can report when a customer sees your paywall by calling trackCustomPaywallImpression.
RevenueCat Paywalls track impressions automatically. This method is only needed if you're building your own paywall UI.
Supported SDK versions
| RevenueCat SDK | Minimum Version |
|---|---|
| purchases-ios | 5.66.0+ |
| purchases-android | 9.26.1+ |
| react-native-purchases | 9.14.0+ |
| purchases-capacitor | 12.3.0+ |
| purchases-flutter | 9.15.0+ |
| purchases-unity | 8.8.0+ |
| purchases-kmp | 2.9.0+17.52.0+ |
Tracking an Impression
Call trackCustomPaywallImpression as soon as your custom paywall becomes visible to the customer. You can optionally pass the identifier of your custom paywall. By default, the SDK assumes the paywall is displaying the current offering. You can override this by passing a different offering ID.
- Swift
- Objective-C
- Kotlin
- Kotlin MP
- Java
- Flutter
- React Native
- Capacitor
- Unity
// Basic usage
Purchases.shared.trackCustomPaywallImpression()
// Passing your custom paywall identifier
Purchases.shared.trackCustomPaywallImpression(
CustomPaywallImpressionParams(paywallId: "my-paywall")
)
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.shared.trackCustomPaywallImpression(
CustomPaywallImpressionParams(
paywallId: "my-paywall",
offeringId: "premium-offering"
)
)
// Basic usage
[[RCPurchases sharedPurchases] trackCustomPaywallImpression];
// Passing your custom paywall identifier
RCCustomPaywallImpressionParams *params =
[[RCCustomPaywallImpressionParams alloc] initWithPaywallId:@"my-paywall"];
[[RCPurchases sharedPurchases] trackCustomPaywallImpression:params];
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
RCCustomPaywallImpressionParams *params =
[[RCCustomPaywallImpressionParams alloc] initWithPaywallId:@"my-paywall"
offeringId:@"premium-offering"];
[[RCPurchases sharedPurchases] trackCustomPaywallImpression:params];
// Basic usage
Purchases.sharedInstance.trackCustomPaywallImpression()
// Passing your custom paywall identifier
Purchases.sharedInstance.trackCustomPaywallImpression(
CustomPaywallImpressionParams(paywallId = "my-paywall")
)
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.sharedInstance.trackCustomPaywallImpression(
CustomPaywallImpressionParams(
paywallId = "my-paywall",
offeringId = "premium-offering"
)
)
// Basic usage
Purchases.sharedInstance.trackCustomPaywallImpression()
// Passing your custom paywall identifier
Purchases.sharedInstance.trackCustomPaywallImpression(
CustomPaywallImpressionParams(paywallId = "my-paywall")
)
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.sharedInstance.trackCustomPaywallImpression(
CustomPaywallImpressionParams(
paywallId = "my-paywall",
offeringId = "premium-offering"
)
)
// Basic usage
Purchases.getSharedInstance().trackCustomPaywallImpression(
new CustomPaywallImpressionParams()
);
// Passing your custom paywall identifier
Purchases.getSharedInstance().trackCustomPaywallImpression(
new CustomPaywallImpressionParams("my-paywall")
);
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.getSharedInstance().trackCustomPaywallImpression(
new CustomPaywallImpressionParams("my-paywall", "premium-offering")
);
// Basic usage
Purchases.trackCustomPaywallImpression();
// Passing your custom paywall identifier
Purchases.trackCustomPaywallImpression(
params: CustomPaywallImpressionParams(paywallId: 'my-paywall'),
);
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.trackCustomPaywallImpression(
params: CustomPaywallImpressionParams(
paywallId: 'my-paywall',
offeringId: 'premium-offering',
),
);
// Basic usage
Purchases.trackCustomPaywallImpression();
// Passing your custom paywall identifier
Purchases.trackCustomPaywallImpression({
paywallId: "my-paywall",
});
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.trackCustomPaywallImpression({
paywallId: "my-paywall",
offeringId: "premium-offering",
});
// Basic usage
Purchases.trackCustomPaywallImpression();
// Passing your custom paywall identifier
Purchases.trackCustomPaywallImpression({
paywallId: "my-paywall",
});
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.trackCustomPaywallImpression({
paywallId: "my-paywall",
offeringId: "premium-offering",
});
// Basic usage
Purchases.TrackCustomPaywallImpression();
// Passing your custom paywall identifier
Purchases.TrackCustomPaywallImpression(
new Purchases.CustomPaywallImpressionParams("my-paywall")
);
// Passing your custom paywall identifier and offering id (only useful if the paywall is not displaying the current offering)
Purchases.TrackCustomPaywallImpression(
new Purchases.CustomPaywallImpressionParams(
paywallId: "my-paywall",
offeringId: "premium-offering"
)
);
Best Practices
Call this method right after the paywall has rendered and is visible on screen. Make sure it is only called once per paywall view — for example, onAppear in SwiftUI may fire multiple times for the same view.
If you don't call trackCustomPaywallImpression, exposure data will be incomplete and analytics will be less reliable. Make sure every code path that shows your paywall includes this call.
Next Steps
- If you haven't already, set up your custom paywall to display products from RevenueCat Offerings