React Native SDK
The Monetai React Native SDK allows you to integrate our purchase prediction engine directly into your app. This guide will walk you through the entire process, from installation to using key features like event tracking and purchaser prediction.
Prerequisitesβ
- React Native
0.73or higher - iOS: iOS
13.0or higher - Android: API Level
24or higher- Android is supported from SDK version
0.2.9. - Android Billing Client v7 is used from SDK version
0.3.0.
- Android is supported from SDK version
Essential SDK Setupβ
π This section covers the essential steps to install the Monetai SDK and configure it to collect the data needed for purchase predictions.
Please make sure to follow all three steps to lay the foundation for all promotion features.
1. SDK Installationβ
First, add the Monetai package to your project using your preferred package manager.
- yarn
- npm
yarn add @hayanmind/monetai-react-native
npm install @hayanmind/monetai-react-native
iOS Additional Setup
Run the following command in your iOS project to install native modules
cd ios && pod install
App Rebuild
After installation, rebuild your app to apply the changes.
- iOS
- Android
npx react-native run-ios
npx react-native run-android
2. SDK Initializationβ
Initialize the SDK when your app launches. We recommend doing this in a top-level component like App.js.
import MonetaiSDK from "@hayanmind/monetai-react-native";
// Initialize when app starts
const initializeMonetai = async () => {
try {
const result = await MonetaiSDK.initialize({
sdkKey: "YOUR_SDK_KEY", // SDK key issued from Monetai dashboard
userId: "USER_ID", // User ID of your app's user
useStoreKit2: true, // Use StoreKit2 on iOS 15+ devices (recommended)
});
console.log("Monetai SDK initialization completed:", result);
} catch (error) {
console.error("Monetai SDK initialization failed:", error);
}
};
// Call in App.js
useEffect(() => {
initializeMonetai();
}, []);
API Reference: MonetaiSDK.initialize()
Parameters
| Parameter | Type | Description |
|---|---|---|
| sdkKey | string | SDK key issued from Monetai (Settings > SDK Integration) |
| userId | string | User ID of your app's user (if not available, use a unique identifier such as email or device ID) |
| useStoreKit2 | boolean? | Whether to use StoreKit2 (iOS only, default: false) |
Return Value
| Return Value | Type | Description |
|---|---|---|
| organizationId | number | Organization ID |
| platform | 'react_native' | Platform info |
| version | string | SDK version |
| userId | string | Set user ID |
| group | ABTestGroup | null | A/B test group |
ABTestGroup Type
| Value | Description |
|---|---|
| monetai | Experimental group with automatic promotion |
| baseline | Control group without promotion |
| unknown | Users not included in campaign |
| null | When no current campaign exists |
3. Logging User Eventsβ
This is a critical step. Monetai's AI model relies entirely on the user events you log to analyze behavior and predict purchase intent. Without this data, the prediction feature will not function.
import MonetaiSDK from "@hayanmind/monetai-react-native";
// Basic event logging
await MonetaiSDK.logEvent({
eventName: "app_in",
});
// Event logging with parameters
await MonetaiSDK.logEvent({
eventName: "screen_in",
params: { screen: "home" },
});
- Log all in-app events. Monetai will automatically select events most relevant to non-payer prediction for training.
- If no events are logged, instrument events on key features or buttons, especially those that occur before a purchase.
Events logged before the SDK is initialized are queued and sent automatically once initialization is complete.
Important: Even with the same event name, different parameters create different events that the AI model recognizes separately. Using too many diverse parameter values can reduce model accuracy.
Best Practices:
- β
Good:
{ screen: "home" },{ button: "upgrade" },{ category: "premium" } - β Avoid:
{ timestamp: "2024-01-15T10:30:00Z" },{ userId: "user123" },{ sessionId: "abc123" }
Why? Parameters like timestamps, user IDs, or session IDs create unique events for each occurrence, making it difficult for the model to find patterns. Focus on parameters that represent user behavior categories rather than specific instances.
API Reference: MonetaiSDK.logEvent()
Parameters
| Parameter | Type | Description |
|---|---|---|
| eventName | string | Event name |
| params | object? | Event parameters (optional) |
Implementing Promotionsβ
π With the essential setup complete, this section dives into implementing the core promotion logic.
You'll learn how to trigger purchase predictions and use the results to display your custom promotional UI.
1. Predicting Purchasesβ
Call the predict() function at a key purchase decision moment within your app to predict whether a user is likely to make a purchase.
- To optimize the user experience and most clearly measure campaign performance, we strongly recommend calling the
predict()function at only one specific point in the user journey. - It's most effective to call it at the critical moment of hesitationβafter the user has recognized the product's value but is still deciding whether to purchase.
Depending on your app's characteristics, consider points like:- When the user navigates away from the full-price subscription page.
- When the user completes a core workflow or task.
- When the user attempts to access or use a premium feature.
import MonetaiSDK from "@hayanmind/monetai-react-native";
const predictUserPurchase = async () => {
try {
const result = await MonetaiSDK.predict();
console.log("Prediction result:", result.prediction);
console.log("Test group:", result.testGroup);
if (result.prediction === "non-purchaser") {
// When predicted as non-purchaser, offer discount
console.log("Predicted as non-purchaser - discount can be applied");
} else if (result.prediction === "purchaser") {
// When predicted as purchaser
console.log("Predicted as purchaser - discount not needed");
}
} catch (error) {
console.error("Prediction failed:", error);
}
};
API Reference: MonetaiSDK.predict()
Return Value
| Return Value | Type | Description |
|---|---|---|
| prediction | PredictResult | Prediction result |
| testGroup | ABTestGroup | A/B test group |
PredictResult Type
| Value | Description |
|---|---|
| non-purchaser | Predicted not to purchase |
| purchaser | Predicted to purchase |
| null | Cannot predict (before model creation or no active campaign) |
predict() Function- Multiple Calls
- When a promotion is already active from a previous
predict()call, callingpredict()multiple times will not start a new promotion. Only the same promotion information will be returned inonDiscountInfoChange.
- When a promotion is already active from a previous
- Restarting Promotions
- After a promotion period ends, calling
predict()again will start a new promotion if the user is still predicted as a non-paying user.
- After a promotion period ends, calling
- Handling Existing Subscribers
- If you do not want to provide promotions to users who are already on paid subscriptions, do not call the
predict()function for those users.
- If you do not want to provide promotions to users who are already on paid subscriptions, do not call the
2. Displaying Promotion UIβ
When predict() identifies a user as a non-paying user, the SDK delivers discount information via the MonetaiProvider. You can use this to display promotional UI to the user.
A. Quick Start with UI Templates (Recommended)β
Pass paywallConfig to MonetaiProvider. When predict() returns a non-purchaser and the discount is within its valid period, the banner/paywall will appear automatically.
Paywall UI templates are supported in React Native SDK 0.4.0 and above.
See available template styles and examples: UI Template Design Guide
import React, { useEffect, useState } from "react";
import MonetaiSDK, { MonetaiProvider } from "@hayanmind/monetai-react-native";
import { Button, View } from "react-native";
export default function App() {
const [isSubscriber, setIsSubscriber] =
useState(/* the customer's actual subscription status */);
const runPredict = async () => {
const result = await MonetaiSDK.predict();
console.log("Predict result:", result);
};
return (
<MonetaiProvider
paywallConfig={{
enabled: true,
isSubscriber, // Reflect the user's actual subscription status
locale: "en",
discountPercent: 50,
style: "highlight-benefits", // 'compact' | 'highlight-benefits' | 'key-feature-summary' | 'text-focused'
// Paywall price info (set per your business rules)
regularPrice: "$10.00",
discountedPrice: "$5.00",
// features are only needed for 'highlight-benefits' or 'key-feature-summary'
features: [
{
title: "All premium features",
description: "Unlock everything",
isPremiumOnly: true,
},
{
title: "Advanced analytics",
description: "Insights and detailed reports",
},
{ title: "Priority support", description: "24/7 customer support" },
],
// Optional: banner/paywall position & z-order
// Banner position offset from bottom (px)
bannerBottom: 20,
// iOS: adjust z-order when covered by other components
bannerZIndex: 1000,
paywallZIndex: 2000,
// Android: adjust z-order when covered by other components
bannerElevation: 8,
paywallElevation: 16,
// Callbacks
onPurchase: async (closePaywall) => {
// TODO: Trigger your purchase flow
// On success, close paywall and update subscriber state
closePaywall();
setIsSubscriber(true);
},
onTermsOfService: () => {
// TODO: Open Terms of Service
},
onPrivacyPolicy: () => {
// TODO: Open Privacy Policy
},
}}
>
<View>
<Button title="Run predict" onPress={runPredict} />
</View>
</MonetaiProvider>
);
}
PaywallConfig
| Key | Type | Required | Description |
|---|---|---|---|
| enabled | boolean | β | Enable automatic banner/paywall display |
| isSubscriber | boolean | β | Whether the user is a subscriber (hidden when true) |
| locale | string | β | Language code (e.g., en, ko) |
| discountPercent | number | β | Discount percentage (0-100) |
| style | 'compact' | 'highlight-benefits' | 'key-feature-summary' | 'text-focused' | β | Template style |
| regularPrice | string | β | Regular price label |
| discountedPrice | string | β | Discounted price label |
| features | Array<{ title: string; description: string; isPremiumOnly?: boolean }> | - | Only needed for 'highlight-benefits' or 'key-feature-summary' |
| bannerBottom | number | - | Bottom offset for the floating banner |
| bannerZIndex | number | - | iOS: z-index to avoid being covered by other components |
| bannerElevation | number | - | Android: elevation to avoid being covered by other components |
| paywallZIndex | number | - | iOS: z-index for the paywall |
| paywallElevation | number | - | Android: elevation for the paywall |
| onPurchase | (closePaywall: () => void) => void | - | Purchase button callback (call closePaywall() on success) |
| onTermsOfService | () => void | - | Terms of Service click callback |
| onPrivacyPolicy | () => void | - | Privacy Policy click callback |
B. Custom UI (Advanced)β
You can build your own promotion screen. The Monetai SDK provides the discount timing (startedAt and endedAt) and triggers the onDiscountInfoChange callback. Your app can use this information to implement the custom UI components.
The startedAt and endedAt values in the discount information indicate the valid period for the promotion. You should use these timestamps to:
- Show your promotion screen only during the valid period
- Hide the screen when the period expires
import MonetaiSDK, { MonetaiProvider } from "@hayanmind/monetai-react-native";
const App = () => {
const [discountInfo, setDiscountInfo] = useState(null);
const handleDiscountInfoChange = (newDiscountInfo) => {
setDiscountInfo(newDiscountInfo);
if (newDiscountInfo) {
// Update UI when discount info is available
const now = new Date();
const endTime = new Date(newDiscountInfo.endedAt);
if (now < endTime) {
// When discount is valid
showDiscountBanner(newDiscountInfo);
}
} else {
// When no discount info
hideDiscountBanner();
}
};
const showDiscountBanner = (info) => {
// Show discount banner logic
console.log("Show discount banner:", info);
};
const hideDiscountBanner = () => {
// Hide discount banner logic
console.log("Hide discount banner");
};
return (
<MonetaiProvider onDiscountInfoChange={handleDiscountInfoChange}>
{/* App components */}
{discountInfo && <DiscountBanner discountInfo={discountInfo} />}
</MonetaiProvider>
);
};
The onDiscountInfoChange callback is triggered both when the app starts and there's valid discount information and when a new discount is generated by a predict() call. Use it to update banners, prices, or other UI elements in real-time.
API Reference: MonetaiProvider
Props
| Props | Type | Description |
|---|---|---|
| children | ReactNode | Child components |
| onDiscountInfoChange | (discountInfo: DiscountInfo | null) => void | Discount info change callback |
DiscountInfo Type
| Property | Type | Description |
|---|---|---|
| startedAt | Date | Discount start time |
| endedAt | Date | Discount end time |
| userId | string | User ID |
| sdkKey | string | SDK key |
Managing User Stateβ
SDK Resetβ
Initialize the SDK when the user logs out.
import MonetaiSDK from "@hayanmind/monetai-react-native";
// When user logs out
const logoutUser = async () => {
try {
await MonetaiSDK.reset();
console.log("User logout completed");
} catch (error) {
console.error("User logout failed:", error);
}
};
Support
If you run into any trouble during the integration, don't hesitate to contact us at support@monetai.io.
Next Stepsβ
With the SDK setup complete, you're ready to create a model and launch a campaign: