如何用 Stripe 加入訂閱功能:方案、試用、Webhook 與付款失敗
要用 Stripe 加入訂閱功能,請在 Stripe 控制台中建立一個帶有定期價格的商品,從你的伺服器把顧客導向訂閱模式的 Stripe Checkout,並由 Webhook 告訴你的應用程式每一次付款何時成功、失敗、變更或結束。請把訂閱狀態儲存在使用者身上,並根據該狀態授予存取權限,而不是依據成功頁面。另外加入管理帳單按鈕,開啟 Stripe 代管的客戶入口網站,讓人們可以更換信用卡、切換方案和取消訂閱,而你不必自行建置這些畫面。
本指南建立在如何為應用程式加入付款功能的基礎上,該文涵蓋單次付款的 Checkout、測試模式與正式上線。這裡則聚焦於定期計費的不同之處。Stripe 的細節取自其截至 2026 年 9 月的官方文件。
為什麼訂閱比單次付款更難
單次付款發生在顧客仍在你的應用程式中時。訂閱則會在顧客離開後繼續運作:每個月續約、信用卡到期、週期中途升級、在週期結束時才生效的取消。你的應用程式只會透過 Webhook 得知這些事件。大多數訂閱相關的錯誤,都來自於把第一次付款當成全部的故事。
你的選擇
| 做法 | 你需要建置什麼 | 最適合 |
|---|---|---|
| 帶有定期價格的付款連結 | 只需要一個連結 | 測試需求;手動處理存取權限 |
| Checkout(訂閱模式)+ 客戶入口網站 | 一個伺服器路由、一個 Webhook、一個帳單按鈕 | 大多數 SaaS 應用程式與會員制 |
| 訂閱 API 搭配你自己的付款表單 | 多得多:付款介面、驗證、重試 | 有特殊計費流程的應用程式 |
| 商家代理人服務商 | 與 Checkout 相似 | 希望由服務商處理銷售稅的賣家 |
對大多數應用程式來說,Checkout 加上入口網站是合適的取捨。如果稅務處理讓你擔心,可以比較 Stripe vs Paddle vs Lemon Squeezy。
先在 Stripe 中規劃定價
在 Stripe 中,**商品(product)**是你販售的東西(「Pro 方案」),**價格(price)**則是收費方式(「每月 20 美元」、「每年 200 美元」)。一個商品可以有多個價格。請先決定:
- 你提供哪些等級,以及每個等級在你的應用程式中解鎖什麼
- 按月、按年,或兩者都提供
- 是否提供試用,以及試用是否需要先輸入信用卡
請在測試模式中建立商品和價格,並保存它們的價格 ID;你的應用程式會引用這些 ID。如果定價尚未確定,請閱讀如何為 SaaS 產品定價和免費增值與免費試用的比較。
你必須處理的訂閱生命週期
Stripe 的訂閱總覽列出了訂閱可能的狀態。以下是對存取權限最重要的幾種:
| 狀態 | 含義 | 是否授予存取權限 |
|---|---|---|
trialing | 處於試用期間 | 是 |
active | 狀況良好 | 是 |
incomplete | 首次付款尚未完成;Stripe 會給顧客 23 小時 | 否 |
incomplete_expired | 首次付款從未成功 | 否 |
past_due | 最近一次付款失敗或未嘗試;之後可能會重試 | 由你決定;許多應用程式會給予短暫的寬限期 |
unpaid | 重試已結束,發票保持未付款,不會再嘗試 | 否,Stripe 的文件建議撤銷存取權限 |
canceled | 已結束;無法重新啟動 | 否 |
paused | 試用結束時沒有付款方式,且設定為暫停 | 否 |
請把狀態儲存在使用者或帳戶紀錄上,並以此作為存取權限的依據。每次收到相關的 Webhook 時都要更新它。
需要處理的 Webhook 事件
| 事件 | 你的應用程式該做什麼 |
|---|---|
checkout.session.completed | 把新的 Stripe 顧客與訂閱 ID 連結到你的使用者 |
invoice.paid | 把訂閱標記為有效,並記錄新的期間結束時間 |
invoice.payment_failed | 告訴使用者信用卡失敗,並附上入口網站的連結 |
invoice.payment_action_required | 要求使用者完成信用卡驗證 |
customer.subscription.updated | 更新方案、狀態,以及任何已排定的取消 |
customer.subscription.deleted | 移除付費存取權限 |
customer.subscription.trial_will_end | 在試用結束前提醒使用者;Stripe 會在三天前發送 |
Stripe 的 Webhook 文件中的處理器規則仍然適用:使用原始內容驗證簽章、快速回傳 2xx、處理重複與順序錯亂的事件,並預期會有重試。什麼是 Webhook 解釋了這個概念,而付款指南則詳列了這些規則。
逐步執行
- 在 Stripe 測試模式中建立商品與價格。
- 加入 secrets:secret key、價格 ID,以及之後的 Webhook 簽署密鑰。絕不要放在前端程式碼中。
- 定價頁面:每個方案的按鈕會呼叫你的伺服器,由伺服器為已登入的使用者建立訂閱模式的 Checkout 工作階段。傳入你的使用者 ID,讓 Webhook 能把付款與帳戶對應起來。
- Webhook 端點:驗證簽章,並處理上述事件,每位使用者只更新一筆訂閱紀錄。
- 依儲存的狀態與方案限制功能,並且在伺服器上對每個受保護的動作進行檢查,而不只是隱藏按鈕。
- 客戶入口網站:在 Stripe 控制台中設定(允許顧客切換到哪些方案、是否可以取消),然後加入管理帳單按鈕,在伺服器上建立入口網站工作階段並導向該處。
- 付款失敗:在 Stripe 的帳單設定中,選擇重試行為,以及最後一次重試之後會發生什麼。在
past_due期間顯示應用程式內的提示橫幅。 - 測試整個生命週期,然後發布並註冊正式環境的 Webhook。
交給 AI 建置工具的提示詞
用 Stripe 加入訂閱計費。方案:Starter(價格 ID 放在 STRIPE_PRICE_STARTER)和 Pro(STRIPE_PRICE_PRO)。定價頁面在伺服器上使用 STRIPE_SECRET_KEY 建立訂閱模式的 Checkout 工作階段,並附上已登入使用者的 ID。把 Stripe 顧客 ID、訂閱 ID、方案與狀態儲存在使用者身上。絕不要把 secret key 暴露給瀏覽器。
新增 POST /api/stripe/webhook。使用原始請求內容並以 STRIPE_WEBHOOK_SECRET 驗證簽章。處理 checkout.session.completed、invoice.paid、invoice.payment_failed、customer.subscription.updated、customer.subscription.deleted 和 customer.subscription.trial_will_end。記錄已處理的事件 ID,讓重複事件被忽略。根據訂閱物件更新使用者的狀態,而不是根據事件抵達的順序。
只有在狀態為 active 或 trialing,且方案為 Pro 時,才在伺服器上允許使用 Pro 功能。當狀態為 past_due 時,顯示「付款失敗,請更新信用卡」的橫幅。加入「管理帳單」按鈕,為此使用者開啟 Stripe 客戶入口網站。
升級、降級與按比例計費
當顧客切換方案時,Stripe 的文件說明,變更通常會產生按比例計費(proration):新價格會套用到當前計費週期的剩餘時間。你可以預覽按比例計費的結果,或將其關閉。如果兩個方案的計費週期相同,計費日期保持不變;從按月改為按年,則計費日會移到切換當天。讓顧客在入口網站中變更方案可以省去你撰寫這套邏輯的工作,但你需要在入口網站設定中決定允許哪些切換。
測試檢查清單
請使用 Stripe 測試模式與測試卡,逐一走過每一種狀態:
- 新訂閱會把正確的方案授予正確的使用者
- 付款後立即關閉分頁,仍然能取得存取權限(證明 Webhook 有效)
- 註冊時信用卡被拒絕,不會授予任何權限
- 失敗的續約會讓帳戶進入 past_due,並顯示提示橫幅
- 在入口網站更新信用卡後,狀態恢復為 active
- 升級與降級會正確變更功能
- 在週期結束時取消,會保留存取權限直到結束日期,然後移除
- 試用使用者能取得存取權限、收到提醒,並正確地轉為付費或失去存取
- 同一個 Webhook 事件送達兩次,不會產生任何變化
Stripe 的測試時鐘可以模擬時間流逝,讓你不必等待一個月就能測試續約。請查閱 Stripe 目前的測試文件,了解如何使用它們。
常見錯誤
- **在成功頁面上授予存取權限。**顧客可能已付款,卻從未抵達該頁面。請使用 Webhook。
- **只處理第一次付款。**續約、失敗與取消會以事件的形式在之後抵達。
- **只在前端檢查方案狀態。**任何人都可以直接呼叫你的 API。
- **不小心讓同一位使用者擁有多筆訂閱。**在建立新的 Checkout 工作階段之前,先檢查是否已有訂閱,或直接把既有顧客導向入口網站。
- **第一次續約失敗就撤銷存取權限。**信用卡失敗的原因通常很平凡。短暫的寬限期加上清楚的提示橫幅,能留住顧客。
- **忘了正式環境的 Webhook。**測試與正式環境的端點有不同的簽署密鑰。
- **忽略稅務與退款。**在上線前決定退款政策,並請會計師確認你的稅務義務。
Mythex 中的訂閱功能
在 Mythex 上建置的應用程式使用的是你自己的 Stripe 帳戶與金鑰;你的應用程式沒有一鍵連接 Stripe 的功能。把測試金鑰與價格 ID 加入專案 secrets,使用上面類似的提示詞,並在預覽中用 Stripe 測試卡測試。Webhook 需要你應用程式的公開網址,因此請先發布,再在 Stripe 中註冊端點;切換到正式金鑰後,再次發布,讓正式應用程式套用這些金鑰。請參閱使用 Stripe 接受付款和在後端處理 Webhook。若想了解整個產品的其他部分,如何建置 SaaS MVP說明了計費之外還需要建置什麼。
常見問題
用 Stripe 加入訂閱功能,最簡單的方法是什麼?
在 Stripe 控制台建立一個帶有定期價格的商品,把顧客導向訂閱模式的 Stripe Checkout,用 Webhook 處理訂閱事件,並把「管理帳單」按鈕連結到 Stripe 代管的客戶入口網站。這樣你就不必自行建置信用卡表單和方案變更畫面。
訂閱功能需要哪些 Stripe Webhook 事件?
至少需要:checkout.session.completed,用來把新訂閱連結到你的使用者;invoice.paid,用來確認每一次成功的付款;invoice.payment_failed,用來提醒續約失敗;以及 customer.subscription.updated 和 customer.subscription.deleted,用來追蹤方案變更與取消。
訂閱付款失敗時會發生什麼事?
根據截至 2026 年 9 月 Stripe 的文件,訂閱通常會變為 past_due,而 Stripe 可以依你的設定重試付款。在最後一次重試之後,你在控制台中的設定會決定它是被取消、標記為 unpaid,還是維持 past_due。
我可以提供免費試用,又不要求先輸入信用卡嗎?
可以。Stripe 支援免費試用,其文件也說明,若如此設定,試用結束時仍未提供付款方式的情況可以進入 paused 狀態。預先收集信用卡通常會使註冊人數減少,但付費客戶會增加;請測試哪種方式最適合你的產品。