RevenueCat

RevenueCat Integration Guide

Integrate Botsi AI Pricing with RevenueCat to show each user the optimal paywall based on Botsi's machine learning predictions. RevenueCat handles offerings and paywall display, while Botsi determines which offering each user should see.

1. Normal Botsi AI API Setup

Complete the standard Botsi AI Pricing integration following the AI Pricing Integration Guide.

2. Set Up Different Offers/Paywalls in RevenueCat and Botsi

Decide what prices you want to show and how you want to present them on different paywalls.

If you use RevenueCat Offerings to determine what products users can see on a paywall, you can set up these different offerings with these different products attached in their dashboard.

RevenueCat Offerings dashboard showing the standard offering configuration

For example, if you want to use multiple annual price points, you could set up:

  • Offering: "default" — annual → com.app.pro.annual_standard
  • Offering: "discounted" — annual → com.app.pro.annual_discounted

Then, you'll set up Paywalls in Botsi that correspond to the RevenueCat Offerings. You can add the same products you have in a RevenueCat Offering to the Botsi Paywall. This lets the AI model know what prices/products are available.

Botsi Paywall dashboard showing products matching RevenueCat offerings

3. Botsi Get Paywall API

You will specify the external ID value (data.externalID) in the Botsi dashboard when setting up a paywall.

The exact value is not important as long as it's unique, but we recommend using a common naming convention so you can keep track in other tools. (e.g. onboardingPaywall_29.99Annual_v2)

When you call the Botsi Get Paywall API, it will return that "external ID" value to you. Technically, you can use data.ID or data.externalID, but ID is always a number that you cannot adjust and so is less easily understood.

You will then use this value to set a "Custom Attribute" in RevenueCat using their SDK.

The naming of this custom attribute is not important as you'll parse out the value from the Botsi API and write it via the RevenueCat SDK. We recommend an understandable name for other internal users. (e.g. "botsi_paywall_id" or "botsi_paywall_prediction")

You will use the externalID as the value.

4. RevenueCat Paywall and Offering Targeting using Botsi

You will use RevenueCat Targeting Rules with custom attributes to show the right paywall/offering to the right user. Follow the instructions there for setting up your targeting rules based on the custom attribute you added.

You will need to call the syncAttributesAndOfferingsIfNeeded() method in the RevenueCat SDK to ensure that the customer sees the correct paywall based on any newly set custom attributes.

You should call this method after the custom attribute is set and before the paywall is shown.

5. Send the Paywall Impression

Continue with API call 3, Profile Events API in the documentation, to send the paywall impression.

This should reference the Get Paywall API response field "id" (not externalID).

6. Send Purchase Transaction Data to Botsi

You will need to send the iOS Transaction ID/Original Transaction ID, or Android Purchase token, for the Botsi Purchase Validate API. You can get this from the RevenueCat SDK:

  • Swift
  • Kotlin
  • React Native
  • Unity
let result = try await Purchases.shared.purchase(package: package)
if let tx = result.transaction {
    let appleTransactionId = tx.transactionIdentifier    // e.g. "2000001234567890"
    let originalTxId = txsk2Transaction?.originalID
    // Send to Botsi backend API (Section 4a in Botsi documentation)
    // POST to /api/v1/web-api/purchases/apple-store/validate
}
val result = purchases.purchase(activity, packageToBuy)
// Android:
result?.let { tx ->
    val purchaseToken = tx.purchaseToken    // e.g. "abcdefhijklmnop..."
    val orderId = tx.orderId                // if you also need Google orderId
    // send to your backend here
}

See RevenueCat's Making Purchases documentation for more details. Use setAttributes() to set the Botsi custom attribute, and syncAttributesAndOfferingsIfNeeded() to sync before fetching offerings.

import Purchases from 'react-native-purchases';

// Set the custom attribute with Botsi's predicted paywall ID
Purchases.setAttributes({
    "botsi_paywall_id": botsiExternalPaywallId
});

// Sync attributes and refresh offerings for targeting
await Purchases.syncAttributesAndOfferingsIfNeeded();

// Make the purchase
const { customerInfo, productIdentifier } = await Purchases.purchasePackage(package);

// Access the transaction identifier from customerInfo
// For subscriptions, check customerInfo.entitlements
// For non-subscriptions, check customerInfo.nonSubscriptionTransactions
const transactions = customerInfo.nonSubscriptionTransactions;
if (transactions.length > 0) {
    const transactionId = transactions[0].transactionIdentifier;
    // Send to Botsi backend API
    // iOS: POST to /api/v1/web-api/purchases/apple-store/validate
    // Android: POST to /api/v1/web-api/purchases/play-store/validate
}

See RevenueCat's Unity SDK documentation for more details. Use SetAttributes() to set the Botsi custom attribute.

using RevenueCat;

// Set the custom attribute with Botsi's predicted paywall ID
var purchases = GetComponent<Purchases>();
purchases.SetAttributes(new Dictionary<string, string> {
    { "botsi_paywall_id", botsiExternalPaywallId }
});

// Sync attributes and refresh offerings for targeting
purchases.SyncAttributesAndOfferingsIfNeeded();

// Make the purchase
purchases.PurchasePackage(package, (productIdentifier, customerInfo, userCancelled, error) => {
    if (!userCancelled && error == null) {
        // Access transaction from customerInfo
        var transactions = customerInfo.NonSubscriptionTransactions;
        if (transactions.Count > 0) {
            var transactionId = transactions[0].TransactionIdentifier;
            // Send to Botsi backend API
            // iOS: POST to /api/v1/web-api/purchases/apple-store/validate
            // Android: POST to /api/v1/web-api/purchases/play-store/validate
        }
    }
});

Notes

  • Ensure server-side notifications are configured in both RevenueCat and Botsi for accurate analytics
  • The custom attribute set in RevenueCat should match the targeting rules you configure in the RevenueCat dashboard
  • Always handle errors appropriately when calling both Botsi and RevenueCat APIs
  • Test the integration thoroughly in sandbox/test environments before going to production
  • Remember to call syncAttributesAndOfferingsIfNeeded() after setting the custom attribute and before displaying the paywall