import { useEffect, useState } from 'react';
import Purchases, { CustomerInfo } from 'react-native-purchases';
import { Platform } from 'react-native';
const API_KEYS = {
ios: "appl_custom_key_here",
android: "goog_custom_key_here"
};
export function usePremiumStatus() {
const [isPremium, setIsPremium] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
const initPurchases = async () => {
try {
Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);
if (Platform.OS === 'ios' || Platform.OS === 'android') {
await Purchases.configure({ apiKey: API_KEYS[Platform.OS] });
const customerInfo = await Purchases.getCustomerInfo();
// 'premium' este ID-ul Entitlement-ului configurat în RevenueCat
setIsPremium(customerInfo.entitlements.active['premium'] !== undefined);
}
} catch (e) {
console.error("Eroare la inițializarea RevenueCat", e);
} finally {
setLoading(false);
}
};
initPurchases();
}, []);
return { isPremium, loading };
}Am integrat recent RevenueCat într-o aplicație Expo cu peste 12.000 de useri activi și cred că am salvat vreo 30% din timpul de dezvoltare pe partea de plăți. Dacă ai încercat vreodată să scrii de mână logică de StoreKit și Google Play Billing în React Native, știi că e o rețetă sigură pentru burnout. Astăzi îți arăt cum configurezi totul curat prin EAS Build și care sunt capcanele de care sigur te vei lovi la testare.
Adio Expo Go, salut EAS Build
Primul lucru pe care trebuie să-l înțelegi e că biblioteca react-native-purchases are cod nativ. Asta înseamnă că poți să uiți de Expo Go. Va trebui să folosești un Development Build rulezi pe un dispozitiv fizic sau emulator.
Eu am pierdut două ore la primul proiect încercând să înțeleg de ce nu se inițializa SDK-ul într-un emulator simplu. Răspunsul e simplu: Expo Go nu are cum să ruleze bridge-ul nativ de la RevenueCat. Fă-ți un serviciu și rulează direct:
npx eas build --profile development --platform ios (sau android)
Setup-ul de Store-uri (Unde începe durerea reală)
La Apple e relativ simplu. Generezi un App-Specific Shared Secret în App Store Connect, configurezi produsele și le pui în dashboard-ul RevenueCat.
La Google, în schimb, e teroare birocratică. Trebuie să creezi un Service Account în Google Cloud Console, să-i dai drepturi de "View Financial Data" și "Manage Orders" în Google Play Console, apoi să descarci cheia JSON și să o urci în RevenueCat.
Am pățit o chestie extrem de frustrantă: API-ul Google dădea erori de autentificare timp de vreo 36 de ore după ce am creat cheia API. Nu e vina ta, sistemele lor interne se propagă incredibil de greu. Dacă primești erori 401/403 la început, deși ești sigur că ai pus drepturile corect, lasă-l să se "coacă" o zi înainte să începi să ștergi și să refaci cheile.
Testarea în Sandbox (Unde se rupe filmul)
Pe iOS, testarea se face super ușor cu un cont de Sandbox creat în App Store Connect. Intri pe telefon în Settings -> App Store -> Sandbox Account și te loghezi acolo. Nu te loga în iCloud-ul principal cu contul de sandbox că o să-ți strici backup-urile.
Pe Android, ai nevoie de "License Testing". Adaugă adresa ta de Gmail în lista de testeri autorizați din Google Play Console (la Setup -> License Testing), altfel Google îți va debita cardul real în timpul testelor.
Un detaliu genial la sandbox: pe Android, abonamentele sunt accelerate. Un abonament de o lună expiră în 5 minute și se reînnoiește automat de maxim 6 ori. E perfect ca să testezi dacă hook-ul tău de React Native reacționează corect când userul își pierde accesul premium.
Trade-off-ul sincer
RevenueCat e gratuit până la 10.000$ încasări lunare (tracked revenue). După aceea, îți iau în jur de 1%. Pentru un startup la început, e un no-brainer total.
Dacă ajungi să faci peste 50k$ pe lună, s-ar putea ca acel 1% să doară și să te gândești să-ți scrii propriul backend de validare a chitanțelor. Dar până acolo, timpul economisit cu gestionarea webhook-urilor de refund, upgrade, downgrade și cross-grade de pe două platforme diferite merită fiecare cent.
Voi cum gestionați plățile in-app în proiectele voastre de React Native? Ați rămas pe soluții custom sau ați externalizat totul?