products.ts

產品、方案、價格顯示和購買後授予的存取權限。

config/products.ts 匯出一個 Record<string, ProductConfig> 物件。第一層 Key 是產品 ID,每個產品的 plans 再以方案 ID 作為 Key。產品 ID 和方案 ID 都可以自行定義,saavo_starter、license、startup_monthly 等名稱只是範本示例。

必須替換 Price ID

預設範本中的六個 priceId 都以 _replace_me 結尾,只是占位值。啟用 Checkout 前,必須替換成目前 Stripe 帳號中實際存在的 Price ID。介面顯示的 salePrice 不參與扣款,實際金額和計費週期以 Stripe Price 為準。

產品 Key

產品 Key 必須是非空字串,可以依專案需求新增、刪除或修改。設定中既有的產品 Key 會組成 ProductId 聯集型別,沒有產品時可以匯出空物件。

產品物件

Prop

Type

plans

plans 儲存這個產品的方案,型別為 Record<string, PlanConfig>。方案 Key 必須是非空字串,不同產品可以使用不同的 Key。設定中既有的方案 Key 會組成 PlanIdOf<P> 和 PlanId 聯集型別。

方案物件

Prop

Type

訂閱方案欄位

type 為 recurring 時,還必須填寫下列欄位:

Prop

Type

features

方案賣點陣列,型別為 LocalizedText[]。介面依陣列中的順序顯示,不需要展示方案賣點時可以省略。

presentation

購買頁面的顯示設定,只影響公開產品頁面和購買頁面中的文案,不會改變價格、購買狀態或存取權限。

Prop

Type

purchaseFacts 是 LocalizedText[],用於填寫購買須知。specifications 是規格陣列,每個項目包含 label: LocalizedText、value: LocalizedText 和選用的 tone: "default" | "positive"。highlights 是特色卡片陣列,每個項目包含 icon、title 和 description,icon 可以填入 documentation、access、source 或 payment。

填寫 presentation 時,purchaseFacts、specifications 和 highlights 都必須填寫,陣列可以為空。

couponOffers

透過 /offer/:id 連結啟用的動態優惠活動陣列。填寫後至少要有一個項目。

Prop

Type

優惠活動也可以覆寫 features 和 presentation,格式與方案欄位相同。優惠活動不能修改 priceId、計費週期、購買狀態或存取權限,也不能巢狀包含其他優惠活動。

access

購買成功後授予的角色和權益。單次購買方案可以省略,訂閱方案則必須填寫,而且 roles 和 entitlements 中至少要有一個非空陣列。

roles

角色陣列。陣列項目可以直接填入角色 Key,也可以填入含有授予參數的物件。

Prop

Type

config 可以填入 priority: number、description: string、metadata: Record<string, unknown>,以及 effective.startsAt、effective.endsAt 兩個 Unix 毫秒時間戳記。

entitlements

權益陣列。單次購買方案可以直接填入權益 Key,也可以填入物件,訂閱方案則必須使用物件寫法。

Prop

Type

訂閱方案的權益物件必須填寫 config。

Prop

Type

kind 為 numeric 時,還可以填寫下列欄位:

Prop

Type

reset 用於設定額度重設週期。alignment: "calendar" 支援日、週、月、年,alignment: "fixed" 只支援日和週,count 必須是正整數。quotaUsedStrategy 可以填入 clear、drain、keep,也可以使用 { mode: "override", quotaUsed: number } 指定已用額度。

範本預設設定

範本預設設定只包含一個產品。表中的產品 ID 和方案 ID 都是示例,可以依業務需求替換。重新命名或清空產品前,必須同步處理頁面、購買流程、聯盟行銷、升級建議等引用,不能只修改這份設定,就認為功能仍然完整。

產品 IDname.valuename.key方案數量
saavo_starterSample SaaS subscriptioncomponents.billing.product.name6

description.value 為 Example monthly and yearly plans to replace with your product terms.,文案 Key 為 components.billing.product.description。

方案

方案 ID標題週期salePricepriceId標記
licenseHobby每月$19price_hobby_monthly_replace_medefault: true
hobby_yearlyHobby每年$190price_hobby_yearly_replace_me—
startup_monthlyStartup每月$49price_startup_monthly_replace_merecommended: true
startup_yearlyStartup每年$490price_startup_yearly_replace_merecommended: true
enterprise_monthlyEnterprise每月$149price_enterprise_monthly_replace_me—
enterprise_yearlyEnterprise每年$1,490price_enterprise_yearly_replace_me—

六個方案的 type 都是 recurring,intervalCount 都是 1,allowRepurchase 都是 false。三個年繳方案也填寫了「兩個月免費」的 valueHint。

存取權限

方案角色 Key權益 Key權益型別優先順序
license、hobby_yearlypremiumstarter_downloadboolean100
startup_monthly、startup_yearlypremiumstarter_downloadboolean200
enterprise_monthly、enterprise_yearlypremiumstarter_downloadboolean300

premium 和 starter_download 也只是範本預設設定中的示例 Key,分別來自 roles.ts 和 entitlements.ts。修改這些定義時,需要同步更新本檔案中的引用。