import Purchases, { LOG_LEVEL } from 'react-native-purchases';
import { Platform } from 'react-native';
export const initRevenueCat = async (userId?: string) => {
Purchases.setLogLevel(LOG_LEVEL.DEBUG);
const apiKey = Platform.select({
ios: process.env.EXPO_PUBLIC_RC_IOS_KEY!,
android: process.env.EXPO_PUBLIC_RC_ANDROID_KEY!,
});
if (!apiKey) throw new Error('Missing RevenueCat API Key');
await Purchases.configure({ apiKey, appUserID: userId });
};
export const makePurchase = async (pkg: any) => {
try {
const { customerInfo } = await Purchases.purchasePackage(pkg);
return customerInfo.entitlements.active['pro'] !== undefined;
} catch (e: any) {
if (!e.userCancelled) {
console.error('Purchase error:', e.message);
}
return false;
}
};Am băgat recent RevenueCat pe o aplicație Expo cu peste 14.000 de useri activi și am salvat cel puțin 3 săptămâni de muncă pe backend. Dacă ai încercat vreodată să gestionezi singur webhook-urile de la Apple App Store Connect și Google Play Billing, știi deja ce coșmar sunt stările de renewal, grace period sau cancellation. În postarea asta îți zic exact unde te lovești când configurezi RevenueCat în Expo și ce capcane sunt la testing.
Setup-ul de console: Apple și Google te mănâncă de viu
Marea greșeală pe care o văd la mulți devi este că cred că RevenueCat le rezolvă totul din prima. În realitate, 80% din timp îl pierzi tot în consolele de la Apple și Google.
La Apple, până nu semnezi Paid Apps Agreement și nu completezi datele bancare și fiscale, SDK-ul îți va da erori generice de genul Invalid Product Identifiers. La Google Play Console, trebuie să creezi obligatoriu un Service Account în Google Cloud, să-i dai drepturi de Admin/Finance în Play Console și să legi cheia JSON în dashboard-ul RevenueCat.
A doua chestie critică pentru Expo: SDK-ul react-native-purchases nu merge în Expo Go. Ai nevoie neapărat de un Development Build făcut cu eas build --profile development. În app.json, adaugi plugin-ul react-native-purchases și faci rebuild la dev client. Dacă uiți pasul ăsta, te uiți 2 ore la ecran alb întrebându-te de ce nu se inițializează SDK-ul.
Structura din RevenueCat: Entitlements vs Offerings
În dashboard-ul RevenueCat, trebuie să înțelegi clar trei concepte ca să nu-ți prinzi urechile:
- Products: SKUs-urile brute din App Store / Google Play (ex:
sub_monthly_10usd). - Entitlements: Ce primește user-ul în app (ex: acces la feat-ul
pro). - Offerings: Grupul de pachete pe care le afișezi dinamic în Paywall.
Faza tare e că poți schimba prețul sau durata abonamentului din dashboard fără să modifici o linie de cod mobil. Aplicația cere Purchases.getOfferings() și primește automat pachetele curente configurate remote.
Capcane la Testing și Sandbox
Testing-ul pe iOS Sandbox e extrem de enervant dacă nu știi la ce să te aștepți. Abonamentele lunare expiră în 5 minute pe Sandbox, iar după 5 reînnoiri consecutive se anulează automat. Să nu crezi că e un bug din codul tău când vezi că s-a anulat abonamentul de test după 25 de minute.
Pe Android, trebuie să adaugi email-ul de test în License Testing în Google Play Console și să folosești un track intern (Internal Testing). Fără un build urcat în Internal Track, Google Play Billing API va returna eroare la orice încercare de achiziție.
Trade-off-ul direct cu RevenueCat? E moca până la $2,500 MRA (Monthly Realized Revenue), iar după aceea plătești 1%. Pentru mine, la un volum de $8k/lună pe un alt proiect, $80 pe lună au fost bani extrem de bine cheltuiți comparativ cu mentenanța unei infrastructuri proprii de validare a receipt-urilor.
Cum rezolvați voi sincronizarea stării de Pro pe backend-ul propriu? Trimiteți doar webhook-ul din RevenueCat către Node/Laravel sau verificați entitlement-ul direct din client?