關於訂閱項目

本主題說明如何處理訂閱的生命週期事件,例如續訂和到期日。同時也會說明訂閱服務的其他功能,例如提供促銷活動和允許使用者自行管理訂閱項目。

如果您尚未設定應用程式的訂閱產品,請參閱「建立並設定產品」。

訂閱總覽

「訂閱項目」表示使用者在指定期間內可以享有的一系列權益。例如,訂閱項目可能會授權使用者存取音樂串流服務。

同一個應用程式中可以有多個訂閱項目,可以是代表不同的權益組合,也可以是不同層級的單一權益組合 (例如「白銀級」和「黃金級」)。

您可以透過「基本方案」和「優惠方案」為同一項訂閱產品建立多項設定。例如,您可以為從未訂閱應用程式的使用者建立新用戶優惠。同樣地,您也可以為已訂閱的使用者建立升級優惠。

如需訂閱產品、基本方案和優惠方案的詳細總覽,請參閱 Play 管理中心的說明中心文件。

預付方案整合

預付方案不會在到期後自動續訂。如要在不中斷的情況下延長訂閱授權,使用者必須為同一訂閱項目的預付方案「儲值」

如要儲值,請依照原始購買交易啟動帳單流程。您不必表明購買交易方式為儲值。

預付方案儲值一律會採用 CHARGE_FULL_PRICE 替代模式,因此不需明確設定此模式。系統會立即向使用者收取完整帳單週期的費用,並將授權效期延長至儲值指定的期限。

儲值之後,Purchase 結果物件中的下列欄位會更新,以反映最近一次儲值購買交易:

  • 訂單 ID
  • 購買時間
  • 簽名
  • 購買憑證
  • 已確認

下列 Purchase 欄位一律包含原始購買交易中的相同資料:

  • 套件名稱
  • 購買狀態
  • 產品
  • 自動續訂

預付購買確認

與自動續訂訂閱項目類似,您必須在購買後確認預付方案。初次購買和所有儲值作業都需要獲得確認。詳情請參閱處理購買交易一文。

由於預付方案的持續時間可能比較短,請務必盡快確認購買交易。

預付期為一週或以上的預付方案必須在三天內確認。

預付期少於一週的預付方案必須在方案效期的一半時間內確認。例如,對於為期三天的預付方案,開發人員有 1.5 天的時間來進行確認。

利用深層連結允許使用者管理訂閱項目

應用程式應在設定或偏好設定畫面中提供連結,讓連結能融入應用程式的自然外觀和風格,方便使用者管理訂閱項目。

您可以使用訂閱資源subscriptionState 欄位判斷各訂閱項目是否過期,並且在應用程式加入深層連結,指向 Google Play 訂閱中心的未過期訂閱項目。 基於上述情況,您可以透過幾種方式加入 Play 商店訂閱中心的深層連結。

使用下列網址,將使用者導向至顯示所有訂閱項目的頁面,如圖 1 和圖 2 所示:

https://play.google.com/store/account/subscriptions
Play 商店訂閱項目畫面顯示使用者所有 Google Play 付費訂閱項目的狀態。
圖 1.Play 商店訂閱項目畫面顯示使用者所有 Google Play 付費訂閱項目的狀態。


輕觸訂閱項目查看更多資訊。
圖 2. 輕觸訂閱項目即可查看更多資訊。

使用者可以透過這個深層連結,從 Play 商店訂閱中心還原已取消的訂閱項目。

如要直接連結至未過期訂閱項目的管理頁面,請指出與購買訂閱項目相關聯的套件名稱和 productId。如要透過程式判斷現有訂閱項目的 productId,請查詢應用程式的後端或呼叫 BillingClient.queryPurchasesAsync(),取得與特定使用者相關的訂閱項目清單。每個訂閱項目的訂閱狀態資訊都會包含對應的 productId。與訂閱購買交易相關聯的每個 SubscriptionPurchaseLineItem 物件都包含 productId 值,該值與使用者在該明細項目中購買的訂閱項目相關聯。

使用下列網址將使用者導向至特定訂閱管理畫面 (請將「your-sub-product-id」和「your-app-package」分別替換為 productId 和應用程式套件名稱):

https://play.google.com/store/account/subscriptions?sku=your-sub-product-id&package=your-app-package

接著,使用者就能管理付款方式和存取功能,包括取消、重新訂閱和暫停。

允許使用者升級、降級或變更訂閱項目

