我是如何保證 SaaS 訂閲過期不漏處理的?1 層被動+ 2 層主動兜底

作者:桃與SaaS
日期:2026年4月1日 上午7:53
來源:WeChat 原文

整理版優先睇

速讀 5 個重點 高亮

SaaS訂閲過期點樣確保權限實收?三層防禦:Webhook + 定時巡檢 + 懶加載,漏一個都唔得。

整理版摘要

呢篇文章來自一個做SaaS支付嘅開發者,佢最近兩個月搞掂咗一個好實際嘅問題:訂閲到期點樣保證權限一定收返嚟,唔會漏。佢做嘅產品係 pay4saas,一個整合 StripePayPalCreem 嘅支付套件。作者想解決嘅係支付系統最易忽略嘅安全漏洞——訂閲狀態變更處理唔好,可能會令用戶仲有權限但冇俾錢,或者提早 cut 權限令俾咗錢嘅用戶嬲。佢嘅整體結論係,單靠Webhook唔夠穩,一定要疊加主動兜底機制,形成閉環。

文章先解釋點解被動層(Webhook)係基本盤,但唔係100%可靠,因為網絡抖動、服務器重啟、部署間隙都會導致事件丟失。然後佢提出兩層主動兜底:定時任務定時巡檢,同埋用戶訪問嗰嚇做懶加載即時修復。最後解釋三層點樣互補——Webhook覆蓋99%正常情況,定時任務補返漏網同埋用戶唔訪問嘅情況,懶加載做最後把關。成個設計嘅核心係「唔好悄悄地錯」:寧願多做幾步檢查,都唔好等對數先發現問題。

  • Webhook係被動主力,但唔可靠,要配合主動兜底先穩陣。
  • 定時巡檢唔止改狀態,仲要處理關聯數據,避免污染下游。
  • 懶加載即時校驗係最終防線,用戶一到就修正,零延遲。
  • 三層各自有短板,疊加先形成閉環Webhook + 定時 + 實時。
  • 做支付最怕唔係bug,而係悄悄錯咗你都唔知,所以要用兜底機制確保唔漏。
整理重點

被動層:Webhook — 等通知,但唔好信曬佢

訂閲過期呢件事,主動權唔喺我哋手。用戶喺 StripePayPalCreem 俾錢,續費、取消、到期全部由平台掌控。我哋只能等通知,即係 Webhook。每個平台喺狀態變更嗰嚇會送事件過嚟,收到就處理,收唔到就唔知。

但訂閲狀態遠比想像多:取消中、過期、續訂、逾期、升級、降級——每一種嘅事件類型都唔同,漏一個就有人蝕底。

  • 用戶取消咗但未到期(取消中)
  • 到期自動終止(過期)
  • 續費成功,週期刷新(續訂)
  • 付款失敗,入寬限期(逾期)
  • 升級立即生效
  • 降級下個週期生效

作者提醒,Stripe 嘅「到期取消」其實分兩步通知:先話你知用戶取消咗,再話你知週期完結真正終止。如果第一步就收權限,用戶會好嬲,因為佢呢個月係俾咗錢㗎。另外,三個平台嘅事件名及時序都唔同,統一處理係另一道坎。

整理重點

主動層:兩道兜底 — 定時巡檢 + 懶加載即時修復

第一道係定時任務巡檢。Webhook 丟咗,用戶又唔嚟訪問,數據庫狀態就會一直錯。唔單止數據唔準,仲會令活躍訂閲數虛高,影響決策,甚至搞亂下游嘅營銷郵件。所以週期性掃一次,將應該過期嘅過期,同時要處理關聯數據,唔可以只改狀態唔改其他。

定時巡檢嘅難位係:點樣確保唔誤殺正常續費?點樣一次過處理曬相關數據,唔搞亂數字?呢啲先係坑。

第二道係懶加載即時自愈。用戶訪問嗰嚇做實時校驗,如果發現數據唔啱就當場修正。用戶感覺唔到延遲,但狀態已經準確。呢個係最後防線,無論前面兩層點樣漏,用戶一到就必定正確。

