React Native SDK
Install the SDK once. Configure billing recovery, cancel saves, and win back from the Redchurn dashboard. Copy, offers, and flow toggles update in your app within 60 seconds without a release.
Overview
The React Native SDK connects your app to Redchurn through a single API key. It registers your RevenueCat App User ID, syncs remote configuration, and renders native UI for three retention scenarios.
Everything visible to the subscriber (titles, messages, buttons, offers) is edited in the dashboard. The SDK polls for changes and updates automatically. You do not ship a new build to change copy.
- Cancel Save: intercept cancel taps with a native sheet
- Billing Recovery: in-app dunning when RevenueCat reports a billing issue
- Win back: reactivation prompt for churned subscribers
- Remote config: flows, copy, and offers controlled from the dashboard
Requirements
- React 18 or later
- React Native 0.72 or later (Expo supported)
- RevenueCat configured in your app with App User IDs
- @notifee/react-native optional, for local billing and win back notifications
Installation
Add the package to your project:
npm install @redchurn/react-native-sdk
# Optional: local notifications
npx expo install @notifee/react-nativeProvider setup
Wrap your app with RedchurnProvider. Get your SDK key from the Redchurn dashboard under Settings or during onboarding. Pass the RevenueCat App User ID so Redchurn can match subscribers to events.
import { RedchurnProvider } from "@redchurn/react-native-sdk";
export default function App() {
return (
<RedchurnProvider config={{
sdkKey: "rdchrn_live_xxxxxxxx",
rcAppUserId: user.revenueCatAppUserId,
}}>
<RootNavigator />
</RedchurnProvider>
);
}Setting the App User ID after login
If the RevenueCat App User ID is not available at app launch, set it after authentication:
import { useEffect } from "react";
import { useRedchurn } from "@redchurn/react-native-sdk";
function AuthBridge({ userId }: { userId: string }) {
const { setRCAppUserId } = useRedchurn();
useEffect(() => {
setRCAppUserId(userId);
}, [userId, setRCAppUserId]);
return null;
}Cancel Save
Replace your cancel button handler with startCancelFlow. Redchurn shows the save sheet with your configured offers before opening store cancellation UI.
import { useCancelFlow, CancelSaveSheet } from "@redchurn/react-native-sdk";
function SubscriptionSettings({ rcAppUserId }: { rcAppUserId: string }) {
const { startCancelFlow, sheetProps } = useCancelFlow({ rcAppUserId });
return (
<>
<Button title="Cancel subscription" onPress={startCancelFlow} />
<CancelSaveSheet {...sheetProps} />
</>
);
}Billing Recovery
When RevenueCat reports a billing issue, Redchurn shows a dunning banner inside your app on the next open. Add BillingRecoveryBanner near the root of your layout.
import { BillingRecoveryBanner } from "@redchurn/react-native-sdk";
function AppShell() {
return (
<>
<BillingRecoveryBanner />
<MainContent />
</>
);
}Win back
For churned subscribers who open your app again, WinBackPrompt displays your reactivation offer from the dashboard.
import { WinBackPrompt } from "@redchurn/react-native-sdk";
function AppShell() {
return (
<>
<WinBackPrompt />
<MainContent />
</>
);
}Remote configuration
After the SDK is installed, all subscriber-facing content is managed in the dashboard. Toggle flows on or off, edit copy, change offers, and update styling. Changes propagate within 60 seconds.
The SDK polls a lightweight /version endpoint every minute and only re-downloads configuration when something changed. You can also trigger a refresh when the app returns to foreground.
- In-app flows and copy: Dashboard → Scenarios → In-app
- Cancel offers: Dashboard → Cancel saves
- Email sequences: Dashboard → Scenarios → Email
- Branding and fallback CTA: Dashboard → Settings
Fail-safe behavior
The SDK never throws errors to your app. If Redchurn is unreachable, hooks become no-op and your app renders normally. If cancel tracking fails, the subscriber can still complete cancellation.
Use the onError callback to log non-fatal issues to Sentry or your monitoring tool.
- 12 second request timeout, no UI freeze
- Fail-open on cancel: user always reaches store if they insist
- Invalid SDK key: children render, hooks are no-op
- Unmount-safe: no state updates after component unmount
<RedchurnProvider config={{
sdkKey: "rdchrn_live_...",
debug: __DEV__,
onError: (error) => {
Sentry.captureMessage(`[Redchurn] ${error.code}: ${error.message}`);
},
}}>Production checklist
- RevenueCat webhook connected and delivering events
- SDK key from production environment (rdchrn_live_...)
- App User ID set for every authenticated subscriber
- Cancel button wired to useCancelFlow, not direct store link
- BillingRecoveryBanner and WinBackPrompt in root layout
- In-app copy and offers reviewed in dashboard before launch