您可以為現有訂閱者提供多種選項,讓他們根據需求變更訂閱方案:

  • 如果您販售多個訂閱層級 (例如「基本級」和「進階級」訂閱項目),則可讓使用者購買不同訂閱項目的基本方案或優惠,藉此轉換層級。
  • 您可以讓使用者變更目前的帳單週期,例如從月費方案改成年繳方案。
  • 您也可以允許使用者切換自動續訂或預付方案。

您可以提供訂閱優惠,為合格使用者提供折扣,鼓勵上述任何變動。例如,您可以建立一項優惠,在從月費方案改成年繳方案時提供第一年 50% 折扣,並且將這項優惠僅提供給訂閱月費方案但尚未購買這項優惠的使用者。如要進一步瞭解優惠資格條件,請前往說明中心

圖 3 顯示包含三種不同方案的範例應用程式:

這個應用程式有三個訂閱層級。
圖 3. 這個應用程式有三個訂閱層級。

應用程式可以顯示與圖 3 類似的畫面,為使用者提供變更訂閱項目的選項。無論是哪種情況,您都應該讓使用者清楚瞭解目前的訂閱方案內容,以及可供變更的選項。

使用者決定升級、降級或變更訂閱項目時,您可以指定「取代模式」,決定如何套用目前付費帳單週期的按比例計費價值,以及任何授權變更的生效時間。

取代模式

下表列出可用的取代模式和使用範例。

取代模式

說明

使用範例

WITH_TIME_PRORATION

訂閱項目會立即升級或降級。根據費用差額調整任何剩餘時間,並將下一個帳單日期往後推延,計入新的訂閱項目。此為預設行為。

升級至較昂貴的層級,但不須立即支付額外費用。

CHARGE_PRORATED_PRICE

系統會立即升級訂閱項目,並保持相同的帳單週期,接著,系統會向使用者收取剩餘訂閱期的費用差額。

注意:這個選項僅適用於升級訂閱,亦即每個時間單位的費用增加。

在不變更帳單日期的情況下,升級至較昂貴的層級。

CHARGE_FULL_PRICE

系統會立即升級或降級訂閱項目,並向使用者收取新授權的全額費用。先前訂閱項目的剩餘價值會轉用於相同授權,或在切換至不同授權時依比例計算時間。

注意:如果新訂閱項目提供新用戶優惠或免費試用,則系統會在升級或降級時,向使用者收取新用戶優惠價格,或不收取費用 (以適用者為準)。

從較短的帳單週期升級至較長帳單週期。

WITHOUT_PRORATION

系統會立即升級或降級訂閱項目,並在訂閱項目續訂時依新的價格收費。帳單週期維持不變。

升級至較高的訂閱層級,同時保留剩餘的免費訂閱期。

DEFERRED

系統只能在續訂時升級或降級訂閱項目,但會立即發出新購買交易並附上新授權的開始日期,這樣開發人員才能讓使用者視需要進行其他變更。舉例來說,使用者可以還原為原始方案,或是提出新的延遲方案變更。

降級至價格較低的層級。

如要進一步瞭解如何將升級或降級優惠應用在各種向上銷售和挽回活動上,請參閱優惠與促銷活動指南。

設定購買交易的取代模式

您可以根據偏好設定和商業邏輯,針對不同的訂閱轉換類型使用不同的取代模式。本節說明如何為訂閱項目變更設定取代模式,以及適用的限制。

在同一訂閱項目內重新訂閱或切換方案

您可以在 Google Play 管理中心指定預設替代模式。如果現有訂閱者購買同一訂閱項目的不同基本方案或優惠,或是在取消訂閱後重新訂閱,您可利用這項設定選擇向他們收取費用的時間。可用選項包括「立即收費」(相當於 CHARGE_FULL_PRICE) 和「在下個結帳日收費」(相當於 WITHOUT_PRORATION)。在同一訂閱項目中切換基本方案時,這些是唯一相關的替代模式。

舉例來說,如果使用者在訂閱到期前取消訂閱,而您要針對同一個方案實作挽回優惠,可以將新購買交易視為一般購買交易處理,不必在 SubscriptionUpdateParams 中指明任何值。系統會採用您在訂閱項目中設定的預設取代模式,並自動處理從舊購買交易至新購買交易的方案轉換作業。

在不同訂閱項目間切換方案,或是覆寫預設取代模式

