import Purchases, { PurchasesPackage } from 'react-native-purchases';
import { Platform } from 'react-native';
export const initRevenueCat = () => {
Purchases.setLogLevel(Purchases.LOG_LEVEL.DEBUG);
if (Platform.OS === 'ios') {
Purchases.configure({ apiKey: process.env.EXPO_PUBLIC_RC_IOS_KEY! });
} else if (Platform.OS === 'android') {
Purchases.configure({ apiKey: process.env.EXPO_PUBLIC_RC_ANDROID_KEY! });
}
};
export const buyPackage = async (pack: PurchasesPackage) => {
try {
const { customerInfo } = await Purchases.purchasePackage(pack);
if (customerInfo.entitlements.active['pro_access']) {
return true;
}
} catch (e: any) {
if (!e.userCancelled) {
console.error('Eroare la procesarea plății:', e.message);
}
}
return false;
};Dacă ai încercat vreodată să implementezi StoreKit 2 pe iOS și Google Play Billing pe Android direct din native modules, știi deja ce coșmar e menținerea infrastructurii de backend pentru validat chitanțe. Am trecut prin asta acum vreo doi ani la un proiect cu 12k de abonamente active și am pierdut 3 săptămâni doar depanând webhook-uri ratate de la Google. Cu react-native-purchases și RevenueCat schimbi ecuația radical, dar trebuie să fii foarte atent la setup-ul inițial.
Birocrația din App Store Connect și Google Play Console
Codul e partea cea mai ușoară, adevărata provocare e birocrația de configurare. Pe iOS, primul pas obligatoriu e să semnezi 'Paid Apps Agreement' în App Store Connect. Dacă nu faci asta, Purchases.getOfferings() îți va returna un array gol fără nicio eroare clară în consolă. Creezi produsele în store (de exemplu app_pro_monthly), iar în RevenueCat le asociezi cu un Entitlement (ex: pro_access).
Pe Android, treaba e un pic mai alambicată. Trebuie să creezi un Service Account în Google Cloud Console, să-i generezi o cheie JSON și să-i dai acces de 'Financial Manager' în Google Play Console. Fără legătura asta, RevenueCat nu poate verifica starea abonamentelor pe serverele Google.
Trade-off: RevenueCat vs In-House Revenue Infrastructure
Să fim sinceri cu privire la costuri. RevenueCat e gratuit până la $2,500 MRA (Monthly Realized Revenue), iar apoi plătești $1 pentru fiecare $1,000 procesați. La un MRR de $30,000 plătești în jur de $27 pe lună.
Pentru noi, balanța e clară: e mai ieftin să dai acei bani decât să plătești ore de server și timp de suport pentru un sistem propriu care să trateze cazurile de 'grace period', 'billing retry' sau 'cross-platform restore'. Totuși, dacă ai un volum uriaș cu margini mici de profit (de exemplu tranzacții unice de valoare mare), comisionul poate deveni deranjant.
Expo Dev Client și regulile pentru Sandbox
Nu încerca să testezi plăți în Expo Go. Nu va funcționa niciodată deoarece componentele native de In-App Purchase nu sunt incluse în clientul standard. Trebuie să generezi un build de dezvoltare folosind eas build --profile development și să-l instalezi pe un device fizic.
Pentru testarea pe iOS, creezi un cont de 'Sandbox Tester' în App Store Connect. Pe telefon, intri la Settings -> App Store -> Sandbox Account și te loghezi cu contul respectiv (NU te deloga de pe contul tău principal de Apple ID din rădăcina setărilor!). Pe Android e mai simplu: adaugi adresa de e-mail a testerului la License Testing în Google Play Console și tranzacțiile vor fi aprobat instant fără debita cardul.
Atât timp cât testezi pe un build nativ făcut cu EAS și ai mapat corect produsele din store în Entitlements, totul merge uns. Voi ce soluție folosiți pentru Paywalls dinamice fără să re-trimiteți build-ul în store?