mcpField
R
rc-revenuecat-api-quick-reference

rc-revenuecat-api-quick-reference

github.com/revenuecat开发76640 次安装1 天前更新
代码仓库

关于 rc-revenuecat-api-quick-reference

供 Android 开发者和后端工程师查阅 RevenueCat API 的参考指南,索引 Android SDK 操作与数据字段,并说明何时使用客户端 SDK 或 REST API。

主要功能

  1. 01区分 SDK 与 REST API 任务
  2. 02列出协程操作及签名
  3. 03梳理产品、方案与权益字段
  4. 04汇总购买错误代码
  5. 05提供常用 Kotlin 代码片段

适用场景

  1. 01查询购买操作的返回类型
  2. 02读取权益字段以控制访问
  3. 03为任务选择 SDK 或 REST API
  4. 04在 Android 代码中处理购买错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/revenuecat/ai-toolkit --skill rc-revenuecat-api-quick-reference

安装后在 Claude Code 中输入/rc-revenuecat-api-quick-reference确认已加载。

详细介绍

RevenueCat API 快速参考

阶段 0:意图

在编写 Android 代码或服务器逻辑时,如果需要快速查询 RevenueCat API 的相关接口,请使用此技能。你可以在这里查找并回答以下常见问题:

  • 哪个构建器选项可以控制给定的 Purchases.configure 行为?
  • awaitPurchase、awaitOfferings、awaitCustomerInfo、awaitRestore、awaitLogIn、awaitLogOut 的返回类型和签名是什么?
  • 如何读取 Offering、套餐、产品和权益字段?
  • 应该针对哪个 PurchasesErrorCode 进行分支处理?
  • 应该注册哪个监听器回调来获取 CustomerInfo 更新?

不要将此技能用于深入教程。需要分步指导或设计原理时,请使用针对特定功能的技能(购买流程、配置 SDK、错误处理、订阅状态)。

阶段 1:定位

在搜索表格之前,先判断要查询的是 SDK 接口还是 REST 接口。

使用 SDK(客户端,即 Android 应用代码):

  • 代码在 Android 应用内部运行,例如 Activity、ViewModel 或随应用打包的后台 Worker。
  • 你需要发起购买、恢复购买、读取缓存的 CustomerInfo、获取 Offerings、识别用户或将用户登出,或监听更新。
  • 你希望在 UI 中根据权益进行访问控制。

使用 REST API(服务器端):

  • 代码在你的后端、Webhook 处理程序、管理工具或定时任务中运行。
  • 你需要授予或撤销促销权益、覆盖订阅、查询其他服务中的订阅者、退款,或向其他系统发送事件。
  • 你正在与无法嵌入 SDK 的系统集成。

此技能中的表格逐字涵盖附录 A 中的 Android SDK 10.x 接口。如需了解 REST 端点路径、身份验证和负载,请参阅 revenuecat.com 上的完整附录,并结合后端和 Webhook 技能使用;此文件仅作为 SDK 索引。

阶段 2:参考表

SDK 初始化
// Minimum setup
Purchases.configure(
    PurchasesConfiguration.Builder(context, "api_key").build()
)

// Full options
Purchases.configure(
    PurchasesConfiguration.Builder(context, "api_key")
        .appUserID("user_id")                    // null for anonymous
        .showInAppMessagesAutomatically(true)    // default: true
        .purchasesAreCompletedBy(PurchasesAreCompletedBy.REVENUECAT) // default
        .entitlementVerificationMode(EntitlementVerificationMode.INFORMATIONAL)
        .diagnosticsEnabled(false)               // default: false
        .pendingTransactionsForPrepaidPlansEnabled(false) // default: false
        .build()
)

Purchases.logLevel = LogLevel.DEBUG // before configure()
核心操作(协程)
// Fetch offerings
val offerings: Offerings = Purchases.sharedInstance.awaitOfferings()

// Fetch specific products
val products: List<StoreProduct> = Purchases.sharedInstance.awaitGetProducts(
    listOf("product_id"),
    type = ProductType.INAPP // or SUBS, or null for all
)
// Purchase
val result: PurchaseResult = Purchases.sharedInstance.awaitPurchase(
    PurchaseParams.Builder(activity, packageOrStoreProductOrSubscriptionOption).build()
)

// Purchase upgrade/downgrade
val result = Purchases.sharedInstance.awaitPurchase(
    PurchaseParams.Builder(activity, newPackage)
        .oldProductId("old_product_id")
        .googleReplacementMode(GoogleReplacementMode.WITH_TIME_PRORATION)
        .build()
)
// Get customer info
val customerInfo: CustomerInfo = Purchases.sharedInstance.awaitCustomerInfo()
val fresh: CustomerInfo = Purchases.sharedInstance.awaitCustomerInfo(
    fetchPolicy = CacheFetchPolicy.FETCH_CURRENT
)

// Restore
val customerInfo: CustomerInfo = Purchases.sharedInstance.awaitRestore()