如果使用者要變更訂閱的產品 (也就是購買不同的訂閱項目),或是您想基於任何理由覆寫預設取代模式,可以透過購買流程參數在「執行階段」指定依比例計費的比率。

如要在執行階段購買流程設定中正確提供 SubscriptionUpdateParams,請注意下列限制:

  • 預付方案或自動續約型方案升級、降級或將同一訂閱項目切換預付方案時,唯一允許的依比例計費模式為 CHARGE_FULL_PRICE。如果指定任何其他依比例計費模式,購買交易就會失敗,使用者也會看到錯誤訊息。
  • 在同一訂閱項目內,預付方案或自動續約型方案切換自動續約型方案時,有效的依比例計費模式為 CHARGE_FULL_PRICEWITHOUT_PRORATION。如果指定任何其他依比例計費模式,購買交易就會失敗,使用者也會看到錯誤訊息。

取代模式的範例和行為

若要瞭解各種依比例計費模式的運作方式,請考慮下列情境:

Samwise 訂閱了 Country Gardener 應用程式的線上內容,按月訂閱第 1 層級純文字內容版本。這個訂閱項目的費用為「每月 $2 美元」,並於每月第一天續訂。

4 月 15 日,Samwise 選擇升級為按年訂閱的第 2 層級版本,內容包含影片更新,費用為每年 $36 美元

升級該訂閱項目時,開發人員需選取依比例計費模式。以下清單說明各種依比例計費模式對 Samwise 訂閱項目的影響:

WITH_TIME_PRORATION

Samwise 的第 1 層級訂閱會立即結束。由於他支付了全額月費 (4 月 1 日至 30 日),但在訂閱期間中途進行了升級,因此半個月的訂閱費用 ($1 美元) 會套用到新訂閱項目。不過,由於新訂閱項目的費用為每年 $36 美元,1 美元的抵免餘額只能用於支付 10 天的費用 (4 月 16 日至 25 日),因此在 4 月 26 日,系統會針對新訂閱項目向他收取 $36 美元的費用,之後每年的 4 月 26 日再收取 $36 美元。

您應在購買交易成功時呼叫應用程式的 PurchasesUpdatedListener,這樣就能透過 queryPurchasesAsync() 呼叫擷取新的購買交易。您的後端會立即收到 SUBSCRIPTION_PURCHASED 即時開發人員通知。

CHARGE_PRORATED_PRICE

您可以使用這種模式,因為第 2 層級每個時間單位的訂閱價格 (每年 $36 美元 = 每月 $3 美元) 高於第 1 層級每個時間單位的訂閱價格 (每月 $2 美元)。Samwise 的第 1 層級訂閱會立即結束。由於他已支付全額月費,但只使用了一半時間,因此半個月的訂閱費用 ($1 美元) 會套用到新的訂閱項目。不過,由於新訂閱項目的費用為每年 $36 美元,剩餘 15 天的費用為 $1.50 美元,因此系統會針對新訂閱項目向他收取 $0.50 美元的差額。系統會在 5 月 1 日針對新的訂閱層級向 Samwise 收取 $36 美元,並在之後每年的 5 月 1 日再收取 $36 美元。

您應在購買交易成功時呼叫應用程式的 PurchasesUpdatedListener,這樣就能透過 queryPurchasesAsync() 呼叫擷取新的購買交易。您的後端會立即收到 SUBSCRIPTION_PURCHASED 即時開發人員通知。

WITHOUT_PRORATION

Samwise 的第 1 層級訂閱會立即免費升級為第 2 層級,系統會在 5 月 1 日針對新的訂閱層級向他收取 $36 美元,之後每年的 5 月 1 日再收取 $36 美元。

您應在購買交易成功時呼叫應用程式的 PurchasesUpdatedListener,這樣就能透過 queryPurchasesAsync() 呼叫擷取新的購買交易。您的後端會立即收到 SUBSCRIPTION_PURCHASED 即時開發人員通知。

DEFERRED

Samwise 的第 1 層級訂閱繼續有效,直到 4 月 30 日到期為止。5 月 1 日,第 2 層級訂閱生效,系統會針對新的訂閱層級向 Samwise 收取 $36 美元。

