銷售訂閱項目

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

閱讀本主題前,請務必先參閱「將 Google Play 帳款服務程式庫整合至應用程式」一文,瞭解在應用程式中販售及管理產品的一般操作說明。

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

訂閱總覽

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

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

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

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

處理訂閱生命週期

購買的訂閱項目會在其生命週期中經歷各種狀態變更,而您的應用程式必須對每項變更做出回應。若要查看訂閱項目的狀態,可以使用 Google Play 帳款服務程式庫中的 BillingClient.queryPurchasesAsync(),或 Google Play Developer API 中的 Purchases.subscriptionsv2:get

BillingClient.queryPurchasesAsync() Purchases.subscriptionsv2:get
狀態 是否傳回? isAutoRenewing 是否傳回? expiryTime subscriptionState autoRenewing
進行中 未來 SUBSCRIPTION_STATE_ACTIVE
已取消 未來 SUBSCRIPTION_STATE_CANCELED
在寬限期內 未來 (寬限期結束) SUBSCRIPTION_STATE_IN_GRACE_PERIOD
保留中 不適用 過去 (預計的到期時間結束,或寬限期結束,如果有的話) SUBSCRIPTION_STATE_ON_HOLD
已暫停 不適用 過去 SUBSCRIPTION_STATE_PAUSED
已過期 不適用 過去 SUBSCRIPTION_STATE_EXPIRED

如果應用程式將訂閱狀態儲存在安全的後端伺服器上,則應使用即時開發人員通知監聽狀態變更,以確保狀態保持同步。系統會針對影響訂閱狀態的事件 (例如續訂和取消訂閲) 傳送 SubscriptionNotification

應用程式必須處理下列各節所述的狀態變更。

新增訂閱項目

請務必遵循我們的建議處理新的購買交易。購買一項訂閱項目後,BillingClient.queryPurchasesAsync()SubscriptionNotification 會傳回該訂閱項目,並傳送類型為 SUBSCRIPTION_PURCHASED 的通知。收到這則通知時,需查詢 Google Play Developer API 來取得最新的訂閱狀態。訂閱資源類似於以下範例。請注意,在確認購買交易之前,資源會具有 ACKNOWLEDGEMENT_STATE_PENDINGacknowledgementState

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", // need to acknowledge new purchases
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

續訂

如果訂閱項目成功續訂,BillingClient.queryPurchasesAsync() 會持續傳回該訂閲項目。

續訂訂閲項目時,也會傳送 SUBSCRIPTION_RENEWED 通知。應用程式應確保使用者仍有權訂閱,並以 Google Play Developer API 傳回的訂閱資源中的新 expiryTime 來更新訂閱狀態。訂閱資源類似如下:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ]
}

到期日

訂閱到期後,BillingClient.queryPurchasesAsync() 中不會再傳回訂閲項目,使用者將無法再存取該訂閱項目。

訂閱到期時,系統也會傳送類型為 SUBSCRIPTION_EXPIREDSubscriptionNotification。收到這則通知時,您應查詢 Google Play Developer API 來取得最新的訂閱狀態。訂閱資源類似如下所示:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time_in_past,
      ...
    }
  ],
}

取消

使用者可以自發性地從 Play 商店取消訂閱項目,也可以在訂閱項目進入帳戶保留狀態後不進行復原,讓系統自動取消訂閱項目。使用者取消訂閱項目後,在目前的帳單週期結束前仍可存取訂閲內容。帳單週期結束後,系統會撤銷存取權。

如果訂閱項目已取消,但訂閲項目尚未到期BillingClient.queryPurchasesAsync() 會傳回該訂閱項目。取消訂閱項目會觸發 SUBSCRIPTION_CANCELED 通知。收到這則通知時,從 Google Play Developer API 傳回的訂閱資源含有 autoRenewing = false,而 expiryTime 則含有使用者無法再存取該訂閱項目的日期。如果 expiryTime 是過去的日期,使用者會立即失去授權。否則,使用者應保留授權,直到授權到期為止。訂閱資源類似如下所示:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

應用程式可以在 Google Play Developer API 傳回的訂閱資源中查看 cancelReason,瞭解取消訂閱項目的原因 (例如客戶自行取消或出現帳單問題)。如果使用者取消了訂閱項目,您可以查看 cancelSurveyResult 欄位,瞭解使用者取消該訂閲項目的原因。

建議您在應用程式中顯示訊息,通知使用者訂閱項目已取消,例如「您的訂閱項目將於 <日期> 到期」。應用程式也可以利用深層連結至 Google Play 商店,讓使用者還原訂閱項目