實際上需要即時校驗嘅嘢遠超「訂閲有冇過期」——所有同時間相關嘅狀態變更都要檢。

整理重點

點解要三層,唔係一層?

支付呢家嘢唔可以賭。Webhook 被動,第三方唔通知就唔知;定時任務有延遲,兩次巡檢之間有窗口期;懶加載要等用戶上門。三層各有短板,但疊加一齊就形成閉環。

做支付系統最怕唔係出 bug,而係悄悄地錯,錯咗你都唔知,直到對數先發現唔啱。三層防禦嘅意義在於:無論邊個環節出問題,總有人兜底。

呢個就係 pay4saas 處理訂閲過期嘅完整思路:Webhook、定時任務、懶加載,三層疊埋,確保每個狀態變更都唔漏。

如果你都係做 SaaS 變現,唔想喺支付呢層踩坑,可以睇睇 pay4saas.cn,入面已經填好好多坑。

做 SaaS 支付,我哋最關注嘅往往係「點樣收到錢」。但真正令人瞓唔着嘅,係另一個問題——訂閲到期咗,點樣保證權限一定收得返嚟?

漏發積分,用戶會揾你。漏收權限,你自己蝕。兩邊都唔可以出錯㗎。

我呢兩個月,做支付嘅過程中,將呢個問題拆到好透。最終落地咗一套三層防禦,1 層被動 + 2 層主動兜底

今日就傾下,點解要咁做,同埋中間踩過嘅坑。

01

被動層,Webhook 通知

訂閲過期呢件事,主動權唔喺我哋手度。

用戶喺 Stripe/PayPal/Creem 付咗錢,續咗未續費、取消咗未取消、有冇到期——呢啲狀態變更,全部都係由支付平台掌控。我哋能夠做到嘅,就係等通知

呢個就係 Webhook 嘅角色,各個支付平台喺狀態變更嘅瞬間,向我哋伺服器發送一個事件。收到咗,就處理;冇收到,就唔知道。

聽落簡單,但訂閲嘅狀態遠比想像中多。

  • 用戶取消咗,但未到期(取消中)
  • 到期咗,自動終止(過期)
  • 續費成功咗,週期刷新(續訂)
  • 付款失敗咗,進入寬限期(逾期)
  • 升級咗,立即生效
  • 降級咗,下個週期生效

每一種狀態變更,支付平台發嘅事件類型都唔一樣。漏咗處理一個,後果,就唔講啦,總之總有一方蝕。

我最早喺呢度都翻過車。例如「到期取消訂閲」呢件事,Stripe 其實分兩步通知,第一步話畀我知「用戶發起咗取消」,第二步等週期結束先話畀我知「訂閲真正終止咗」。如果我喺第一步就收咗權限,用戶會好嬲——人哋呢個月係俾咗錢㗎。

呢兩步之間點樣處理,我試咗好幾版先至穩住。而且 Stripe、PayPal、Creem 三家嘅事件命名及時序都唔一樣,統一起嚟又係一道坎。

Webhook 係 99% 場景嘅主力。Stripe、PayPal 呢啲平台做咗好多年,可靠性好高,仲有自動重試機制。但——

佢唔係 100%。

網絡抖動、伺服器重啟、部署間隙、Supabase 間中超時……都可能導致 Webhook 遺失或處理失敗。機率好低,但喺 SaaS 入面,「好低」唔等於「唔會」。

所以,就需要做兜底啦。

02

主動層,兩道兜底

第一道,定時任務巡檢

Webhook 遺失咗,用戶又冇嚟訪問——呢種情況下,數據庫入面嘅狀態就一直係錯嘅。冇人通知,亦冇人觸發,訂閲永遠「有效」。

呢個仲唔止係「數據唔準」嘅問題。你嘅 dashboard 上面,活躍訂閲數係虛高嘅,你用呢個數據做決策就係呃緊自己。