您應在購買交易成功時呼叫應用程式的 PurchasesUpdatedListener,這樣就能透過 queryPurchasesAsync() 呼叫擷取新的購買交易。您的後端會立即收到 SUBSCRIPTION_PURCHASED 即時開發人員通知。屆時,處理購買交易的方式應與處理其他新購買交易時相同。具體而言,請務必確認這筆新購買交易。請注意,取代模式生效時 (也就是舊訂閱項目到期時),系統會填入新訂閱項目的 startTime。屆時,您會收到新訂閱方案的 SUBSCRIPTION_RENEWED RTDN。如要進一步瞭解 ReplacementMode.DEFERRED 行為,請參閱「處理延遲取代模式」一節。

CHARGE_FULL_PRICE

Samwise 的第 1 層級訂閱會立即結束。他的第 2 層級訂閱將於今天開始生效,並須支付 $36 美元的費用。由於他已支付全額月費,但只使用了一半時間,因此半個月的訂閱費用 ($1 美元) 會套用到新的訂閱項目。由於新訂閱項目的費用為每年 $36 美元,因此訂閱期可再加上一年的 1/36 (約 10 天)。因此,下次向 Samwise 收費的時間為從今天起 1 年 10 天後,費用為 $36 美元。之後,系統每年會收取 $36 美元的費用。

選擇依比例計費模式時,請務必查看我們的「取代模式建議」。

觸發應用程式內訂閱項目異動

應用程式可以使用與「啟動購買流程」相同的步驟,向使用者提供升級或降級服務。不過,在升級或降級時,您需要提供目前訂閱項目、未來 (升級或降級後) 訂閱項目的詳細資料,以及要使用的取代模式等內容,範例如下:

Kotlin

val offerToken = productDetails
        .getSubscriptionOfferDetails(selectedOfferIndex)
        .getOfferToken()

val billingParams = BillingFlowParams.newBuilder().setProductDetailsParamsList(
       listOf(
           BillingFlowParams.ProductDetailsParams.newBuilder()
               .setProductDetails(productDetails)
               .setOfferToken(offerToken)
               .build()
       )
       ).setSubscriptionUpdateParams(
           BillingFlowParams.SubscriptionUpdateParams.newBuilder()
               .setOldPurchaseToken("old_purchase_token")
               .setSubscriptionReplacementMode(
                 BillingFlowParams.ReplacementMode.CHARGE_FULL_PRICE
               )
               .build()
       ).build()

billingClient.launchBillingFlow(
    activity,
    billingParams
   )
// ...

Java

String offerToken = productDetails
    .getSubscriptionOfferDetails(selectedOfferIndex)
    .getOfferToken();

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(
        ImmuableList.of(
            ProductDetailsParams.newBuilder()
                // fetched via queryProductDetailsAsync
                .setProductDetails(productDetails)
                // offerToken can be found in
                // ProductDetails=>SubscriptionOfferDetails
                .setOfferToken(offerToken)
                .build()))
    .setSubscriptionUpdateParams(
        SubscriptionUpdateParams.newBuilder()
            // purchaseToken can be found in Purchase#getPurchaseToken
            .setOldPurchaseToken("old_purchase_token")
            .setSubscriptionReplacementMode(ReplacementMode.CHARGE_FULL_PRICE)
            .build())
    .build();

BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
// ...

取代模式建議

下表列出依比例計費的不同情境,以及我們針對每個情境的建議做法:

情境 建議取代模式 結果
升級至價格更高的層級 CHARGE_PRORATED_PRICE 使用者立即取得存取權,並保留相同的收費週期。
降級至價格更低的層級 DEFERRED 使用者已支付較昂貴層級的費用,因此在下次帳單日期前仍可存取內容。
在免費試用期內升級,保有免費試用資格 WITHOUT_PRORATION 使用者保有免費試用資格,但在試用期的剩餘時間升級至更高的訂閱層級。
在免費試用期內升級,結束免費試用資格 CHARGE_PRORATED_PRICE 使用者會立即取得新訂閱層級的存取權,但不再享有免費試用資格。

處理訂閱項目異動購買交易

就所有條款和用途而言,方案的變更應視為新購買交易,且在帳單流程成功完成後以此方式處理及確認。除了妥善處理新購買交易,您也必須終止要取代的購買交易。

應用程式內行為與任何新購買交易相同。應用程式可在 PurchasesUpdatedListener 中收到新購買交易的結果,並使用 queryPurchasesAsync 中的新購買交易。

如果有購買交易取代現有購買交易,Google Play Developer API 會在訂閱資源中傳回 linkedPurchaseToken。請務必讓 linkedPurchaseToken 中提供的憑證失效,確保舊的憑證無法用來存取服務。請參閱「升級、降級和重新註冊」相關說明,瞭解如何處理升級和降級購買交易。