如果顯示這則訊息,您也應該讓使用者可以永久關閉這則訊息。

另外請注意,取消訂閱的訊息可能會讓使用者感到困擾,特別是在使用者自行取消,而不是因付款逾時而取消的情況下。您可以選擇不通知手動取消訂閲項目的使用者。

撤銷

使用者的訂閱項目可能會基於各種原因而遭撤銷,例如應用程式使用 Purchases.subscriptions:revoke 撤銷訂閱項目或是購買交易遭退單。在這種情況下,應用程式應立即撤銷使用者的授權。BillingClient.queryPurchasesAsync() 不會再傳回撤銷的訂閱項目。發生這樣的情況時,系統也會傳送類型為 SUBSCRIPTION_REVOKEDSubscriptionNotification。收到這則通知時,從 Google Play Developer API 傳回的訂閱資源含有 autoRenewing = false,而 expiryTime 則含有使用者無法再存取該訂閱項目的日期。訂閱資源看起來類似如下:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

帳戶保留

帳戶保留是一種訂閱狀態。假如使用者的付款方式無效,且相關寬限期結束後仍未解決付款問題,訂閱項目就會進入這個狀態。當訂閱項目進入帳戶保留狀態時,您應封鎖對相關內容或服務的存取權。帳戶保留期限最長可達 30 天。

在帳戶保留期限內,BillingClient.queryPurchasesAsync() 不會傳回該訂閱項目。

在帳戶保留期間,您可以視需要處理任何取消還原或重新購買訂閱項目的操作。

當使用者進入帳戶保留狀態後,您應利用即時開發人員通知,通知使用者訂閱項目存取權遭到停權的原因。您應該在應用程式中提供訊息,說明如何修正付款方式以及重新取得該訂閱項目的存取權。訊息應包含 Google Play 訂閱設定的連結,以便使用者修正付款方式。例如,您可以使用類似以下的訊息:

"There is a problem with your subscription. Click here to go to the
Google Play subscription settings to fix your payment method."

如果使用者可以在應用程式外存取訂閱內容,建議您向使用者傳送推播通知或電子郵件,告知對方訂閱項目已失效。

如果客戶修正了付款問題,您可以在應用程式中顯示訊息,通知使用者訂閱項目已於何時還原。例如,您可以使用類似以下的訊息:

"Your form of payment was updated, and your subscription has
been recovered."

透過即時開發人員通知,當訂閱項目進入帳戶保留狀態時,您會收到類型為 SUBSCRIPTION_ON_HOLDSubscriptionNotification。從安全的後端伺服器呼叫 Google Play Developer API 以擷取新的訂閱資訊。在帳戶保留期間,訂閱資源expiryTime 會設定為過去的時間戳記:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

使用者修正付款方式後,訂閱項目會恢復為活動狀態,接著您必須還原訂閱內容的存取權。

如果應用程式僅使用 queryPurchasesAsync() 判斷使用者是否有權存取訂閱項目,應用程式應自動處理從帳戶保留狀態復原的訂閱項目。

如果應用程式會與伺服器同步訂閱狀態,則應監聽類型為 SUBSCRIPTION_RECOVEREDSubscriptionNotification,以便在復原訂閱項目時收到通知,而使用者則應重新取得存取權。如果您在收到這則通知後查詢訂閱項目,expiryTime 會設定為未來的時間戳記:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      ...
    }
  ],
}

如果使用者在帳戶保留期結束前仍未修正付款方式,您會收到 SUBSCRIPTION_CANCELED 即時開發人員通知。如需處理取消訂閱的相關說明,請參閱取消訂閱。當您查詢以這種方式取消的訂閱項目時,傳回的 expiryTime 會設定為過去的時間戳記:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

寬限期

如果啟用了寬限期,而在帳單週期結束時出現付款問題,訂閱項目會進入寬限期。在這段期間,當 Google Play 嘗試續訂訂閲項目時,使用者仍可存取該訂閱項目。可以透過 Google Play 管理中心的應用程式內產品設定指定寬限期的長度。

如果應用程式僅使用 queryPurchasesAsync() 判斷使用者是否有權存取訂閱項目,則應用程式應自動處理寬限期,因為 queryPurchasesAsync() 會在到期日之前繼續傳回取消的購買交易。

