Logging Revenue with RevenueCat

Learn how to log conversion revenue from your in-app purchases if you're using RevenueCat.

ContextDecision supports logging conversions and revenue from any in-app purchase system, including RevenueCat.

Our revenue logging API receives a StoreKit 2 Product object. RevenueCat abstracts away the StoreKit implementation, but it still exposes the underlying Product object if needed.

To retrieve the StoreKit 2 product and log it, implement the paywallViewController(_:didFinishPurchasingWith:) delegate in your class that conforms to PaywallViewControllerDelegate as such:

extension MyDelegateClass: PaywallViewControllerDelegate {
    /// This delegate method notifies when a purchase has finished.
    func paywallViewController(_ controller: PaywallViewController, didFinishPurchasingWith customerInfo: CustomerInfo) {
        guard let latestEntitlement = extractLatestEntitlement(from: customerInfo) else {
            print("No entitlements found.")
            // Handle this scenario
            return
        }
        Purchases.shared.getProducts([latestEntitlement.productIdentifier]) { products in
            if let product = products.first {
                // Log or handle the StoreKit Product object
                if let context = ContextManager.recentContext(flowName: "my_upsell_flow") {
                    context.logRevenueOutcome(from: product.sk2Product)
                } else {
                    // Handle this scenario - make sure your Context is created before presenting the paywall, before reading it here
                }
            } else {
                print("Could not fetch product details for identifier: \(latestEntitlement.productIdentifier)")
                // Handle the error here
            }
        }
    }

    private func extractLatestEntitlement(from customerInfo: CustomerInfo) -> EntitlementInfo? {
        return customerInfo.entitlements.all.values
            .sorted(by: { ($0.latestPurchaseDate ?? .distantPast) > ($1.latestPurchaseDate ?? .distantPast) })
            .first
    }
}

Last updated

Was this helpful?