更麻煩嘅係咩呢,如果系統入面有第二啲邏輯讀咗呢個狀態——例如發營銷電郵——全部跟住錯。一個漏網嘅過期訂閲,可以污染一串下游數據。

所以我加咗一層定時巡檢,週期性咁掃一次,將應該過期嘅過期咗佢。

聽落簡單,但真正做嘅時候會發現,淨係改狀態唔夠,關聯嘅數據都要一齊處理,否則下次用戶訪問時數字對唔上,其次,你統計收入嘅時候都對唔上數,係咪。

一次巡檢要處理幾多嘢、點樣保證唔會誤殺正常續費嘅訂閲——呢啲先係坑。

第二道,Lazy Load 即時自癒/修復

定時任務有延遲,Webhook 可能遺失。但有一個時刻係確定嘅——用戶嚟咗

用戶訪問嘅嗰一瞬間,我會做一次實時校驗。如果發現數據唔啱,當場修正。用戶感受唔到延遲,但狀態已經係準嘅啦。

呢個係最後一道防線。唔理前面兩層點樣漏,用戶嚟咗就一定會係準嘅。

而且實際做落會發現,需要喺呢個時刻校驗嘅嘢遠不止「訂閲有冇過期」一項。同時間相關嘅狀態變更,比你想象嘅多好多㗎。

03

點解係三層,唔係一層?

你可能會話,Webhook 咁穩定,搞到咁複雜做咩?

因為支付係唔可以賭嘅

Webhook 係被動嘅——第三方唔通知,我哋就唔知道。定時任務係有延遲嘅——兩次巡檢之間有窗口期。Lazy Load 係有前提嘅——用戶要嚟訪問。

三層各有短板,但組合埋一齊,就形成咗閉環。

層級
類型
觸發方式
覆蓋場景
Webhook
被動
支付平台推送
99% 正常情況
定時任務
主動
週期性巡檢
Webhook 遺失 & 用戶唔嚟
懶加載
主動
用戶訪問時檢查
最終防線,嚟咗就準

做支付系統最怕嘅唔係出 bug——bug 可以查可以修。最怕嘅係靜靜雞錯,錯咗你都唔知,直到某日對數發現數字對唔上。

三層防禦嘅意義唔在於佢哋每一層都成日被用到,而在於——唔理邊個環節出咗問題,總有站長兜底。

呢個就係我喺 pay4saas 入面處理訂閲過期嘅完整思路。Webhook、定時任務、Lazy Load,三層疊埋一齊,確保由訂閲到取消、由續費到過期,每一個狀態變更都唔會被漏咗。

如果你都喺做 SaaS 變現,唔想喺支付呢層踩坑,pay4saas.cn,更多嘅坑,都已經填好咗。令你放心收錢。

做 SaaS 支付,我們最關注的往往是「怎麼收到錢」。但真正讓人睡不着的,是另一個問題——訂閲到期了,怎麼保證權限一定收回來?

漏發積分,用戶會找你。漏收權限,你自己虧。兩頭都不能出錯啊。

我在這 2 個月,做支付的過程中,把這個問題拆透了。最終落地了一套三層防禦,1 層被動 + 2 層主動兜底

今天就聊一下,為什麼要這麼做,以及中間踩過的坑。

01

被動層,Webhook 通知

訂閲過期這件事,主動權不在我們手裏。

用戶在 Stripe/PayPal/Creem 付了錢,續沒續費、取沒取消、有沒有到期——這些狀態變更,全部由支付平台掌控。我們能做的,就是等通知

這就是 Webhook 的角色,各個支付平台在狀態變更的瞬間,給我們服務器發一個事件。收到了,處理;沒收到,就不知道。

聽起來簡單,但訂閲的狀態遠比想象的多。

  • 用戶取消了,但還沒到期(取消中)
  • 到期了,自動終止(過期)
  • 續費成功了,週期刷新(續訂)
  • 付款失敗了,進入寬限期(逾期)
  • 升級了,立即生效
  • 降級了,下個週期生效