如果應用程式會與後端同步訂閱狀態,則應監聽類型為 SUBSCRIPTION_IN_GRACE_PERIODSubscriptionNotification,以便在使用者進入寬限期時收到通知。當使用者處於寬限期時,訂閱資源會包含 autoRenewEnabled = true

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

當使用者進入寬限期後,您應該在應用程式中顯示訊息,讓使用者瞭解如何修正付款方式。否則,在寬限期結束時,使用者就無法再存取訂閱項目。這則訊息可以透過深層連結至 Google Play 商店,協助使用者管理訂閱項目。

只要使用者修正付款方式,系統就會隨即續訂訂閱項目,而應用程式會依據「續訂」一節所述的方式處理續訂作業。

如果使用者在寬限期內未修正付款方式,訂閱項目就會進入帳戶保留狀態。

暫停提供的訂閱項目

您可以讓使用者暫停訂閱項目以避免自願性流失。啟用暫停功能時,使用者可以選擇將訂閱項目暫停一週至三個月,視循環週期而定。啟用暫停功能後,「暫停」選項會顯示在訂閱中心和取消流程中。請注意,按年的訂閱項目無法暫停,一週和三個月的暫停限制隨時有可能會變動。

若要讓使用者暫停訂閱項目,請執行下列步驟:

  1. 登入 Google Play 管理中心
  2. 選取您的應用程式,然後依序前往「商店發布」>「應用程式內產品」>「訂閱項目」。
  3. 展開「訂閱設定」專區。
  4. 勾選「允許暫停訂閱」。

目前的帳單週期結束後,訂閱項目暫停功能才會生效。訂閱項目暫停期間,使用者無法存取該訂閱項目。暫停期間結束後,訂閱就會恢復,Google 會嘗試續訂該訂閲項目。如果成功恢復訂閱,該訂閱項目就會再次生效。如果因付款問題而恢復失敗,使用者會進入帳戶保留狀態,如圖 1 所示:

使用者暫停訂閱項目,帳戶進入保留狀態
圖 1.使用者暫停訂閱項目,帳戶進入保留狀態。

使用者也可以選擇在暫停期間內,隨時手動恢復訂閱項目,如圖 2 所示。使用者手動恢復時,帳單日期會變更為手動恢復日期。

使用者暫停訂閱後再恢復訂閱項目
圖 2.使用者暫停訂閱後再恢復訂閱項目。

使用者暫停訂閱時,queryPurchasesAsync() 不會傳回訂閱項目。恢復訂閲後,queryPurchasesAsync() 會傳回該訂閱項目。

如果應用程式會與安全的後端伺服器同步訂閱狀態,則應監聽即時開發人員通知來維持狀態。這些通知也可讓您在應用程式中通知使用者他們已暫停訂閱項目,因而無法存取訂閱內容。您還應該為使用者提供一種方法,使其可以利用 Google Play 的深層連結來手動恢復訂閱項目。

使用者暫停訂閱項目時,系統會傳送類型為 SUBSCRIPTION_PAUSE_SCHEDULE_CHANGEDSubscriptionNotification。這時候使用者應保有訂閱項目的存取權,而訂閱資源則有 autoRenewing = truepaymentState = 1(已收到款項)以及 expiryTimeautoResumeTimeMillis 的未來值。

暫停功能生效後,系統會傳送類型為 SUBSCRIPTION_PAUSEDSubscriptionNotification。此時,使用者應無法存取訂閲項目,而訂閱資源則含有 autoRenewing = truepaymentState = 0 (待處理)、autoResumeTimeMillis 的未來值以及 expiryTime 的過去值。

如果在暫停訂閲期結束時訂閱自動恢復,或是使用者選擇手動恢復訂閲,則系統會傳送類型為 SUBSCRIPTION_RENEWEDSubscriptionNotification。這個程序應依據「續訂」一節所述的方式處理。

如果在嘗試恢復訂閱時付款失敗,系統會傳送類型為 SUBSCRIPTION_ON_HOLDSubscriptionNotification。這個程序應依據「帳戶保留」一節所述的方式處理。

復原

在到期日之前,取消的訂閱項目仍會顯示在 Play 商店應用程式中,使用者只要在 Google Play 商店應用程式的「訂閱」部分中按一下「重新訂閱」(先前為「恢復」),即可復原已取消的訂閱項目。

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

如果應用程式僅使用 queryPurchasesAsync() 判斷使用者是否有權存取訂閱項目,應用程式應自動處理訂閱的還原作業,因為 queryPurchasesAsync() 會在到期日之前繼續傳回取消的購買交易。還原的訂閱項目會形同未曾被取消般繼續續訂。