// Log in / log out
val loginResult: LogInResult = Purchases.sharedInstance.awaitLogIn("user_id")
// loginResult.customerInfo, loginResult.created (Boolean)
val customerInfo: CustomerInfo = Purchases.sharedInstance.awaitLogOut()
Offering 结构
val offerings: Offerings
offerings.current          // current Offering
offerings.all              // Map<String, Offering>
offerings["my_offering"]   // by identifier
offerings.getCurrentOfferingForPlacement("placement_id") // targeting
val offering: Offering
offering.identifier
offering.monthly           // Package? (shortcut)
offering.annual            // Package?
offering.weekly            // Package?
offering.availablePackages // List<Package>
offering.metadata          // Map<String, Any>
val pkg: Package
pkg.identifier             // "$rc_monthly", "$rc_annual", custom
pkg.packageType            // PackageType enum
pkg.product                // StoreProduct
pkg.webCheckoutURL         // URL? (RevenueCat web billing)
val product: StoreProduct
product.productId
product.title
product.description
product.price.formatted    // "$4.99"
product.price.amountMicros
product.price.currencyCode
product.period             // Period? (null for INAPP); use period.iso8601 for "P1M", "P1Y", etc.
product.subscriptionOptions // List<SubscriptionOption>? (null for INAPP)
product.defaultOption       // SubscriptionOption? best available offer
权益
val customerInfo: CustomerInfo
customerInfo.entitlements.active         // Map<String, EntitlementInfo> (active only)
customerInfo.entitlements.all            // Map<String, EntitlementInfo> (all)
customerInfo.entitlements["pro_access"]  // EntitlementInfo?
customerInfo.activeSubscriptions         // Set<String> of "productId:basePlanId"
customerInfo.nonSubscriptionTransactions // List<Transaction>
customerInfo.managementURL               // Uri? to Play Store management
val entitlement: EntitlementInfo
entitlement.isActive                     // Boolean, the main access gate
entitlement.willRenew                    // false if canceled
entitlement.expirationDate               // Date? (null for lifetime)
entitlement.periodType                   // NORMAL, TRIAL, INTRO, PREPAID
entitlement.billingIssueDetectedAt       // Date? (non-null = grace/hold)
entitlement.unsubscribeDetectedAt        // Date? (non-null = canceled)
entitlement.store                        // PLAY_STORE, APP_STORE, etc.
entitlement.productIdentifier            // subscription product ID
entitlement.productPlanIdentifier        // base plan ID (Google only)
entitlement.verification                 // VerificationResult
错误处理
// Purchase errors
try {
    Purchases.sharedInstance.awaitPurchase(params)
} catch (e: PurchasesTransactionException) {
    e.userCancelled     // Boolean
    e.error.code        // PurchasesErrorCode
    e.error.message     // description string
}

// Other errors
try {
    Purchases.sharedInstance.awaitOfferings()
} catch (e: PurchasesException) {
    e.error.code        // PurchasesErrorCode
}
// Key error codes
PurchasesErrorCode.PurchaseCancelledError
PurchasesErrorCode.ProductAlreadyPurchasedError
PurchasesErrorCode.PaymentPendingError
PurchasesErrorCode.NetworkError
PurchasesErrorCode.StoreProblemError
PurchasesErrorCode.IneligibleError
PurchasesErrorCode.ConfigurationError
监听器
// CustomerInfo updates
Purchases.sharedInstance.updatedCustomerInfoListener =
    UpdatedCustomerInfoListener { customerInfo -> }

// Show in-app messages manually
Purchases.sharedInstance.showInAppMessagesIfNeeded(activity)

阶段 3:常见代码片段

根据权益控制功能的访问权限。

val info = Purchases.sharedInstance.awaitCustomerInfo()
val hasPro = info.entitlements["pro_access"]?.isActive == true
if (hasPro) unlockFeature() else showPaywall()

购买当前 Offering 中的月度套餐。

val current = Purchases.sharedInstance.awaitOfferings().current ?: return
val monthly = current.monthly ?: return
val result = Purchases.sharedInstance.awaitPurchase(
    PurchaseParams.Builder(activity, monthly).build()
)

区分取消操作和实际失败。

try {
    Purchases.sharedInstance.awaitPurchase(params)
} catch (e: PurchasesTransactionException) {
    if (e.userCancelled) return
    when (e.error.code) {
        PurchasesErrorCode.PaymentPendingError -> showPendingUi()
        PurchasesErrorCode.NetworkError -> showRetry()
        else -> showGenericError(e.error.message)
    }
}

服务器端授予权益后,强制重新获取 CustomerInfo。

val fresh = Purchases.sharedInstance.awaitCustomerInfo(
    fetchPolicy = CacheFetchPolicy.FETCH_CURRENT
)

登录已识别的用户并检测是否为首次登录。

val login = Purchases.sharedInstance.awaitLogIn("user_123")
val isNewAlias = login.created
val info = login.customerInfo

响应后台权益变更。

Purchases.sharedInstance.updatedCustomerInfoListener =
    UpdatedCustomerInfoListener { info ->
        val active = info.entitlements["pro_access"]?.isActive == true
        uiState.update { it.copy(hasPro = active) }
    }

参考资料

评论

支持 Markdown