RevenueCat

revenuecatPayments47 lines

In-app subscriptions and purchases across the App Store and Play Store.

Current — as published in v1.3.2. Written by hand for RevenueCat, not generated.

The rule

Access checks

  • Check entitlements, never product identifiers:
ts
  const isPro = info.entitlements.active['pro'] !== undefined;

Hardcoding a product id means every pricing change needs an app update.

  • Ask the SDK, do not trust local state. getCustomerInfo() is the source of truth; cached flags go stale after a refund, a cancellation or an expiry.
  • Access checks live in one service. Components ask that service, never the SDK.

Configuration

  • Purchases.configure() runs exactly once, at startup, before any other call.
  • Each platform gets its own public SDK key via Platform.select.
  • The secret API key is server-side only. It must never appear in the app, in an EXPO_PUBLIC_* variable, or in this repository.

Purchases

  • userCancelled is not an error. Check it before reporting or logging:
ts
  catch (error) {
    if (error.userCancelled) return;
    report(error);
  }
  • Restore purchases must be reachable from the UI. Apple rejects apps without it, and users need it after reinstalling.
  • Call Purchases.logIn(userId) after sign-in so entitlements follow the account rather than the device.

Never

  • Never grant access based on a local flag alone.
  • Never assume a purchase succeeded without checking the returned customerInfo.
  • Never put purchase logic in a component.
  • Never expect this to work in Expo Go — it is a native module, so it needs a development build.

As each tool receives it

The same guidance, in the shape each editor reads. Cursor and Claude Code are written separately by hand; the rest are derived from the Cursor rule.

.cursor/rules/revenuecat.mdchand-written for this tool
.cursor/rules/revenuecat.mdc
---
description: RevenueCat and in-app purchase conventions
globs: ["src/services/payments/**", "src/features/**/subscription*/**"]
alwaysApply: false
---

# RevenueCat

## Access checks

- Check **entitlements**, never product identifiers:

  ```ts
  const isPro = info.entitlements.active['pro'] !== undefined;
  ```

  Hardcoding a product id means every pricing change needs an app update.

- Ask the SDK, do not trust local state. `getCustomerInfo()` is the source of
  truth; cached flags go stale after a refund, a cancellation or an expiry.
- Access checks live in one service. Components ask that service, never the SDK.

## Configuration

- `Purchases.configure()` runs exactly once, at startup, before any other call.
- Each platform gets its own public SDK key via `Platform.select`.
- The **secret** API key is server-side only. It must never appear in the app,
  in an `EXPO_PUBLIC_*` variable, or in this repository.

## Purchases

- `userCancelled` is not an error. Check it before reporting or logging:

  ```ts
  catch (error) {
    if (error.userCancelled) return;
    report(error);
  }
  ```

- Restore purchases must be reachable from the UI. Apple rejects apps without
  it, and users need it after reinstalling.
- Call `Purchases.logIn(userId)` after sign-in so entitlements follow the
  account rather than the device.

## Never

- Never grant access based on a local flag alone.
- Never assume a purchase succeeded without checking the returned
  `customerInfo`.
- Never put purchase logic in a component.
- Never expect this to work in Expo Go — it is a native module, so it needs a
  development build.

What else this module writes

Selecting RevenueCat contributes more than a rule file — all of it merged with every other module you pick, with conflicts resolved rather than duplicated.

Environment
EXPO_PUBLIC_REVENUECAT_IOS_KEYrequiredPublic SDK key for the iOS app, from the RevenueCat dashboard.
EXPO_PUBLIC_REVENUECAT_ANDROID_KEYrequiredPublic SDK key for the Android app.
REVENUECAT_SECRET_KEYoptionalServer-side REST API key. Never ship this in the app.
Dependencies
react-native-purchases^10.6.0
Folders
src/features/subscriptions/screens/src/features/subscriptions/components/src/hooks/payments/src/services/payments/
Checklists
checklists/payments.md

Related

Put this in your repo

Adds RevenueCat to a project this tool generated, without starting over. Files you have hand-edited are left alone.