每一種狀態變更,支付平台發的事件類型都不一樣。漏處理一個,後果,就不說了,反正總有一方虧。

我最早就在這裏也翻過車。比如「到期取消訂閲」這件事,Stripe 其實分兩步通知,第一步告訴我「用戶發起了取消」,第二步等週期結束才告訴我「訂閲真正終止了」。如果我在第一步就把權限收了,用戶會很生氣——人家這個月是付過錢的。

這兩步之間怎麼處理,我試了好幾版才穩住。而且 Stripe、PayPal、Creem 三家的事件命名和時序還都不一樣,統一起來又是一道坎。

Webhook 是 99% 場景的主力。Stripe、PayPal 這些平台做了很多年了,可靠性很高,還有自動重試機制。但——

它不是 100%。

網絡抖動、服務器重啓、部署間隙、Supabase 偶爾超時……都可能導致 Webhook 丟失或處理失敗。概率很低,但在 SaaS 裏,「很低」不等於「不會」。

所以,就需要做兜底了。

02

主動層,兩道兜底

第一道,定時任務巡檢

Webhook 丟了,用戶也沒來訪問——這種情況下,數據庫裏的狀態就一直是錯的。沒人通知,也沒人觸發,訂閲永遠「有效」。

這還不只是「數據不準」的問題。你的 dashboard 上,活躍訂閲數是虛高的,你拿這個數據做決策就是在騙自己。

更麻煩的是什麼呢,如果系統裏有別的邏輯讀了這個狀態——比如發營銷郵件——全都跟着錯。一個漏網的過期訂閲,能污染一串下游數據。

所以我加了一層定時巡檢,週期性地掃一遍,把該過期的過期掉。

聽起來簡單,但真正做的時候會發現,光改狀態不夠,關聯的數據也要一起處理,否則下次用戶訪問時數字對不上,其次,你統計收入的時候也對不上賬,是吧。

一次巡檢要處理多少東西、怎麼保證不誤殺正常續費的訂閲——這些才是坑。

第二道,懶加載即時自愈/修復

定時任務有延遲,Webhook 可能丟。但有一個時刻是確定的——用戶來了

用戶訪問的那一瞬間,我會做一次實時校驗。如果發現數據不對,當場修正。用戶感知不到延遲,但狀態已經是準的了。

這是最後一道防線。不管前面兩層怎麼漏,用戶來了就一定是準的。

而且實際做下來會發現,需要在這個時刻校驗的東西遠不止「訂閲有沒有過期」一項。跟時間相關的狀態變更,比你想象的要多得多呢。

03

為什麼是三層,不是一層?

你可能會說,Webhook 那麼穩,搞這麼複雜幹嘛?

因為支付是不能賭的

Webhook 是被動的——第三方不通知,我們就不知道。定時任務是有延遲的——兩次巡檢之間有窗口期。懶加載是有前提的——用戶得來訪問。

三層各有短板,但組合在一起,就形成了閉環。

層級
類型
觸發方式
覆蓋場景
Webhook
被動
支付平台推送
99% 的正常情況
定時任務
主動
週期性巡檢
Webhook 丟失&用戶不來
懶加載
主動
用戶訪問時檢查
最終防線,來了就準

做支付系統最怕的不是出 bug——bug 能查能修。最怕的是悄悄地錯,錯了你都不知道,直到某天對賬發現數字對不上。

三層防禦的意義不在於它們每一層都經常被用到,而在於——不管哪個環節出了問題,總有站長兜着。

這就是我在 pay4saas 裏處理訂閲過期的完整思路。Webhook、定時任務、懶加載,三層疊在一起,確保從訂閲到取消、從續費到過期,每一個狀態變更都不會被漏掉。

如果你也在做 SaaS 變現,不想在支付這層踩坑,pay4saas.cn,更多的坑,都已經填好了。讓你放心收錢。