Migrating from RevenueCat
EntitleHub's model and SDK are intentionally close to RevenueCat's, so the move is mostly a rename and a re-point. This page maps the concepts and calls, and is honest about the one thing EntitleHub doesn't replace yet.
On Expo / React Native, @entitlehub/react-nativedrives the native StoreKit / Play Billing sheet and validates with EntitleHub in one call — a direct swap for RevenueCat's purchasePackage(). On other stacks, keep any billing library to open the sheet, then report the receipt to EntitleHub (see Purchases). EntitleHub replaces the whole backend: entitlements, server-side validation, state, webhooks.
Concepts
| RevenueCat | EntitleHub |
|---|---|
| Project / App | Project (its id is your app_id) |
| Entitlement | Entitlement (same idea; check the key) |
| Product | Product, mapped to entitlements |
| Offering / Package | /v1/offerings |
app_user_id | app_user_id — identical; use your own stable user id |
| Public SDK key | Publishable key (pk_live_…) |
| Secret API key | Secret key (sk_live_…) |
| CustomerInfo | CustomerInfo (isActive, active, …) |
| Webhooks | Webhooks (HMAC-signed) |
Calls
| RevenueCat SDK | EntitleHub |
|---|---|
Purchases.configure({apiKey, appUserID}) | new EntitleHub({apiKey: pk_…, appUserId}) |
Purchases.logIn / logOut | eh.logIn(id) / eh.logOut() |
getCustomerInfo() | eh.getCustomerInfo() |
customerInfo.entitlements.active["pro"] | info.isActive("pro") / info.active["pro"] |
getOfferings() | eh.getOfferings() |
purchaseStoreProduct() | your billing lib opens the sheet → server reportPurchase(...) |
restorePurchases() | billing lib restores → re-reportPurchase → re-read customer info |
| RC webhook → your DB | EntitleHub webhook → your DB (or read /v1/subscribers/{id} live) |
A typical purchase flow
// 1. App (client): open the native purchase sheet with your billing library.
const { purchaseToken } = await billing.purchase("app_pro_monthly");
// 2. App → your backend: send the token (never the secret key to the client).
await api.post("/iap/report", { productId: "app_pro_monthly", purchaseToken });
// 3. Your backend: validate + record via EntitleHub (secret key).
import { EntitleHubServer } from "@entitlehub/sdk";
const eh = new EntitleHubServer({ apiKey: process.env.ENTITLEHUB_SECRET_KEY! });
await eh.reportPurchase(userId, {
store: "play", storeProductId: "app_pro_monthly",
purchaseToken, isSubscription: true,
});
// 4. App: re-read entitlements (or wait for the webhook to update your DB).
const info = await eh.getCustomerInfo(); // client-side: eh.getCustomerInfo()Don't re-enter everything by hand. Dashboard → Import takes a RevenueCat v2 secret key + project id, reads your entitlements, products, and mappings, previews them, and creates them in EntitleHub. Read-only against RevenueCat.
Suggested cutover
- Set up your project, then Import your catalog from RevenueCat, grab keys, and add store credentials.
- Dual-write: on each purchase, report to EntitleHub in addition to RevenueCat, and compare entitlements for a week.
- Switch your app's reads to EntitleHub once they match.
- Drop the RevenueCat SDK; keep your billing library for the purchase sheet.