收到新的購買憑證後,請執行與驗證新的購買憑證相同的驗證程序。請務必透過 Google Play 帳款服務程式庫的 BillingClient.acknowledgePurchase() 或 Google Play Developer API 的 Purchases.subscriptions:acknowledge 確認這些購買交易。

處理延遲取代模式

延遲取代模式可讓使用者在開始新方案前,先用完舊方案的剩餘授權。

如果針對新購買交易使用 ReplacementMode.DEFERREDqueryPurchasesAsync() 會在購買流程後傳回新的購買憑證,該購買憑證仍保留與舊產品的關聯性,直到下一個續訂日期延遲取代模式生效後,系統才會傳回新產品。

過去,您可以透過已淘汰的 ProrationMode.DEFERRED 實現這項使用者體驗,但 ProrationMode.DEFERRED 已從 Play 帳款服務程式庫第 6 版淘汰。請參閱下表,瞭解兩者的行為差異:

時間

ProrationMode.DEFERRED (已淘汰)

ReplacementMode.DEFERRED

購買流程成功後立即執行 (應用程式)

系統會在購買交易後叫用 PurchasesUpdatedListener,並附帶升級或降級是否成功的狀態。

舊方案的授權仍然有效,直到下次續訂日期為止。為確保應用程式提供正確的授權,queryPurchasesAsync() 會傳回 Purchase 物件,其中包含原始購買憑證,且該原始授權維持有效,直到執行取代模式為止。

系統未提供新的購買憑證,因此目前無法處理。

系統會在購買交易後叫用 PurchasesUpdatedListener,並附帶升級或降級是否成功的狀態。

queryPurchasesAsync() 會立即傳回購買交易,其中包含新的購買憑證,以及相關聯的原始授權

系統已提供新的購買憑證,因此應在此時加以處理,同時將取代模式生效日期列入考量。

購買流程成功後立即執行 (後端)

系統「不會」在購買流程後傳送 SUBSCRIPTION_PURCHASED RTDN。後端尚未得知新的購買交易。

系統會在購買流程後立即傳送含有舊 product_id 的 SUBSCRIPTION_PURCHASED RTDN,提供新的購買憑證。

使用新購買憑證呼叫 purchases.subscriptionsv2.get 方法會傳回一個購買交易,其中的「startTime」會以兩個明細項目表示購買時間:

  • 一個代表「舊」授權,並且在未來會有「expiryTime」。舊授權不會續約, DeferredItemReplacement 內含內含授權的產品。這表示舊授權在到期後,有待處理的替換項目。
  • 一個代表「新購買」授權。未針對「expiryTime」設定任何值。

系統會針對「舊」購買憑證傳送 SUBSCRIPTION_EXPIRED。使用「舊」購買憑證呼叫 purchases.subscriptionsv2.get 方法時,會顯示為已過期 (舊方案剩餘時間的授權會轉移給新購買交易)。

執行取代模式時 - 購買流程後首次續訂 (應用程式)

queryPurchasesAsync() 會傳回新的 Purchase 物件,其中包含新的購買憑證和授權。

系統已提供新的購買憑證,因此應在此時加以處理

queryPurchasesAsync() 會立即傳回購買交易,其中包含新的購買憑證,以及相關聯的新授權

購買流程成功後,新購買交易應該已處理完畢,因此應用程式除了確定已授予正確授權外,不應採取任何特殊動作。

執行取代模式時 - 購買流程後首次續訂 (後端)

現在可在系統傳送第一個 SUBSCRIPTION_RENEWED RTDN 時處理及確認新購買交易。

您可利用訂閱資源中的 linkedPurchaseToken,判斷訂閱後端中的哪位使用者 (在適用情況下) 應更新為新授權。

系統在為新購買憑證傳送 SUBSCRIPTION_PURCHASED RTDN 後,新購買交易已處理完畢並記錄為「startTime」。

使用 ReplacementMode.DEFERRED 時,首次續訂會依循任何其他續訂的標準行為,因此發生這個事件時,您不需要處理任何取代模式的特殊邏輯。

使用新購買憑證呼叫 purchases.subscriptionsv2.get 方法時,會傳回包含兩個明細項目的購買交易:

  • 一個代表「舊」授權,其中包含過去的「expiryTime」,但未設定 DeferredItemReplacement 的值。
  • 一個代表「新」授權,其中包含未來的「expiryTime」,且已啟用 auto_renewing_enabled 標記。

