rc-understanding-revenuecat

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Understanding RevenueCat

了解RevenueCat

Phase 0: Intent

阶段0:目的

Use this skill before writing any RevenueCat code. It gives you the vocabulary and mental model you need so that downstream skills (setup, configuration, purchase flow, entitlements) make sense.
Start here if any of these apply:
  • You are new to RevenueCat or coming from a raw Play Billing integration.
  • You are unsure which concept maps to which dashboard object.
  • You need to decide which downstream skill to invoke for a specific user goal.
Skip this skill if you already know the difference between an Offering, a Package, a Product, and an Entitlement, and you already know that
Purchases.sharedInstance
is the single entry point.
在编写任何RevenueCat代码前使用此技能。它会为你提供所需的术语和思维模型,让后续技能(设置、配置、购买流程、权限)的内容更容易理解。
如果符合以下任一情况,请从本技能开始:
  • 你是RevenueCat新手,或是从原生Play Billing集成转来的。
  • 你不确定某个概念对应控制台中的哪个对象。
  • 你需要根据特定的用户目标决定调用哪个后续技能。
如果你已经了解Offering、Package、Product和Entitlement之间的区别,并且知道
Purchases.sharedInstance
是唯一入口,则可以跳过本技能。

Phase 1: Orient

阶段1:架构梳理

Raw Android in-app purchases require three separate systems. RevenueCat folds all three into one SDK plus one dashboard.
Raw Google Play stackRevenueCat replacementWhere it lives
BillingClient
on the client
Purchases
SDK
Your Android app
Google Play Developer API on your serverRevenueCat backendRevenueCat managed
Real Time Developer Notifications via Cloud Pub/SubRevenueCat webhooksRevenueCat managed, delivered to your server
The call path is:
text
Your App
  -> Purchases SDK
  -> RevenueCat Backend
  -> Google Play Developer API
  -> Google Play
Your app talks to the
Purchases
SDK. The SDK talks to Google Play for the purchase UI and to the RevenueCat backend for verification and entitlement storage. Your server side code talks to the RevenueCat backend, not to Google Play directly.
One consequence: RevenueCat sits in the purchase verification path. After a user completes a purchase, the SDK posts the token to RevenueCat before your app sees confirmation. You trade a network round trip for not having to build server side verification yourself.
原生Android内购需要三个独立的系统。RevenueCat将这三者整合为一个SDK加一个控制台。
原生Google Play栈RevenueCat替代方案部署位置
客户端的
BillingClient
Purchases
SDK
你的Android应用
服务器端的Google Play Developer APIRevenueCat后端RevenueCat托管
通过Cloud Pub/Sub实现的Real Time Developer NotificationsRevenueCat webhooksRevenueCat托管,推送到你的服务器
调用路径如下:
text
Your App
  -> Purchases SDK
  -> RevenueCat Backend
  -> Google Play Developer API
  -> Google Play
你的应用与
Purchases
SDK通信。SDK会与Google Play交互处理购买UI,同时与RevenueCat后端交互进行验证和权限存储。你的服务器端代码直接与RevenueCat后端通信,而非Google Play。
由此带来的一个结果是:RevenueCat会介入购买验证流程。用户完成购买后,SDK会先将令牌发送给RevenueCat,之后你的应用才会收到确认信息。你需要付出一次网络往返的代价,但无需自行构建服务器端验证逻辑。

The four concepts you must know

你必须掌握的四个核心概念

ConceptWhat it isWhere you define it
ProductA subscription, base plan, or one time purchaseGoogle Play Console
PackageA Product wrapped with a type label (Monthly, Annual, Lifetime, custom). The unit your paywall displaysRevenueCat dashboard
OfferingA group of Packages. One Offering is marked Current and returned by
offerings.current
RevenueCat dashboard
EntitlementA logical access level your app checks, such as
"pro_access"
. Products are attached to Entitlements
RevenueCat dashboard
CustomerInfo
is the runtime snapshot of the user's purchase history and active Entitlements, computed and cached by RevenueCat.
概念定义定义位置
Product订阅、基础套餐或一次性购买项目Google Play Console
Package带有类型标签(月度、年度、终身、自定义)的Product,是付费墙展示的单元RevenueCat控制台
Offering一组Package的集合。其中一个Offering会被标记为Current,并通过
offerings.current
返回
RevenueCat控制台
Entitlement你的应用检查的逻辑访问级别,例如
"pro_access"
。Product会关联到Entitlement
RevenueCat控制台
CustomerInfo
是用户购买历史和当前激活Entitlements的运行时快照,由RevenueCat计算并缓存。

The only two reads you need most of the time

大多数情况下你仅需用到的两个读取操作

kotlin
val offerings = Purchases.sharedInstance.awaitOfferings()
val monthly = offerings.current?.monthly
kotlin
val customerInfo = Purchases.sharedInstance.awaitCustomerInfo()
val hasPro = customerInfo.entitlements["pro_access"]?.isActive == true
isActive
already resolves the seven Play subscription states (ACTIVE, IN_GRACE_PERIOD, ON_HOLD, PAUSED, CANCELED, EXPIRED, PENDING) on the server side. You do not reimplement that logic on the client.
kotlin
val offerings = Purchases.sharedInstance.awaitOfferings()
val monthly = offerings.current?.monthly
kotlin
val customerInfo = Purchases.sharedInstance.awaitCustomerInfo()
val hasPro = customerInfo.entitlements["pro_access"]?.isActive == true
isActive
已经在服务器端处理了Play订阅的七种状态(ACTIVE、IN_GRACE_PERIOD、ON_HOLD、PAUSED、CANCELED、EXPIRED、PENDING)。你无需在客户端重新实现该逻辑。

