rc-backend
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBackend Architecture with RevenueCat
使用RevenueCat构建后端架构
You do not build a receipt verification server with RevenueCat. Your backend still has a role, but that role is consuming RevenueCat state, not validating Google Play purchase tokens.
你无需基于RevenueCat构建收据验证服务器。你的后端仍有其作用,但该作用是获取RevenueCat的状态,而非验证Google Play购买令牌。
Phase 1: Discovery
阶段1:探索
RevenueCat's backend is the receipt verification server. When the Android SDK posts a purchase token, RevenueCat's backend:
- Calls or
purchases.subscriptionsv2.getagainst the Google Play Developer API.purchases.products.get - Validates the receipt is genuine and matches the expected product.
- Records the transaction in its database.
- Returns to the SDK.
CustomerInfo
Your Android app never calls the Google Play Developer API. Your server does not call it either.
Before writing any backend code, confirm these facts about your deployment:
- You have a RevenueCat project with an Android app configured.
- You have a secret API key from Project Settings to API Keys (not the public Android SDK key embedded in the app).
- You know which your SDK uses (the same identifier your auth system uses).
app_user_id - You have decided whether the backend needs real time state (REST API) or event driven state (webhooks).
If your app only gates features inside the client, you may not need a backend component at all. RevenueCat verifies server side before it reaches the SDK, and or adds signature verification on the client. Serve premium content from a server only when you can verify entitlement on the server.
CustomerInfoEntitlementVerificationMode.INFORMATIONAL.ENFORCEDRevenueCat的后端就是收据验证服务器。当Android SDK提交购买令牌时,RevenueCat的后端会执行以下操作:
- 调用Google Play Developer API的或
purchases.subscriptionsv2.get接口。purchases.products.get - 验证收据的真实性,并确认其与预期产品匹配。
- 在数据库中记录该交易。
- 向SDK返回。
CustomerInfo
你的Android应用永远不会调用Google Play Developer API,你的服务器也不需要调用它。
在编写任何后端代码之前,请确认你的部署满足以下条件:
- 你拥有一个已配置Android应用的RevenueCat项目。
- 你从项目设置的API密钥页面获取了一个密钥API密钥(不是嵌入在应用中的公开Android SDK密钥)。
- 你知道SDK使用的(与你的认证系统使用的标识符相同)。
app_user_id - 你已确定后端需要实时状态(REST API)还是事件驱动状态(webhooks)。
如果你的应用仅在客户端内限制功能访问,那么你可能根本不需要后端组件。RevenueCat会在到达SDK之前进行服务器端验证,而或会在客户端添加签名验证。只有当你能在服务器端验证权益时,才从服务器提供付费内容。
CustomerInfoEntitlementVerificationMode.INFORMATIONAL.ENFORCEDPhase 2: Plan
阶段2:规划
Map each backend responsibility to a RevenueCat mechanism.
| Use case | Mechanism | Notes |
|---|---|---|
| React to purchase, renewal, cancellation | Webhook receiver | RevenueCat posts normalized events; your server updates its own DB. |
| Check current entitlement for a user | | Secret API key in |
| Grant promotional access (support, refunds, comps) | | Server side only. |
| Revoke promotional access | | Server side only. |
| Set subscriber attributes from server side data | | Useful for CRM fields the SDK does not know. |
| Bulk data export | RevenueCat data export | Scheduled exports to your warehouse. |
What your backend still owns:
- User authentication.
- Your database of users and their access levels.
- API endpoints that serve premium content.
- The webhook receiver that processes RevenueCat events.
What your backend does not own:
- Google Play Developer API credentials.
- Receipt verification code.
- chain traversal.
linkedPurchaseToken - Subscription state computation across the seven subscription states.
将每个后端职责映射到对应的RevenueCat机制。
| 使用场景 | 机制 | 说明 |
|---|---|---|
| 响应购买、续订、取消操作 | Webhook接收器 | RevenueCat会提交标准化事件;你的服务器更新自身数据库。 |
| 检查用户当前的权益 | | 在 |
| 授予推广访问权限(支持、退款、赠送) | | 仅支持服务器端调用。 |
| 撤销推广访问权限 | | 仅支持服务器端调用。 |
| 从服务器端数据设置订阅者属性 | | 适用于SDK无法获取的CRM字段。 |
| 批量数据导出 | RevenueCat数据导出 | 定期导出数据到你的数据仓库。 |
你的后端仍需负责:
- 用户认证。
- 用户及其访问级别的数据库。
- 提供付费内容的API端点。
- 处理RevenueCat事件的Webhook接收器。
你的后端无需负责:
- Google Play Developer API凭据。
- 收据验证代码。
- 链遍历。
linkedPurchaseToken - 七种订阅状态下的订阅状态计算。
Phase 3: Execute
阶段3:实施
Read a subscriber
读取订阅者信息
http
GET https://api.revenuecat.com/v1/subscribers/{app_user_id}
Authorization: Bearer sk_...
X-Platform: androidThe response body is the same structure the Android SDK returns. Use it in a server side endpoint that gates premium API responses.
CustomerInfohttp
GET https://api.revenuecat.com/v1/subscribers/{app_user_id}
Authorization: Bearer sk_...
X-Platform: android响应体与Android SDK返回的结构相同。可在限制付费API响应的服务器端端点中使用它。
CustomerInfoGrant a promotional entitlement
授予推广权益
http
POST https://api.revenuecat.com/v1/subscribers/{app_user_id}/entitlements/{entitlement_id}/promotional
Authorization: Bearer sk_...
Content-Type: application/json
{"duration": "monthly"}Valid values include , , , , , , , , . Use this for support workflows, never from the client.
durationdailythree_dayweeklymonthlytwo_monththree_monthsix_monthyearlylifetimehttp
POST https://api.revenuecat.com/v1/subscribers/{app_user_id}/entitlements/{entitlement_id}/promotional
Authorization: Bearer sk_...
Content-Type: application/json
{"duration": "monthly"}有效的值包括、、、、、、、、。此接口用于支持工作流,绝不能从客户端调用。
durationdailythree_dayweeklymonthlytwo_monththree_monthsix_monthyearlylifetimeExample: Kotlin Ktor call from your server
示例:你的服务器发起Kotlin Ktor调用
kotlin
val response = client.get("https://api.revenuecat.com/v1/subscribers/$appUserId") {
header("Authorization", "Bearer ${System.getenv("RC_SECRET_KEY")}")
header("X-Platform", "android")
}kotlin
val response = client.get("https://api.revenuecat.com/v1/subscribers/$appUserId") {
header("Authorization", "Bearer ${System.getenv("RC_SECRET_KEY")}")
header("X-Platform", "android")
}API key rules
API密钥规则
| Key | Where it lives | What it can do |
|---|---|---|
| Android public SDK key | Embedded in the Android app | Post purchases, fetch |
| Secret API key | Server environment variable only | Read any subscriber, grant or revoke promotionals, set attributes, bulk operations. |
Never ship the secret key in the Android APK, in a BuildConfig field, or in any client bundle. Rotate it if it leaks. Treat it like a database password.
| 密钥类型 | 存储位置 | 权限 |
|---|---|---|
| Android公开SDK密钥 | 嵌入在Android应用中 | 提交购买请求、获取当前用户的 |
| 密钥API密钥 | 仅存储在服务器环境变量中 | 读取任意订阅者信息、授予或撤销推广权限、设置属性、批量操作。 |
绝不要将密钥打包到Android APK、BuildConfig字段或任何客户端包中。如果密钥泄露,请立即轮换。将其视为数据库密码一样对待。
Webhook receiver outline
Webhook接收器示例
kotlin
post("/revenuecat/webhook") {
val auth = call.request.header("Authorization")
require(auth == "Bearer ${System.getenv("RC_WEBHOOK_SECRET")}")
val event = call.receive<RevenueCatEvent>()
when (event.type) {
"INITIAL_PURCHASE", "RENEWAL" -> grantAccess(event.appUserId, event.entitlements)
"CANCELLATION", "EXPIRATION" -> scheduleRevocation(event.appUserId)
}
call.respond(HttpStatusCode.OK)
}Verify the authorization header you configured in the RevenueCat dashboard. Respond 2xx fast; RevenueCat retries on non 2xx responses.
kotlin
post("/revenuecat/webhook") {
val auth = call.request.header("Authorization")
require(auth == "Bearer ${System.getenv("RC_WEBHOOK_SECRET")}")
val event = call.receive<RevenueCatEvent>()
when (event.type) {
"INITIAL_PURCHASE", "RENEWAL" -> grantAccess(event.appUserId, event.entitlements)
"CANCELLATION", "EXPIRATION" -> scheduleRevocation(event.appUserId)
}
call.respond(HttpStatusCode.OK)
}验证你在RevenueCat仪表板中配置的授权头。快速返回2xx响应;RevenueCat会对非2xx响应进行重试。
What not to build
无需构建的内容
- Do not build a Google Play receipt verification endpoint. RevenueCat already did.
- Do not pass purchase tokens from the Android client to your server for manual verification. The SDK handles the round trip.
- Do not query Google Play Developer API from your backend unless you are building a custom integration that bypasses the SDK.
- Do not mirror the seven subscription state machine in your DB. Consume or webhook events instead.
CustomerInfo.entitlements.active
- 不要构建Google Play收据验证端点。RevenueCat已经实现了该功能。
- 不要将购买令牌从Android客户端传递到你的服务器进行手动验证。SDK会处理这一往返流程。
- 除非你要构建绕过SDK的自定义集成,否则不要从后端调用Google Play Developer API。
- 不要在你的数据库中镜像七种订阅状态机。请使用或Webhook事件替代。
CustomerInfo.entitlements.active