如果應用程式會與後端同步訂閱狀態,則應監聽類型為 SUBSCRIPTION_RESTARTEDSubscriptionNotification。收到通知後,應用程式會回應通知,記錄訂閱項目現在已設為續訂,並且停止在應用程式中顯示還原訊息。訂閱資源應如下所示:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date
      ...
    }
  ],
}

升級、降級和重新訂閱

當使用者升級降級,或在訂閱項目到期前從應用程式重新註冊時,舊的訂閱項目就會失效,系統會使用新的購買憑證建立新訂閱項目

此外,Google Play Developer API 傳回的訂閱資源將包含 linkedPurchaseToken,指出使用者要降級、升級或重新訂閱舊的購買交易。您可以使用 linkedPurchaseToken 查詢舊的訂閱項目,並識別現有的使用者帳戶,以便將新的購買交易連結至同一個帳戶。我們也建議您使用 Google Play Developer API 確認購買交易,以減少使用者操作不便的情形。訂閱資源類似如下所示:

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "linkedPurchaseToken": old_purchase_token,
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

預付方案整合

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

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

預付方案儲值一律會使用 IMMEDIATE_AND_CHARGE_FULL_PRICE 依比例計費模式,而不需明確設定此模式。系統會立即向使用者收取完整帳單週期的費用,並將授權的有效期延長儲值中指定的期限。

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

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

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

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

預付購買確認

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

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

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

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

開發人員必須讓客戶能輕鬆管理訂閱項目。應用程式應具有設定或設定偏好的畫面連結,方便使用者管理訂閱項目。此連結的範例如圖 4 所示。

本圖中的「Google Play 訂閱服務」按鈕為「管理訂閱項目」連結的範例。
圖 4.「Google Play 訂閱服務」按鈕是「管理訂閱項目」的連結範例。

在這個連結的點按處理常式中新增邏輯,以判斷使用者是否擁有應用程式任何未過期的訂閱項目,其中 expiryTime 為未來的日期,或者 autoRenewing 設為 true

每個訂閱項目的 productId 與您在 Play 管理中心建立訂閱項目時為其指派的產品 ID 相符。如要透過程式判斷現有訂閱項目的 productId,請查詢應用程式的後端,取得與特定使用者相關的訂閱項目清單。

如果使用者有未過期的訂閱項目,您可以將他們導向類似下方的網址,並將「your-sub-product-id」和「your-app-package」分別改成訂閱項目 ID 和應用程式套件資訊:

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

如果使用者在應用程式中沒有任何未過期的訂閱項目,請使用下列網址將他們導向顯示所有其他訂閱項目的頁面,如圖 5 和圖 6 所示:

https://play.google.com/store/account/subscriptions
Play 商店訂閱項目畫面顯示了使用者所有訂閱項目的狀態。
圖 5.Play 商店訂閱項目畫面顯示了使用者所有訂閱項目的狀態。
輕觸訂閱項目查看更多資訊。
圖 6.輕觸訂閱項目可以查看更多資訊。

您可以在 Classy Taxi 範例應用程式中找到訂閱項目連結邏輯的範例程式碼。

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

您可以向使用者提供不同的訂閱層級,例如基本級和進階級。圖 7 顯示提供兩個訂閱層級的畫面:

這個應用程式包含兩個訂閱層級
圖 7.這個應用程式有兩個訂閱層級。

使用者必須能夠存取與圖 7 類似的畫面,以升級或降級訂閱項目。升級或降級訂閱項目時,您可以設定依比例計費模式,該模式確定變更對訂閱者造成的影響。

下表列出可使用的依比例計費模式:

依比例計費模式說明
IMMEDIATE_WITH_TIME_PRORATION 訂閱項目會立即升級或降級。根據費用差額調整任何剩餘時間,並將下一個帳單日期往後推延以計入新的訂閲。此為預設行為。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE 系統會立即升級訂閲項目,帳單週期維持不變。系統會向使用者收取剩餘訂閱期間的費用差額。
IMMEDIATE_WITHOUT_PRORATION 系統會立即升級或降級訂閱項目,並在續訂訂閲項目時收取新的價格。帳單週期維持不變。
DEFERRED 只有在續訂時,系統才會升級或降級訂閲項目。
IMMEDIATE_AND_CHARGE_FULL_PRICE 系統將訂閲項目升級或降級,並立即向使用者收取新授權的全額費用。系統會將之前訂閲項目的剩餘價值,轉用於相同的授權,或者在切換至不同的授權時依比例計算時間。

