Migrate from RevenueCat
Map RevenueCat concepts and SDK calls to Voidhash, and move your app over without losing subscribers.
This page maps RevenueCat's concepts and SDK calls to their Voidhash equivalents, then lists the steps specific to moving from RevenueCat. The overall plan, a parallel run followed by a switch behind a flag, is in Migrate to Voidhash.
Concepts
| RevenueCat | Voidhash | Notes |
|---|---|---|
| Project | Project | One per app, across platforms. |
| App (per store) | Payment provider (Help center) | App Store, Google Play, Stripe or a payment source, connected to the project. |
| Entitlement | Perk | Checked by slug, such as premium. |
| Product | Store product | Mapped to a Voidhash product. |
| Package | Product | What your app sells, such as pro_monthly. |
| Offering | Paywall location with a paywall | The location is the slug in your app; Studio decides which paywall it shows. |
| CustomerInfo | Person snapshot | Returned by getCurrentPerson(), with active perks and subscriptions. |
| App User ID | Distinct ID | Your user ID, passed to identify. |
| Anonymous App User ID | Anonymous distinct ID | Starts with vh_anon_. |
| Subscriber attributes | Person attributes | Set with setPersonAttributes. |
| Promotional offers | Offers | Mapped per store under one offer ID. |
| Experiments | A/B tests | Test paywalls at a location. |
| Webhooks | Webhook delivery | Signed; see Webhook events. |
| Observer mode | Observer mode | readOnly in Voidhash. |
SDK calls
RevenueCat names below are the Swift ones; the other RevenueCat SDKs use close equivalents.
| RevenueCat | Swift | Kotlin | React Native |
|---|---|---|---|
Purchases.configure(withAPIKey:) | Voidhash.configure(publishableKey:options:) | Voidhash.configure(context, publishableKey, options) | createVoidhashClient(publishableKey) |
logIn(_:) | identify(externalUserId:) | identify(externalUserId) | client.identify(userId) |
logOut() | signOut() | signOut() | client.signOut() |
customerInfo() | getCurrentPerson() | getCurrentPerson() | client.getCurrentPerson() |
entitlements["pro"]?.isActive | person?.hasActivePerk("premium") | person?.hasActivePerk("premium") | client.hasPerk("premium") or useHasPerk |
offerings() | getProducts() | getProducts() | useProducts() |
purchase(package:) | purchase(product:) | purchase(activity, product) | client.purchase(product) |
restorePurchases() | restorePurchases() | restorePurchases() | client.restorePurchases() |
syncPurchases() | syncPurchases() | syncPurchases() | client.syncPurchases() |
attribution.setAttributes(_:) | setPersonAttributes(_:) | setPersonAttributes(...) | client.setPersonAttributes(...) |
| Presenting a paywall | presentFlow(placement: "onboarding") | presentFlow(activity, "onboarding") | client.presentFlow("onboarding") |
Voidhash finishes a transaction only after it has recorded it, and the SDK refreshes the person after each purchase, so gate features on perks rather than on the purchase call returning.
Steps specific to RevenueCat
Rebuild the catalog
For each entitlement, create a perk. For each package, create a product, map it to the same App Store and Google Play products and attach its perks. Import products on the Products page lists the store products that aren't mapped yet. Recreate promotional offers as offers with the same IDs on both stores. See Products and perks.
Keep RevenueCat in charge, and observe
Ship the Voidhash SDK with readOnly on, next to RevenueCat, which keeps finishing transactions.
After each purchase RevenueCat completes, call reportTransaction with the App Store transaction
ID or Google Play purchase token. See Observer mode.
Use the same user IDs
Call identify with the same ID you pass to logIn. Anonymous RevenueCat IDs don't carry over;
anonymous buyers appear in Voidhash once their app reports their purchases.
Share store notifications
Point App Store Server Notifications at Voidhash and set Voidhash's forwarding URL to the URL RevenueCat gave you. On Google Play, add Voidhash's subscription to your existing Pub/Sub topic. See Store notifications.
Import Stripe history
If you sell through Stripe, set voidhash_distinct_id on existing Stripe customers and run the
Stripe history import (Help center). App Store and Google Play have
no history import: subscribers appear when they open a release with the Voidhash SDK, or when the
store sends a notification about them.
Move webhooks, then switch
Log Voidhash webhooks next to RevenueCat's, compare access for a sample of people, then move
purchase UI and transaction ownership to Voidhash behind one flag with setReadOnly(false).
Remove RevenueCat once the flag is at 100%.
Exactly one SDK must finish or acknowledge each transaction. Decide which from one flag, read before either SDK starts a purchase, and never let both, or neither, own purchases.
Next steps
- Migrate to Voidhash: the phased plan and timeline.
- Run in observer mode
- Go-live checklist
Something wrong or missing on this page? Tell us by email or on Discord.