Back to the RevenueCat homepage
RevenueCat SDKGoogle Play Billing

Chapter 9: Backend Architecture

Building purchase verification from scratch means standing up a server that calls the Google Play Developer API, manages service account credentials, validates receipts, grants entitlements, and protects against token reuse. It is a non-trivial backend service with Google Cloud credential management.

With RevenueCat, you do not build that backend.

What RevenueCat Replaces

RevenueCat's backend is your receipt verification server. After every purchase, the RevenueCat SDK posts the purchase token to RevenueCat's backend, which:

  1. Calls purchases.subscriptionsv2.get or purchases.products.get on the Google Play Developer API
  2. Validates the receipt is genuine and matches the expected product
  3. Records the transaction in RevenueCat's database
  4. Returns CustomerInfo to the SDK

Your app never calls the Google Play Developer API. Your server never calls it either, unless you are building a custom integration that bypasses the SDK entirely.

Your Backend's Role with RevenueCat

If you have a backend server, its billing-related responsibilities are:

  1. Receive RevenueCat webhooks (optional but recommended): RevenueCat sends normalized events for every purchase, renewal, cancellation, grace period, and expiry. Your server consumes these to maintain its own record of subscription state.
  2. Call the RevenueCat REST API (optional): Instead of calling the Google Play Developer API, you can call https://api.revenuecat.com/v1/subscribers/{app_user_id} to get the current CustomerInfo for any user. This is authenticated with your RevenueCat secret API key.
  3. Grant/revoke access in your own database: Based on webhook events or REST API responses, your server updates its own records. This is the same responsibility as before, but the trigger is a RevenueCat webhook instead of a Google Cloud Pub/Sub message.

The RevenueCat REST API

Your backend can check a user's entitlement status without calling Google:

kotlin
GET https://api.revenuecat.com/v1/subscribers/{app_user_id}
Authorization: Bearer {your_secret_api_key}

IMPORTANT

The secret API key is found under RevenueCat dashboard → Project Settings → API Keys. It is not the same as the Android public SDK key embedded in your app. Never include the secret API key in client-side code.

The response includes the same CustomerInfo structure the SDK returns. This is useful for server-side access decisions, for example, in an API endpoint that serves premium content.

Do You Still Need a Backend?

That depends on your app. If your app only needs to gate features inside the client app, you may not need any server-side component at all. RevenueCat's CustomerInfo on the client is verified server-side before it reaches your app, and the optional EntitlementVerificationMode.INFORMATIONAL or .ENFORCED setting adds cryptographic signature verification.

If your app serves premium content from a server, API responses, files, or data, you should verify entitlement on the server using RevenueCat webhooks or the REST API. Do not trust the client alone for server-side access decisions.

What You Still Own

  • Your user authentication system
  • Your database of users and their access levels
  • Your API endpoints that serve premium content
  • The webhook receiver that processes RevenueCat events

What you do not own:

  • Google Play Developer API credentials management
  • Receipt verification code
  • linkedPurchaseToken chain traversal
  • Subscription state computation across seven states

Prefer building from scratch?

The Google Play Billing Handbook covers the same topics with raw BillingClient, Developer API, and RTDNs.

Related chapters

  • Chapter 10: Webhooks

    One endpoint with normalized JSON events. No Cloud Pub/Sub configuration, no base64 decoding.

    Learn more
  • Chapter 15: Security

    Trusted Entitlements with built-in response signature verification. Choose from three modes.

    Learn more
  • Chapter 11: Subscription States

    Seven complex subscription states are resolved to just one simple boolean check: isActive.

    Learn more
Backend Architecture | RevenueCat