從此應使用 ReplacementMode.DEFERRED 而非已淘汰的 ProrationMode.DEFERRED,因為前者雖然執行與授權變更相同的行為,但提供的購買交易管理方式,與其他新購買交易的行為更加一致。

客戶管理

在使用即時開發人員通知下,您可以即時得知使用者何時決定取消訂閱。假如使用者在到期前取消訂閱,您可以傳送推播通知或應用程式內通訊訊息,請求使用者重新訂閱。

使用者取消訂閱項目後,您可以嘗試在應用程式中或透過 Play 商店挽回使用者。下表說明各種訂閱情境,以及相關的挽回動作和應用程式相關規定。

訂閱到期前 訂閱到期後
應用程式內 Play 商店中 應用程式內 Play 商店中
挽回功能 應用程式內訂閱項目 還原 應用程式內訂閱項目 重新訂閱
使用者完成結帳流程
使用者的訂閱項目仍對應到同一個 SKU 使用者可訂閱相同或不同的 SKU 使用者可訂閱相同或不同的 SKU
建立新的購買憑證
預設啟用 是,所有開發人員均須支援

沒有帳款服務程式庫 2.0 以上版本的應用程式:否

具有帳款服務程式庫 2.0 以上版本的應用程式:是。開發人員可以在管理中心選擇退出。

向使用者收費時

如果使用相同的 SKU:在當前帳單週期結束時。

如果使用不同的 SKU:取決於依比例計費模式。

目前的帳單週期結束 立即 立即
必須實作 在應用程式中提供重新訂閱的 UI

偵測訂閱狀態變更

Play 商店的深層連結

在應用程式中提供重新訂閱的 UI 處理應用程式外購

訂閱到期前 - 應用程式內

對於已取消但尚未到期的訂閱項目,您可以採取與新訂閱者相同的應用程式內產品購買流程,讓訂閱者還原應用程式中的訂閱項目。請確認 UI 會反映出使用者已有訂閱項目。例如,您可以考慮在「重新啟用」按鈕旁顯示使用者目前的到期日和定期費用

在多數情況下,您應考慮向使用者提供與其訂閱項目相同的價格和 SKU,方法如下:

  • 購買 SKU 相同的新訂閱項目。
  • 新訂閱項目會取代舊訂閱項目,並於相同的到期日續訂。舊訂閱項目會立即標示為「已過期」。
  • 例如,Achilles 訂閱了 Example Music 應用程式,訂閱將於 8 月 1 日到期。7 月 10 日,他又重新訂閱了單月訂閱方案,每個月的價格不變。新訂閱立即生效,並使用了剩餘依比例計費的折抵金額,且依舊在 8 月 1 日續訂。

如要提供不同的價格 (例如新的免費試用期或挽回折扣),可以改為向該使用者提供不同的 SKU:

  • 運用取代模式 WITHOUT_PRORATION,透過不同 SKU 執行升級或降級
  • 新訂閱項目會取代舊訂閱項目,並於相同的到期日續訂。在原有的到期日向使用者收取新 SKU 的費用,包括任何新用戶優惠價。如果舊訂閱項目是使用經過模糊處理的帳戶 ID 建立的,應將相同的 ID 傳遞至 BillingFlowParams 以執行升級和降級。
  • 例如,Achilles 訂閱了 Example Music 應用程式,訂閱將於 8 月 1 日到期。7 月 10 日,他又使用新用戶優惠重新訂閱了按年訂閱的方案。新訂閱方案會立即生效,並且將於 8 月 1 日依新用戶優惠向他收取費用。
  • 如果您決定在挽回 SKU 中納入免費試用期或新用戶優惠,請在 Google Play 管理中心取消勾選「允許每個應用程式免費試用一次」方塊,確保使用者符合資格。這個選項會限制每個應用程式只能向使用者提供一次免費試用。

收到購買憑證後,如同處理新訂閱項目一樣處理購買交易。另外,Google Play Developer API 會在訂閱資源中傳回 linkedPurchaseToken。請務必讓 linkedPurchaseToken 中提供的憑證失效,確保舊的憑證無法用來存取服務。

訂閱到期前 - Play 商店中

