Skip to main content
Skip to navigation

Paywall events

Receive RevenueCat Paywall events in your app or send them to your analytics platforms

Ask RicoChatGPTClaude

RevenueCat Paywalls generate events as Customers view and interact with them. You can receive these events in two ways:

  • In your app, through SDK callbacks that fire at key moments, so you can send your own events to any analytics tool
  • In an analytics integration, delivered by RevenueCat alongside your subscription lifecycle events

Both work at the same time. Listening to the callbacks doesn't change what RevenueCat sends to your integrations.

Receiving events in your app​

The SDK fires a callback at most of these moments, so you can send your own events from them. RevenueCat also sends the matching event to any integrations you've enabled. For callback names on each platform, see Callbacks by platform.

MomentSDK callbackIntegration event
Paywall shownNonepaywall_impression
Paywall closedClosepaywall_close
Payment confirmation dismissed without purchasingCancelpaywall_cancel
Exit offer shownExit offer (UIKit)paywall_exit_offer
Paywall control changedComponent interactionpaywall_component_interacted

For multi-step paywalls, RevenueCat sends paywall_impression and paywall_close only for paywall steps, the steps with packages to purchase. The SDK callbacks cover the whole flow, from the first step to the last.

  • Paywall shown: RevenueCat sends paywall_impression each time a paywall is visited. No SDK callback fires at this moment.
    • For a single-screen paywall, send your own event when you present the paywall.
    • For multi-step paywalls, paywall_impression fires each time a paywall step is visited, including when the Customer returns to one. You can only send your own event when you present the flow, so it also counts Customers who leave before they visit a paywall step.
  • Paywall closed: the close callback fires whenever the paywall closes, including after a purchase.
    • For multi-step paywalls, the close callback is a flow close: it fires whenever the flow closes, from any step. paywall_close fires only if the flow closes while a paywall step is showing. Moving between steps fires no close event. So your close events can outnumber paywall_close.
  • Payment confirmation dismissed without purchasing: the paywall stays open.
  • Exit offer shown: only UIKit on iOS has a callback. The other platforms that support exit offers show them without one. Kotlin Multiplatform and Web don't support exit offers.
  • Paywall control changed: the callback passes the same properties as paywall_component_interacted. See Component interactions.

Unlike onInteraction, the close, cancel, and exit offer callbacks don't pass paywall properties such as paywall_id or offering_id. Add the ones you need from your own code.

Callbacks by platform​

PlatformCloseCancelExit offerComponent interaction
iOS (SwiftUI)onDismiss on presentPaywall or presentPaywallIfNeeded. For an embedded PaywallView, use your own .onDisappear.onPurchaseCancelledNo callback.onPaywallInteraction
iOS (UIKit)paywallViewControllerWasDismissed(_:)paywallViewControllerDidCancelPurchase(_:)paywallViewController(_:willPresentExitOfferController:)paywallViewController(_:didTrackInteraction:)
AndroiddismissRequest on PaywallOptions, or the PaywallActivityLauncher resultPaywallListener.onPurchaseCancelledNo callbackPaywallListener.onInteraction
Kotlin MultiplatformdismissRequest on PaywallOptionsPaywallListener.onPurchaseCancelledNot applicable. KMP paywalls don't show exit offersPaywallListener.onInteraction
FlutteronDismiss on PaywallView, or when presentPaywall completesonPurchaseCancelledNo callbackonInteraction
React NativeonDismiss on RevenueCatUI.Paywall, or when presentPaywall resolvesonPurchaseCancelledNo callbackonInteraction
CapacitorThe paywallDismissed listener, or when presentPaywall resolveslistener.onPurchaseCancelledNo callbacklistener.onInteraction
UnityWhen PaywallsPresenter.Present completesPaywallListener.OnPurchaseCancelledNo callbackPaywallListener.OnInteraction
WebWhen presentPaywall resolves or rejectslistener.onPurchaseCancelledNot applicable. Web paywalls don't show exit offerslistener.onInteraction

On Android, onPurchaseCancelled doesn't fire if you pass your own purchase logic (PurchaseLogic) to the paywall. This includes cross-platform apps running on Android. Track the cancellation in your own purchase code instead.

The SDK also fires callbacks for purchases and restores, such as onPurchaseStarted, onPurchaseCompleted, onPurchaseError, and onRestoreCompleted. RevenueCat doesn't send paywall events for these moments. Purchases reach your integrations as subscription lifecycle events. For the full list of callbacks on each platform, see Displaying Paywalls.

Component interactions​

When a Customer interacts with a paywall control, such as a tab, package, or purchase button, the SDK calls your onInteraction callback with a paywall_component_interacted event. The event is a set of snake_case properties that matches the component interaction reference. Properties that don't apply to an interaction are omitted.

PaywallView()
.onPaywallInteraction { event in
analytics.track("paywall_interaction", properties: event.rawProperties)

let componentType = event.property(for: PaywallInteractionEvent.Keys.componentType)
if componentType == PaywallInteractionEvent.ComponentTypes.purchaseButton {
// React to a specific interaction
}
}

Where onInteraction is available​

PlatformMinimum version
iOS5.89.0
Android10.21.0
Kotlin Multiplatform3.9.0
Flutter10.14.0
React Native10.13.0
Capacitor13.6.0
Unity9.11.0
Web1.60.0

On iOS, Android, and Kotlin Multiplatform the callback receives a PaywallInteractionEvent. Use rawProperties to forward every property, or read a single typed value with the constants in PaywallInteractionEvent.Keys. On the other platforms the callback receives the properties as a plain map or object.

Sending events to integrations​

RevenueCat can deliver paywall events to the following integrations, alongside the standard subscription lifecycle events they already receive.

Supported integrations​

IntegrationUse case
AmplitudeAnalyze paywall engagement alongside subscription lifecycle events in your Amplitude project
MixpanelTrack paywall views and interactions in your Mixpanel project for cohort and funnel analysis
PostHogCombine paywall events with your product analytics in PostHog
SegmentRoute paywall events through your Segment workspace to your warehouse and downstream destinations

Paywall event types​

All four integrations support the same set of paywall-specific events, in addition to the standard RevenueCat subscription lifecycle events they already track:

EventDefault nameDescription
Paywall impressionpaywall_impressionFired when a paywall is displayed to a Customer. For multi-step paywalls, it fires each time a paywall step (a step with packages to purchase) is visited, not when the flow starts
Paywall closepaywall_closeFired when a Customer closes a paywall. For multi-step paywalls, it fires only if the flow closes while a paywall step is showing
Paywall cancelpaywall_cancelFired when a Customer dismisses the payment confirmation on a paywall
Paywall exit offerpaywall_exit_offerFired when an exit offer is shown on a paywall
Paywall component interactionpaywall_component_interactedFired when a Customer changes a paywall control (tab, package, purchase button, sheet, etc.). See the component interaction reference for field details

You can customize the name for each event in the integration settings.

Paywall events are not purchase lifecycle events. They don't include transaction fields such as product_id, price, or transaction_id.

Enabling paywall events​

Paywall event delivery is opt-in, and you enable it per integration. Set the integration up first using the integration-specific docs linked above, then:

  1. Navigate to Integrations in your project and open the relevant integration
  2. Click the Paywall Events tab
  3. Check Send Paywall events
  4. Optionally customize the event names
  5. Save your changes

Next steps​

Was this page helpful?