如果使用者變更訂閱項目的授權,您必須在執行階段指定依比例計算的比率。如果是授權變更,您無法透過 Google Play 管理中心指定預設的依比例計費模式。

如果使用者不是變更訂閱授權,您可以使用透過 Play 管理中心設定的預設依比例計費模式。您也可以在 SubscriptionUpdateParams 中指定依比例計費模式,藉此覆寫此行為。請注意下列限制:

  • 預付方案或自動續約型方案升級、降級或將相同訂閱切換預付方案時,僅允許的依比例計費模式為 IMMEDIATE_AND_CHARGE_FULL_PRICE。如果您指定任何其他依比例計費模式,購買就會失敗,且使用者會看到錯誤訊息。
  • 在同一個訂閱中預付方案切換自動續約型方案時,有效的依比例計費模式為 IMMEDIATE_AND_CHARGE_FULL_PRICEIMMEDIATE_WITHOUT_PRORATION。如果您指定任何其他依比例計費模式,購買就會失敗,且使用者會看到錯誤訊息。

依比例計費範例

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

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

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

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

IMMEDIATE_WITH_TIME_PRORATION
Samwise 的「第 1 層級」訂閱會立即結束。由於他支付了全額月費 (4 月 1 日至 30 日),但在訂閱期間中途進行了升級,因此這個月一半的訂閱費用 ($1 美元) 會套用到新訂閱項目。不過,由於新訂閱項目的費用為每年 $36 美元,$1 美元的抵免餘額只能用於支付 10 天 (4 月 16 日至 25 日) 的費用,因此在 4 月 26 日,系統會針對新訂閲項目向他收取 $36 美元的費用,之後每年的 4 月 26 日再收取 $36 美元。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE
您可以使用這種模式,因為第 2 層級每個時間單位的訂閱價格 (每年 $36 美元 = 每月 $3 美元) 高於第 1 層級每個時間單位的訂閱價格 (每月 $2 美元)。Samwise 的第 1 層級訂閱會立即結束。由於他已支付全額月費,但只使用了一半時間,因此這半個月的訂閱費用 ($1 美元) 會套用到新的訂閱項目。不過,由於新訂閱項目的費用為每年 $36 美元,剩餘 15 天的費用為 $1.50 美元,因此系統會針對新訂閱項目向他收取 $0.50 美元的差額。5 月 1 日系統會針對新的訂閲層級向 Samwise 收取 36 美元,並在之後每年的 5 月 1 日再收取 $36 美元。
IMMEDIATE_WITHOUT_PRORATION
Samwise 的第 1 層級訂閱會立即免費升級為第 2 層級,並且系統會針對新的訂閲層級向他收取 36 美元,之後每年的 5 月 1 日再收取 36 美元。
DEFERRED
Samwise 的第 1 層級訂閱繼續有效,直到 4 月 30 日到期爲止。5 月 1 日,第 2 層級訂閱生效,系統會針對新的訂閲層級向 Samwise 收取 36 美元。
IMMEDIATE_AND_CHARGE_FULL_PRICE
Samwise 的第 1 層級訂閱會立即結束。他的第 2 層級訂閱將於今天開始生效,費用為 36 美元。由於他已支付全額月費,但只使用了一半時間,因此這半個月的訂閱費用 ($1 美元) 會套用到新的訂閱項目。由於新訂閱項目的費用為每年 36 美元,因此訂閱期可再加上一年的 1/36(約 10 天)。因此,下次向 Samwise 收費的時間為從今天起 1 年零 10 天,費用為 36 美元。接下來,系統每年收取 36 美元的費用。

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

應用程式可以使用與推出購買流程相同的步驟,向使用者提供升級或降級服務。不過,在升級或降級時,您必須提供目前的訂閱項目、未來 (升級或降級) 訂閱項目的詳細資料,以及要使用的依比例計費模式等內容,範例如下:

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
            .setOldSkuPurchaseToken("old_purchase_token")
            .setReplaceSkusProrationMode(ProrationMode.IMMEDIATE_AND_CHARGE_FULL_PRICE)
            .build())
    .build();

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

// process purchase results from PurchasesUpdatedListener registered with BillingClient
public void onPurchaseUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
  // check BillingResult
  // process returned Purchase list, e.g. grant entitlement
}

