← Back to ERP system builders

Skill · Version 1.0.0

Mobile purchases and RevenueCat

Connects store transactions and RevenueCat events to verified account entitlements and recoverable purchase states.

mobile-purchases-revenuecat

Team members using this skill

See how it helps

When is it useful?

Use when subscriptions must survive restores, account changes and delayed store events.

What does it help you do?

  • Verifies purchases server-side and finishes transactions appropriately.
  • Defines anonymous-user linking and restore-purchase behavior.
  • Deduplicates provider events and reconciles entitlement changes.

Try asking this

Test subscription restoration after reinstall, including account mismatch and a delayed cancellation notification. Restore a purchase under the original account and then a different one. Access follows verified ownership, while repeated store events cannot grant duplicate entitlements.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Mobile Purchases & RevenueCat Integration

Mobile in-app purchases (Apple App Store In-App Purchase / StoreKit 2, Google Play Billing Library and RevenueCat) operate under store-controlled billing engines: users can upgrade, downgrade, cancel, request refunds or share subscriptions via Family Sharing directly inside OS Settings while your app is closed.

1. Server-Side Verification & Transaction Finishing

  • Never unlock persistent backend entitlements solely from client-side purchase callbacks: always verify the signed transaction/purchase token on your backend (or via RevenueCat's server API/webhooks) before granting server-side entitlements.
  • Acknowledge / Finish Transactions Only After Server Persistence:
    • Google Play Billing: every purchase must be acknowledged within 3 days (acknowledgePurchase for subscriptions/non-consumables, consumeAsync for consumables), otherwise Google Play automatically refunds and revokes the purchase! Only acknowledge after your server has recorded the purchaseToken and granted the entitlement.
    • Apple StoreKit 2: verify the JWS (JSON Web Signature) Transaction signed by Apple (App Store Server API / root certificate chain) and call transaction.finish() only after server fulfillment succeeds.

2. Account Binding, Anonymous Users & "Restore Purchases"

Mobile store accounts (originalTransactionId on iOS, purchaseToken / obfuscatedAccountId on Android) are tied to the user's Apple ID or Google Play account, which may differ from the application's logged-in user account:

  • Pass obfuscated app user IDs: set appAccountToken (UUID) in StoreKit 2 and setObfuscatedAccountId in Google Play Billing (or Purchases.logIn(appUserId) in RevenueCat) so store server notifications map deterministically to your backend user.
  • Mandatory "Restore Purchases" Flow: App Store Review requires a visible "Restore Purchases" action that syncs store transactions and restores entitlements on a new device without charging the user again.
  • Account Transfer / Aliasing Policy: define clearly what happens when User A logs out on a device and User B logs in and taps "Restore Purchases" on the same Apple/Google store account (keep bound to original owner, transfer entitlement, or reject with a clear message).

3. Store Server Notifications & RevenueCat Webhooks

Handle real-time lifecycle events pushed by the stores or RevenueCat:

  • Apple App Store Server Notifications V2 (signedPayload JWS):
    • SUBSCRIBED, DID_RENEW, DID_CHANGE_RENEWAL_STATUS, DID_CHANGE_RENEWAL_PREF (upgrade/downgrade), DID_FAIL_TO_RENEW (check isInBillingRetryPeriod and gracePeriodExpiresDate), GRACE_PERIOD_EXPIRED, EXPIRED, REFUND (revoke access immediately), REVOKE (Family Sharing revoked).
  • Google Play Real-Time Developer Notifications (RTDN via Cloud Pub/Sub):
    • RTDN sends only a purchaseToken and notificationType (SUBSCRIPTION_PURCHASED, SUBSCRIPTION_RENEWED, SUBSCRIPTION_IN_GRACE_PERIOD, SUBSCRIPTION_ON_HOLD, SUBSCRIPTION_CANCELED, SUBSCRIPTION_EXPIRED, SUBSCRIPTION_REVOKED). Your backend must call purchases.subscriptionsv2.get in the Google Play Developer API to read the authoritative state and expiryTime.
  • RevenueCat Integration:
    • Verify the webhook Authorization header, deduplicate by event.id, and process INITIAL_PURCHASE, RENEWAL, CANCELLATION (keep access until expiration_at_ms!), UNCANCELLATION, BILLING_ISSUE, PRODUCT_CHANGE, EXPIRATION and TRANSFER.
    • Unify web (Stripe/Paddle) and mobile (App Store/Play Store) entitlements into your single internal Entitlement model so a user who subscribes on iOS gets immediate access on web and desktop.

Included files 1

  • SKILL.md