如果取消的訂閱項目尚未到期,使用者只要在 Google Play 訂閱中心按一下「重新訂閱」(先前為「還原」),即可還原該訂閱項目。這樣就能保有相同的訂閱項目和購買憑證。

Google Play 商店應用程式中的「訂閱」部分會顯示已取消的訂閱項目和重新訂閱按鈕
圖 8.Google Play 商店應用程式的「帳戶」>「訂閱」部分會顯示已取消的訂閱項目和「重新訂閱」按鈕。

若要進一步瞭解如何還原訂閱項目,請參閱還原

訂閱到期後 - 應用程式內

您可以採取與新訂閱者相同的應用程式內產品購買流程,讓已過期的訂閱者在應用程式內重新訂閱。請注意以下事項:

  • 如要向使用者提供折扣,建議您為訂閱項目提供設有特價優惠的產品 ID (也稱為挽回 SKU)。您可以在應用程式中提供優惠,或在應用程式外向使用者通知優惠內容,例如傳送電子郵件。
  • 若要訂閱一個挽回訂閱,請使用 Google Play 帳款服務資料庫在 Android 應用程式中啟動購買流程。這個流程與新訂閱項目相同,但您可以決定使用者可用的 SKU。
  • 如果您決定在用於挽回的 SKU 中納入免費試用期或新用戶優惠,請在 Google Play 管理中心取消勾選「允許每個應用程式免費試用一次」方塊,以確保使用者符合資格。這個選項會限制使用者每個應用程式只能取得一次免費試用。
  • 如果使用者重新訂閱相同的 SKU,就不符合免費試用或新用戶優惠的資格。請確認 UI 能反映出這些資訊。

收到購買憑證後,如同處理新訂閱項目一樣處理購買交易。您將不會在訂閱資源中收到 linkedPurchaseToken

訂閱到期後 - Play 商店中

如果是啟用的狀態,使用者只要在 Google Play 訂閱中心按一下「重新訂閱」,即可在到期後重新訂閱相同的 SKU,最長可訂閱一年。系統會產生新的訂閱項目和購買憑證。

Google Play 商店應用程式的「訂閱」部分,當中顯示已取消和已過期的訂閱項目,並提供「重新訂閱」和「移除」按鈕
圖 9.Google Play 商店應用程式中的「帳戶」>「訂閱」部分,當中顯示已取消和已過期的訂閱項目,並提供「重新訂閱」和「移除」按鈕。

重新訂閱視為應用程式外購行為,因此請務必遵循「處理應用程式外的購物交易」一節的最佳做法。

宣傳您的訂閱項目

您可以建立促銷代碼,為選取的使用者延長現有訂閱項目的免費試用期。如要瞭解詳情,請參閱促銷代碼

對於免費試用期,Google Play 會在開始免費試用之前,驗證使用者擁有有效的付款方式。部分使用者可能會在其付款方式以「暫緩付款」或「扣款」的形式看到這項驗證。這筆暫緩付款或扣款只是暫時性的,稍後會退還或退款。

試用期結束後,系統會向使用者的付款方式收取全額訂閱費用。

如果使用者在免費試用期內取消訂閱,訂閱項目在試用期結束前仍然有效,而且在免費試用期結束時也不需付費。

取消、退款或撤銷

您可以使用 Google Play Developer API 取消撤銷訂閱項目,或為訂閱項目辦理退款Google Play 管理中心也提供這項功能。

  • 取消:使用者可以在 Google Play 取消訂閱項目。您也可以讓使用者選擇在應用程式中或網站上取消訂閱。應用程式應依據「取消」一節所述的方式處理這些取消操作。
  • 退款:退款後,使用者可以繼續使用該訂閱項目。例如,如果有技術錯誤導致使用者無法存取您的產品,但錯誤已得到解決,則可以使用退款功能。請注意,如果退款金額超過最近支付的款項,或是您要進行部分退款,則必須使用 Google Play 管理中心。
  • 撤銷:當您撤銷訂閱項目後,使用者會立即失去該訂閱項目的存取權。例如,如果有技術錯誤導致使用者無法存取您的產品,而且使用者不想繼續使用該產品,則可以使用此功能。應用程式應依據撤銷所述處理這些取消操作。

下表說明取消、退款與撤銷之間的差異。

停止續訂 退還款項 撤銷存取權
取消 不可
退款
撤銷

延後向訂閱者收費