針對立即取代的依比例計費模式,應用程式會在 PurchasesUpdatedListener 中收到新的購買交易。BillingClient.queryPurchasesAsync() 中也會提供該購買交易。收到購買憑證後,請執行與驗證新的購買憑證相同的驗證程序。請務必透過 Google Play 帳款服務程式庫的 Purchases.subscriptions:acknowledge 或 Google Play Developer API 的 BillingClient.acknowledgePurchase() 確認這些購買交易。

Google Play Developer API 會在訂閱資源中傳回 linkedPurchaseToken。請務必讓 linkedPurchaseToken 中提供的憑證失效,以確保舊的憑證無法用來存取服務。請參閱升級、降級和重新訂閱,瞭解處理升級和降級購買的相關資訊。

如果是延遲的取代模式,應用程式會收到對 PurchasesUpdatedListener 的呼叫,其中含有原始訂閱方案的購買交易,以及升級或降級是否成功的狀態。在取代模式生效前,BillingClient.queryPurchasesAsync() 會繼續傳回原有訂閱方案的購買交易。新的方案生效後,queryPurchasesAsync() 會傳回新訂閱項目的購買交易資料,並將 SUBSCRIPTION_RENEWED 通知傳送至安全的後端伺服器。針對延遲的取代模式,強烈建議您聽取這項通知,並使用 Purchases.subscriptions:acknowledge 確認購買。訂閱資源中的 linkedPurchaseToken 可用來判斷應將訂閱後端的哪位使用者更新到新的授權 (如適用)。應用程式不應仰賴使用者開啟應用程式並透過 BillingClient.acknowledgePurchase() 確認,原因在於使用者不一定會在方案變更生效後的三天內開啟應用程式。

透過免費試用或新用戶優惠升級

當使用者升級或降級時,系統會套用免費試用期的資格設定。您可以在 Google Play 管理中心內調整免費試用資格設定。

請注意以下事項:

  • 在應用程式可提供的所有訂閱項目中,如果使用者只能獲得一次免費試用資格,則使用者變更的方案將不會享有免費試用或新用戶優惠。
  • 如果您為每個訂閱產品提供一次免費試用資格,則使用者變更的方案得以享有免費試用或新用戶優惠。

下表說明新舊方案均可享有免費試用、以及使用者在免費試用期內升級的情況下,各種依比例計費模式的行為:

每個應用程式免費試用一次 每個訂閱產品免費試用一次
IMMEDIATE_WITH_TIME_PRORATION 使用者會立即失去免費試用資格。系統會根據費用差額,將剩餘的免費試用期轉換為新訂閱層級的同等免費試用期。 使用者會失去先前的免費試用資格,不過會立即開始新的免費試用期。此外,系統會將舊訂閱層級的剩餘免費試用期轉換為新訂閱層級的同等免費試用期,並加至新的免費試用期。
IMMEDIATE_AND_CHARGE_PRORATED_PRICE

使用者會立即失去免費試用資格。系統接著會向使用者收取剩餘訂閱期的費用差額。下次帳單日期將維持不變。

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

IMMEDIATE_WITHOUT_PRORATION 使用者會立即升級至新訂閲層級。在上一次帳單週期結束前,使用者仍然可以免費試用新的訂閲層級。
延遲 在下次帳單日期之前,使用者仍可免費試用舊訂閱項目。
IMMEDIATE_AND_CHARGE_FULL_PRICE 使用者會立即失去免費試用資格。接著系統會向使用者收取新訂閱項目的費用。下次帳單日期是新的訂閱週期再加上免費試用期的剩餘時間。

要瞭解在每個應用程式免費試用一次的模式中,免費試用期在預設情況下的轉換方式,請試想以下情境:

Maria 訂閱了 Country Gardener 應用程式的線上內容,目前按月訂閱第 1 層級純文字內容版本。這個訂閱項目的費用為每月 10 美元,而她在 4 月 1 日訂閱了這個項目。身為首次訂閱者,她享有 30 天的免費試用期,因此 5 月 1 日需繳清第一筆款項。

4 月 15 日,Maria 選擇升級至第 2 層級的訂閱,內容包含影片更新,費用為每月 $20 美元。第二次訂閱也可享受 30 天的試用期。