The singleton

单例模式

Purchases.sharedInstance
is the single entry point. You configure it once at app startup:
kotlin
Purchases.configure(
    PurchasesConfiguration.Builder(context, "your_api_key")
        .appUserID("optional_user_id")
        .build()
)
Unlike
BillingClient
, the singleton does not require you to manage connection state. It reconnects and queues calls for you.
Purchases.sharedInstance
是唯一入口。你只需在应用启动时配置一次:
kotlin
Purchases.configure(
    PurchasesConfiguration.Builder(context, "your_api_key")
        .appUserID("optional_user_id")
        .build()
)
BillingClient
不同,该单例无需你管理连接状态。它会自动重新连接并对调用进行排队。

What RevenueCat does not replace

RevenueCat不替代的内容

  • Google Play Console. You still create products, base plans, and offers there.
  • Your app UI. You still build the paywall and display prices. RevenueCat supplies the data.
  • Your authentication system. You bring your own user IDs and pass them to the SDK.
  • Google Play Console:你仍需在其中创建产品、基础套餐和优惠。
  • 应用UI:你仍需构建付费墙并展示价格。RevenueCat仅提供数据。
  • 认证系统:你需要使用自己的用户ID,并将其传递给SDK。

The tradeoff

权衡取舍

You offload verification complexity and take on a dependency. If the RevenueCat backend has an outage, purchase verification is affected. Two mitigations exist and they are different:
FeatureWhat it doesWhen it kicks in
Disk cache of
CustomerInfo
Returns the last known server state for entitlement checksAutomatic, always on
Offline EntitlementsComputes entitlements on the device from local Play Store purchasesOnly when you explicitly configure it
Neither is a full substitute for a reachable backend. Use both where they apply.
你将验证复杂度转移出去,但需要引入一个依赖。如果RevenueCat后端出现故障,购买验证会受到影响。目前有两种不同的缓解措施:
功能作用触发时机
CustomerInfo
磁盘缓存
返回权限检查的最后已知服务器状态自动启用,始终生效
离线权限根据本地Play Store购买记录在设备上计算权限仅当你显式配置时生效
两者都无法完全替代可访问的后端。请在适用场景中同时使用这两种措施。

Phase 2: Map the user goal to a downstream skill

阶段2:将用户目标映射到后续技能

Once you have the model above, pick the next skill based on what the user actually wants to do.
User goalNext skill
Install the SDK, wire up Gradle, add permissions, configure the Play Console product
rc-setup
Call
Purchases.configure
, pass an
appUserID
, set log level, attach attributes
rc-configuring-the-sdk
Fetch Offerings, show a paywall, call
purchase
, handle the result
rc-purchase-flow
Check
customerInfo.entitlements["..."]?.isActive
, gate features, listen for updates
revenuecat/entitlements-and-customerinfo
Identify, alias, or log out a user
revenuecat/user-identity
Handle restore purchases, cross device, promo codes
revenuecat/restore-and-recovery
Receive server side events from RevenueCat
rc-webhooks
Debug a specific purchase, receipt, or entitlement in production
revenuecat/debugging
If the user's goal does not match any row, stay here and keep clarifying intent before routing.
掌握上述模型后,请根据用户实际需求选择下一个技能。
用户目标后续技能
安装SDK、配置Gradle、添加权限、配置Play Console产品
rc-setup
调用
Purchases.configure
、传递
appUserID
、设置日志级别、附加属性
rc-configuring-the-sdk
获取Offerings、展示付费墙、调用
purchase
、处理结果
rc-purchase-flow
检查
customerInfo.entitlements["..."]?.isActive
、限制功能、监听更新
revenuecat/entitlements-and-customerinfo
用户识别、别名设置或登出
revenuecat/user-identity
处理恢复购买、跨设备、促销代码
revenuecat/restore-and-recovery
接收RevenueCat的服务器端事件
rc-webhooks
调试生产环境中的特定购买、收据或权限问题
revenuecat/debugging
如果用户目标与上述任何一行都不匹配,请留在本技能中,先明确用户意图再进行跳转。

Phase 3: Sanity check

阶段3:合理性检查

Before you leave this skill and route to a downstream one, confirm out loud:
  1. You can name which of the three raw pillars (client billing, server Play Developer API, RTDN) the user's question touches.
  2. You can state whether the user is asking about a Product, a Package, an Offering, or an Entitlement. These are not interchangeable.
  3. You know whether the user needs
    Offerings
    (what to sell) or
    CustomerInfo
    (what the user already owns). Most confusion comes from mixing these two.
  4. You have picked exactly one downstream skill to invoke next, or you have a concrete clarifying question.
If any of the four fail, reread Phase 1 or the chapter before proceeding.
在离开本技能并跳转到后续技能之前,请确认以下几点:
  1. 你能说出用户的问题涉及三个原生支柱(客户端计费、服务器端Play Developer API、RTDN)中的哪一个。
  2. 你能明确用户询问的是Product、Package、Offering还是Entitlement。这些概念不可互换。
  3. 你清楚用户需要的是
    Offerings
    (要售卖的内容)还是
    CustomerInfo
    (用户已拥有的内容)。大多数困惑都源于混淆这两者。
  4. 你已经选定了唯一一个后续技能,或者有明确的澄清问题。
如果以上任意一点不满足,请重新阅读阶段1或相关章节后再继续。

References

参考资料