> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# 設定 RevenueCat 購買

建立 RevenueCat 專案，關聯你的 App Store 和 Play 商品，接入校驗購買的 SDK 金鑰與服務端金鑰。

## 初學者演練

為什麼有這一節：Apple 和 Google 要求應用內數字購買走它們自己的計費——絕不走 Stripe Checkout——套件強制這條邊界。RevenueCat 架在兩家商店之上，一次整合覆蓋 iOS 和 Android：它跟蹤收據、訂閱和恢復，你的伺服器向 RevenueCat 詢問工作區是否已付款。

前提條件：移動端賬戶指南里的 Apple Developer Program（每年 99 美元）和 Google Play Console（一次性 25 美元）賬戶——商店商品必須先存在，RevenueCat 才能關聯——再加上一個真正用來測試的 EAS 開發構建，因為 Expo Go 根本跑不了原生購買模組。RevenueCat 免費檔夠測試用；商品上線前這裡的一切都不會扣款。

快速術語：RevenueCat 專案裝著你關聯到商店的應用。商品是在 RevenueCat 裡映象的商店物品。entitlement（權益）是訂閱有效期間 RevenueCat 授予的標記——預設 `pro`。Offering 把商品組合成應用展示的付費牆。公開 SDK 金鑰進移動端 env；API 金鑰和 webhook 授權值留在服務端。

你要建立的：一個專案、兩個關聯商店的應用、商品、一個權益、一個 offering——約一小時，大半在等商店商品設定。

[建立移動端賬戶](https://supastack.dev/zh-tw/docs/mobile/external-accounts.md)

[構建開發客戶端](https://supastack.dev/zh-tw/docs/mobile/eas-setup.md)


## 建立 RevenueCat 賬戶和專案

1. 開啟 [app.revenuecat.com](https://app.revenuecat.com) → 註冊，用你的產品名建立一個專案。

預期結果：空的專案儀錶板，帶 Apps、Products、Entitlements、Offerings 和 API keys 標籤頁——後面幾節按順序把它們填滿。


## 先建商店商品，再關聯兩個應用

RevenueCat 能引用之前，商店側的商品必須先存在。iOS：[appstoreconnect.apple.com](https://appstoreconnect.apple.com) → My Apps → 用你的 `ios.bundleIdentifier` 建應用記錄 → In-App Purchases 或 Subscriptions → 建立你打算銷售的訂閱商品（測試期間可保持草稿）。Android：[play.google.com/console](https://play.google.com/console) → 建應用 → Monetize → Products → Subscriptions（或應用內商品）。

然後在 RevenueCat 內關聯兩者：Apps → New app。iOS 選 App Store，填 bundle id，並提供表單要求的 App Store Connect 憑據——每個欄位都鏈到 RevenueCat 自己的設定檔案。Android 選 Play Store，填包名，上傳 Play 服務賬號 JSON——連結的檔案帶你走完在 Google Cloud 中建立它的過程。

預期結果：兩個應用列在專案下，商店控制台顯示你的商品已存在——此階段草稿狀態沒問題。


## 商品、權益、offering

1. Products → New：每個商店商品建一個 RevenueCat 商品，並附上對應的 App Store 或 Play 商品 ID——ID 必須與控制台完全一致。

2. Entitlements → New：按 `REVENUECAT_ENTITLEMENT_ID` 命名——套件預設 `pro`——並附上授予它的商品。

3. Offerings → New：建一個 offering，加入指向你商品的包，標記為 Current——應用渲染付費牆時讀的是 `offerings.current`。

`REVENUECAT_ENTITLEMENT_KEY` 保持預設 `ai.reference-task`：這是套件內部的賬本鍵——與自帶 Web 方案授予的鍵相同——RevenueCat 訪問記錄在它名下。只有當你的產品方案鍵變化時才改名。


## 複製金鑰並註冊 webhook

Project → API keys 列出下面三種。各平臺的公開 SDK 金鑰（iOS 是 `appl_…`，Android 是 `goog_…`）進 `apps/mobile/.env.local`——它們標識應用、不帶消費許可權，`EXPO_PUBLIC_` 字首對它們是正確的。

API 金鑰（`sk_…`，v1 金鑰）和 webhook 授權值在 `apps/web/.env.local` 中僅限服務端——絕不 `EXPO_PUBLIC_`，絕不提交。伺服器用金鑰呼叫 RevenueCat 的訂閱者 API 來驗證每個工作區的購買狀態。

Webhook：RevenueCat → Integrations → Webhooks → URL 設為 `{APP_URL}/api/billing/webhook/revenuecat`，Authorization 標頭值設為任意你編的長隨機串——然後把完全相同的字串放進 `REVENUECAT_WEBHOOK_AUTHORIZATION`。套件逐字比對標頭，其餘一律拒絕，因此續費、取消和退款不用等下次開啟應用就能到達伺服器。

沙盒購買在生產之外自動放行；生產 env 裡的 `REVENUECAT_ALLOW_SANDBOX=true` 啟動時會被拒絕，所以上線後保持不設定。

```
# apps/mobile/.env.local
EXPO_PUBLIC_MOBILE_PURCHASES_PROVIDER=revenuecat
EXPO_PUBLIC_REVENUECAT_IOS_API_KEY=appl_…
EXPO_PUBLIC_REVENUECAT_ANDROID_API_KEY=goog_…

# apps/web/.env.local — server side
MOBILE_PURCHASES_PROVIDER=revenuecat
REVENUECAT_SECRET_API_KEY=sk_…
REVENUECAT_WEBHOOK_AUTHORIZATION=<the exact Authorization value set on the webhook>
REVENUECAT_ENTITLEMENT_ID=pro
REVENUECAT_ENTITLEMENT_KEY=ai.reference-task
```


## 用沙盒購買驗證

購買只在開發或生產構建內執行——Expo Go 完全沒有原生模組，所以這一步假設 `eas build --profile development` 已產出開發客戶端（EAS 指南負責構建它）。

1. 把開發構建裝到登入了沙盒賬戶的裝置或模擬器：iOS 用 App Store Connect → Users and Access → Sandbox Testers；Android 用 Play Console → license testing。

2. 在應用中開啟付費牆，用沙盒賬戶購買。預期結果：購買在沙盒中完成——不真的扣款——恢復購買可用，工作區權益顯示啟用，服務端記錄在 `ai.reference-task` 鍵下。

常見失敗：付費牆為空表示 offering 不是 Current 或商品沒關聯；裝置上購買失敗表示商店商品仍是草稿或登錯了沙盒賬戶；權益永不翻轉表示 `MOBILE_PURCHASES_PROVIDER`/`EXPO_PUBLIC_MOBILE_PURCHASES_PROVIDER` 關著，或 webhook Authorization 不匹配——RevenueCat 儀錶板列出每次 webhook 送達的狀態。

[在裝置上構建並驗證](https://supastack.dev/zh-tw/docs/mobile/builds.md)

[Web 結賬改用 Stripe](https://supastack.dev/zh-tw/docs/web/stripe-payments.md)


如果你想繼續完成設定，可以閱讀《[構建和裝置驗證](https://supastack.dev/zh-tw/docs/mobile/builds.md)》。


## 下一篇

[構建和裝置驗證](https://supastack.dev/zh-tw/docs/mobile/builds.md)