以下清單說明各種依比例計費模式的免費試用期轉換方式:

  • IMMEDIATE_WITH_TIME_PRORATION - Maria 的訂閱立即升級至第 2 層級。由於 Maria 在訂閱期中途進行了升級,因此這個月一半的訂閱費用 (以每月 $10 美元計算的 15 天費用) 會套用到新的訂閱項目。不過,由於新訂閱項目的費用為每月 $20 美元,因此這 15 天的餘額只能支付 7.5 天的費用。Maria 不符合免費試用第 2 層級的資格,因此自 4 月 22 日起,將會開始每月收取 20 美元。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE可以使用這種模式,因為第 2 層級每個時間單位的訂閲價格 (每月 $20 美元) 高於第 1 層級每個時間單位的訂閲價格 (每月 $10 美元)。Maria 的第 1 層級訂閱立即升級為第 2 層級,同時也失去免費試用資格。由於 Maria 的下次帳單日期是 5 月 1 日,因此今天她必須支付 4 月下半月的費用 ($10 美元),接著自 5 月 1 日起須每月支付 $20 美元。
  • IMMEDIATE_WITHOUT_PRORATION - Maria 的第 1 層級訂閱立即升級為第 2 層級。Maria 可以免費試用至 4 月 30 日,而且現在可以存取第 2 層級的內容。自 5 月 1 日起,她每月必須支付 20 美元。
  • DEFERRED - Maria 的第 1 層級訂閲將持續至需繳交下一筆款項的 5 月 1 日。第 2 層級的訂閱將於 5 月 1 日生效,並在每月的第一天向 Maria 收取 $20 美元。
  • IMMEDIATE_AND_CHARGE_FULL_PRICE - Maria 的第 1 層級訂閱立即升級為第 2 層級,同時也失去免費試用資格。她今天將被收取 20 美元。由於 Maria 的免費試用期仍有 15 天,因此下次收費日期為今天起 1 個月 + 15 天後,也就是 7 月 1 日。自 7 月 1 日起,她每月必須支付 20 美元。

以下清單說明在開發人員改為允許每個訂閱項目免費試用一次的情況下,會發生什麼轉換行為:

  • IMMEDIATE_WITH_TIME_PRORATION - Maria 的訂閱立即升級至第 2 層級。由於 Maria 在訂閱期中途進行了升級,因此這個月一半的訂閱費用 (以每月 $10 美元計算的 15 天費用) 會套用到新的訂閱項目。不過,由於新的訂閱項目費用為每月 20 美元,因此剩下的 15 天餘額只可支付 7.5 天的費用。Maria 符合免費試用第 2 層級的資格,因此她無須支付另外 37.5 天的費用。自 5 月 22 日起,每月將向她收取 20 美元。
  • IMMEDIATE_AND_CHARGE_PRORATED_PRICE可以使用這種模式,因為第 2 層級每個時間單位的訂閲價格 (每月 $20 美元) 高於第 1 層級每個時間單位的訂閲價格 (每月 $10 美元)。Maria 的第 1 層級訂閱立即升級為第 2 層級,同時也失去免費試用資格。由於 Maria 的下次帳單日期是 5 月 1 日,因此今天她必須支付 4 月下半月的費用 ($10 美元),接著自 5 月 1 日起須每月支付 $20 美元。
  • IMMEDIATE_WITHOUT_PRORATION - Maria 的第 1 層級訂閱立即升級為第 2 層級。在 4 月 30 日之前,Maria 可以免費試用,而且她現在可以存取第 2 層級的內容。
  • DEFERRED - Maria 的第 1 層級訂閲將持續至需繳交下一筆款項的 5 月 1 日。第 2 層級的訂閱將於 5 月 1 日生效,並在每月的第一天向 Maria 收取 $20 美元。
  • IMMEDIATE_AND_CHARGE_FULL_PRICE - Maria 的第 1 層級訂閱立即升級為第 2 層級,同時也失去免費試用資格。她今天將被收取 20 美元。由於 Maria 的免費試用期仍有 15 天,因此下次收費日期為今天起 1 個月 + 15 天後,也就是 7 月 1 日。自 7 月 1 日起,每月將向她收取 20 美元。

依比例計費的建議作法

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

情境 推薦的依比例計費模式 結果
升級至價格更高的層級 IMMEDIATE_AND_CHARGE_PRORATED_PRICE 使用者立即取得存取權,並保留相同的收費週期。
降級至價格更低的層級 DEFERRED 使用者已支付較昂貴層級的費用,因此在下次帳單日期前仍可存取內容。
變更同一層級的重複週期(例如從按月訂閲變更為按年訂閲) DEFERRED 使用者將在下次帳單日期支付新的週期性費用。
在免費試用期內升級,保有免費試用資格 IMMEDIATE_WITHOUT_PRORATION 使用者保有免費試用資格,但在試用期的剩餘時間升級至更高的訂閱層級。
在免費試用期內升級,結束免費試用資格 IMMEDIATE_AND_CHARGE_PRORATED_PRICE 使用者會立即取得新訂閱層級的存取權,但不再享有免費試用資格。

