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-device purchases

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

RevenueCatEntitleHub
Project / AppProject (its id is your app_id)
EntitlementEntitlement (same idea; check the key)
ProductProduct, mapped to entitlements
Offering / Package/v1/offerings
app_user_idapp_user_id — identical; use your own stable user id
Public SDK keyPublishable key (pk_live_…)
Secret API keySecret key (sk_live_…)
CustomerInfoCustomerInfo (isActive, active, …)
WebhooksWebhooks (HMAC-signed)

Calls

RevenueCat SDKEntitleHub
Purchases.configure({apiKey, appUserID})new EntitleHub({apiKey: pk_…, appUserId})
Purchases.logIn / logOuteh.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 DBEntitleHub webhook → your DB (or read /v1/subscribers/{id} live)

A typical purchase flow

typescript
// 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()
Import your catalog automatically

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

  1. Set up your project, then Import your catalog from RevenueCat, grab keys, and add store credentials.
  2. Dual-write: on each purchase, report to EntitleHub in addition to RevenueCat, and compare entitlements for a week.
  3. Switch your app's reads to EntitleHub once they match.
  4. Drop the RevenueCat SDK; keep your billing library for the purchase sheet.