您可以使用 Google Play Developer API 中的 Purchases.subscriptions:defer,將自動續訂者的下一個收費日期往後延。在延後期間,使用者可完整存取訂閱的內容,但無須支付費用。系統將根據延後的收費日期更新續訂日期。

對於預付方案,您可以使用延後收費的 API,將到期時間延後。

您可以藉由延後收費來達成下列目的:

  • 以特價優惠的形式向使用者提供免費存取權,例如購買電影可免費享有一週的觀影體驗。
  • 提供使用者免費存取以表達善意。

每個 API 呼叫可以將帳單最短延後一天,最長延後一年。若要將收費時間延得更長,您可以在新的收費日期前再次呼叫 API。

舉例來說,Darcy 按月訂閱 Fishing Quarterly 應用程式的線上內容,通常會在每月第一天支付 1.25 英鎊。3 月時她參與了應用程式發布者的線上問卷調查。發布者獎勵她免費六週的使用權,將下次付款日期延後至 5 月 15 日 (也就是原定帳單日期 4 月 1 日後六個星期)。4 月或 5 月初,Darcy 無須支付費用且仍可存取相關內容。5 月 15 日,她支付了該月 1.25 英鎊的正常訂閱費用。下次續訂日期變為 6 月 15 日。

延後時,您可以考慮透過電子郵件或在應用程式內,通知使用者帳單日期已變更。

處理付款遭拒問題

如果續訂訂閱項目發生付款問題,Google 會在取消訂閱前定期嘗試續訂一段時間。此復原期可以由寬限期和帳戶保留期組成。在這段時間內,Google 會傳送電子郵件和通知,提示使用者更新付款方式。

付款遭拒時,訂閱項目會進入寬限期 (如果已設定)。在寬限期內,您應確保使用者仍可存取訂閱授權。

寬限期結束後,訂閱項目就會進入帳戶保留期。在帳戶保留期間,您應確保使用者無法存取訂閱授權。

您可以在 Google Play 管理中心指定每個自動續約型基本方案的寬限期和帳戶保留期。如果指定長度小於預設值,可能會減少從付款遭拒中復原的訂閱項目數量。

如要在付款遭拒時盡量爭取恢復訂閱,可以通知使用者付款問題並請求對方加以修正。

您可按照「寬限期」和「帳戶保留」章節所述的方式自行執行這項操作,也可以實作應用程式內通訊 API,讓 Google 在應用程式中向使用者顯示訊息。

應用程式內通訊

如果您透過 InAppMessageCategoryId.TRANSACTIONAL 啟用應用程式內通訊功能,Google Play 會在寬限期和帳戶保留期內每天向使用者顯示一次訊息,讓使用者不必離開應用程式就能修正付款問題。

Snackbar 通知使用者修正付款問題
圖 20. Snackbar 通知使用者修正付款問題。

我們建議您在使用者每次開啟應用程式時呼叫此 API,以判斷是否應顯示訊息。

如果使用者成功復原訂閱項目,您會收到 SUBSCRIPTION_STATUS_UPDATED 的回應代碼和購買憑證。接下來,請使用這個購買憑證呼叫 Google Play Developer API,並在應用程式中重新整理訂閱狀態。

整合應用程式內通訊功能

若要向使用者顯示應用程式內通訊訊息,請使用 BillingClient.showInAppMessages()

以下是觸發應用程式內訊息流程的範例:

Kotlin

val inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build()

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        object : InAppMessageResponseListener() {
            override fun onInAppMessageResponse(inAppMessageResult: InAppMessageResult) {
                if (inAppMessageResult.responseCode == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        })

Java

InAppMessageParams inAppMessageParams = InAppMessageParams.newBuilder()
        .addInAppMessageCategoryToShow(InAppMessageCategoryId.TRANSACTIONAL)
        .build();

billingClient.showInAppMessages(activity,
        inAppMessageParams,
        new InAppMessageResponseListener() {
            @Override
            public void onInAppMessageResponse(InAppMessageResult inAppMessageResult) {
                if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.NO_ACTION_NEEDED) {
                    // The flow has finished and there is no action needed from developers.
                } else if (inAppMessageResult.responseCode
                        == InAppMessageResponseCode.SUBSCRIPTION_STATUS_UPDATED) {
                    // The subscription status changed. For example, a subscription
                    // has been recovered from a suspend state. Developers should
                    // expect the purchase token to be returned with this response
                    // code and use the purchase token with the Google Play
                    // Developer API.
                }
            }
        });