客戶管理

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

使用者取消訂閱項目後,您可以嘗試在應用程式中或透過 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:

  • 使用依比例計費模式 IMMEDIATE_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。

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

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

調整訂閲價格

如要瞭解如何使用 Play 管理中心變更訂閱價格,請參閱 Play 管理中心的說明中心內的文件。

警告:請勿變更透過 Google 訂閱的訂閲價格。

Google Play 可讓您向全球不同地區的使用者販售數位產品,他們使用不同的貨幣,價格考量也各不相同。有時,由於區域成本、貨幣波動或其他原因,您可能會決定調整訂閲價格。

您可以變更任何基本方案或優惠方案的價格,新價格將在一小時內對所有新購買交易生效。

如果使用者訂閱的是預付方案,則一律以目前價格支付儲值金和方案變更。

根據預設,目前訂閱自動續約型方案的使用者不會受到影響,而是改為建立舊版價格同類群組。如有需要,您可以結束同類群組,將基本方案的價格變更為目前的價格。您無法變更現有訂閱者的免費或新用戶優惠階段的價格。

如需有關如何使用舊版價格同類群組的更多資訊,請參閱 Play 管理中心的說明中心

向使用者通知價格變更

每當您變更基本方案的價格時 (尤其是當價格調漲時),您應通知現有訂閱者。

如果您調漲訂閱價格,在 Google Play 開始直接通知價格變更前,您有至少 7 天的時間可以向現有訂閱者發出調價通知。

現有訂閱者有至少 30 天的時間審查價格調漲的情形,並決定是否接受。如果不接受漲價,則在他們支付更高的價格之前,其訂閱會自動取消。

使用者可以在 Play 商店的訂閱畫面上查看價格調漲的情形,其中會顯示類似圖 13 的對話方塊。

用於通知使用者訂閲價格變更的一般對話方塊
圖 13.用於通知使用者訂閲價格變更的範例對話方塊。

Google Play 會將即將發生的所有價格變更直接通知現有訂閱者。

在應用程式中,建議您也通知受影響的使用者,並提供 Play 商店訂閱畫面的深層連結

當您調降訂閱價格時,使用者無需同意變更內容,也不會顯示價格變更對話方塊。從下一個帳單日開始,系統會按照較低的價格向使用者收取費用。

處理使用者確認價格變更的操作

如果使用者接受訂閱價格調漲,或者您調降了價格,則系統會續訂訂閱,處理方式與任何其他續訂操作一樣。此外,您會收到類型為 SUBSCRIPTION_PRICE_CHANGE_CONFIRMEDSubscriptionNotification

價格調漲不被接受時的處理方式

如果使用者在支付更高的價格之前不接受價格調漲,系統會自動取消訂閱,您會收到 SUBSCRIPTION_CANCELED 類型的 SubscriptionNotification。您可以依據「取消訂閱」中所述的方式處理這個事件。

意外價格異動

如果您意外調整了訂閲項目的價格,請立即撤銷價格異動。只要價格在 7 天內恢復,現有的訂閱者就不會收到意外價格異動的通知。請注意,在價格首次變更與價格恢復前的期間內,新訂閱者可能會得到意外的價格。

連續處理兩次價格調整

如果您終止了價格調漲的舊版價格同類群組,之後再次變更價格,則所有符合資格的使用者無需回覆第一次價格變更,因為現在只會套用第二次價格變更。

請確保您一次只調整一個訂閱價格。我們不建議您基於測試目的調整價格。

如果您在七天內兩次變更訂閱價格,受影響的使用者只需要同意最新價格變更。

處理付款遭拒問題

如在帳單週期結束時發生付款問題,在取消訂閲項目之前,Google 會定期嘗試該項續訂一段時間。重試期限最長可達 30 天,再加上任何指定的寬限期長度。在這段時間內,Google 也會傳送電子郵件和通知,請使用者更新付款方式。

付款遭拒時,訂閱項目會先進入寬限期 (如果有啟用)。在寬限期內,使用者仍可存取該訂閱項目。

寬限期結束時,訂閱項目進入帳戶保留狀態,最長可達 30 天。在帳戶保留期內,您可以封鎖訂閱項目的存取權。

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

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

應用程式內通訊

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

Snackbar 通知使用者修正付款問題
圖 14. 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.
                }
            }
        });