發揮 Play 帳款服務整合功能的最大效益

發揮 Play 帳款服務整合功能的最大效益

程式碼研究室簡介

subject上次更新時間:5月 19, 2025
account_circle作者:Fangyi Luo, Steven Natiello

1. 總覽

透過 Google Play 提供的 Play 帳款服務程式庫整合程式碼研究室,您可以改善收益來源,並放心推出應用程式。本結構化程式碼研究室將引導您設定、測試及導入可靠的購買交易處理程序,協助您達成營利目標,並提供更順暢的使用者體驗。

我們會協助您為應用程式和遊戲的訂閱項目和一次性產品設定即時開發人員通知 (RTDN) 和 Play 結帳實驗室。您將瞭解如何減少訂閱者流失、防範詐欺和濫用行為、測試極端情況、模擬、重現及解決潛在問題,以及在不影響使用者情況下,測試優惠和價格異動。

完成課程後,您就能開始實施挽回策略、迅速解決整合問題、提高投資報酬率、提供優質體驗,並放心推出應用程式和更新。

必要條件

課程內容

  • 如何妥善管理購買生命週期,運用提升購買轉換和顧客留存率的策略,協助您達成最佳成長
  • 如何使用 Google Cloud Pub/Sub 設定即時開發人員通知 (RTDN),以便導入回訪廣告活動和其他生命週期管理策略
  • 如何在後端伺服器上設定接收器,以便透過精確的追蹤和授權,安全地處理通知,降低不當退款或詐欺和濫用風險
  • 如何使用 Play 帳款服務研究室測試整合作業並模擬錯誤,以便改善使用者體驗,同時降低開發成本

軟硬體需求

2. 訂閱和一次性消費的營利策略

透過應用程式販售數位產品時,成功的營利策略必須考量使用者體驗,包括一次性購買和訂閱。順暢的體驗可提高消費者購買意願,並減少流失率。

一次性消費或訂閱項目的一般購買流程會涉及多個階段:

  1. 使用者瀏覽要購買的商品。
  2. 啟動購買流程,讓使用者完成購買和付款程序。
  3. 通知伺服器完成購買交易
  4. 在伺服器上驗證購買交易。
  5. 將內容提供給使用者。
  6. 確認提交內容。如果是消耗性產品,請在適當時間消耗購買項目,讓使用者可以再次購買該商品。

您可以透過應用程式內整合,啟動購買流程及管理這類使用者體驗,但後端必須能掌握使用者購買授權的最新狀況。如要追蹤購買交易,及管理跨平台授權等使用者體驗的其他面向,這一點至關重要。

即時開發人員通知 (RTDN) 是辨識購買交易生命週期中不同階段的絕佳方式,可有效做為即時成效追蹤工具,以及用於實施訂閱者回訪策略的工具。

舉例來說,假設您的使用者剛購買新商品或剛錯過付款,因此訂閱項目進入寬限期。有了適當的 RTDN,您就能即時 (或幾乎即時) 辨識使用者的狀態變更,並採取適當行動,例如讓使用者更積極地與他們剛購買的商品互動,或是傳送提醒電子郵件,要求他們更新付款詳細資料,以便繼續訂閱。

即使使用者的用戶端發生問題,RTDN 也是新增其他伺服器端控管機制的絕佳方式,有助於管理購買交易。舉例來說,使用者成功完成購買交易且收到 Google 的確認通知,但在使用者裝置和應用程式透過購買事件監聽器收到購買通知前,裝置就失去網路連線。使用 RTDN 時,您會透過伺服器收到獨立通知,讓您能夠辨識購買交易,並在無須依賴用戶端問題的情況下授予使用者授權,確保購買交易過程可靠。

如要進一步瞭解目前支援的所有 RTDN 類型,請參閱這篇文章。每種 RTDN 類型都會顯示不同的購買狀態。請務必實作對應的處理機制,確保在您的用途中能妥善處理。本程式碼研究室將逐步示範如何在安全的後端伺服器中處理 RTDN 訊息,包括接收訊息、驗證購買交易,以及在使用者成功在應用程式中完成購買交易時,將授權授予正確的使用者。接下來,我們將示範如何為應用程式設定 RTDN。

3. 設定即時開發人員通知 (RTDN)

即時開發人員通知 (RTDN) 會利用 Google Cloud Pub/Sub,讓您能立即對購買狀態變更做出回應。Cloud Pub/Sub 是一項全代管的即時訊息服務,可在不同應用程式之間收發訊息。Google Play 使用了 Cloud Pub/Sub,會根據訂閱主題發布推播通知。

如要啟用 RTDN,您必須先使用自己的 Google Cloud Platform (GCP) 專案設定 Cloud Pub/Sub,然後為應用程式開啟通知功能。如果您不熟悉 GCP 和 Cloud Pub/Sub,請參閱快速入門指南

建立主題

如要開始接收通知,您必須建立一個 Google Play 應發布通知的主題。如要建立主題,請按照「建立主題」中的指示操作。

建立 Pub/Sub 訂閱項目

若要接收發布至某項主題的訊息,您必須為該主題建立一個 Pub/Sub 訂閱項目。如要建立 Pub/Sub 訂閱項目,請按照下列指示操作:

  1. 請參閱 Cloud Pub/Sub 訂閱者指南,瞭解如何將訂閱項目設定為推送式訂閱項目接收式訂閱項目。在本程式碼研究室中,我們將使用提取式訂閱項目,這類項目需要透過安全的後端伺服器,向 Cloud Pub/Sub 伺服器發出要求來擷取訊息。
  1. 按照「新增訂閱項目」中的指示建立訂閱項目。

授予主題的發布權限

您必須授予 Google Play 權限,才能讓 Cloud Pub/Sub 針對您的主題發布通知。

  1. 開啟 Google Cloud 控制台
  2. 選取專案,然後在搜尋列中搜尋「Pub/Sub」,並前往 Pub/Sub 設定頁面。搜尋並前往 Pub/Sub 設定頁面
  3. 找出您的主題,然後開啟權限設定。開啟權限設定
  4. 按一下「ADD PRINCIPAL」新增服務帳戶 google-play-developer-notifications@system.gserviceaccount.com,並授予「Pub/Sub Publisher」角色。新增服務帳戶 google-play-developer-notifications@system.gserviceaccount.com,並授予 Pub/Sub 發布者角色
  5. 按一下「儲存」即可完成主題設定。按一下「儲存」即可完成主題設定。

為應用程式啟用 RTDN

瞭解如何設定即時開發人員通知 (RTDN),大幅提升 Play 帳款服務整合功能。您可以透過個人化訊息提高購買可靠度,並防範詐欺和濫用行為,進而提高整體投資報酬率。

RTDN 會直接從 Google Play 提供即時伺服器對伺服器更新,用於處理重要事件,例如訂閱續約、新購買交易和付款問題。這類事件可協助後端系統自動與使用者授權的實際狀態同步,超越用戶端限制,讓您能即時做出適當回應。

如何為應用程式啟用即時開發人員通知:

  1. 開啟 Google Play 管理中心
  2. 選取應用程式。
  3. 依序前往「透過 Play 營利」>「營利設定」
  4. 捲動至「即時開發人員通知」部分。
  5. 勾選「啟用即時通知」
  6. 在「主題名稱」欄位中,輸入您先前設定的完整 Cloud Pub/Sub 主題名稱。主題名稱的格式應為 projects/{project_id}/topics/{topic_name},其中 project_id 是專案的專屬 ID,topic_name 是先前建立的主題名稱。
  7. 按一下「傳送測試訊息」送出測試訊息。測試發布有助於確保已正確完成各項設定。如果測試發布成功,系統會顯示一則訊息,說明測試發布成功。如果這個主題附加了一個訂閱項目,則您應收到該測試訊息。如果是提取式訂閱項目,請前往 Cloud 控制台中的訂閱項目,按一下「查看訊息」,然後繼續提取訊息。您應確認接收到的任何訊息,以避免出現 Cloud Pub/Sub 重複傳遞的情況。如果是推播訂閱項目,請確認測試訊息是否已傳遞至推播端點。成功的回應代碼可用來確認訊息。如果發布失敗,系統會顯示錯誤。請確認主題名稱正確無誤,而且該 google-play-developer-notifications@system.gserviceaccount.com 服務帳戶擁有該主題的 Pub/Sub 發布者存取權。
  8. 選擇要接收的通知類型。
  • 接收訂閱項目和所有作廢交易的通知:接收與訂閱項目和作廢交易相關的即時開發人員通知。你不會收到一次性產品購買交易的通知。
  • 接收訂閱項目和一次性產品的所有通知:接收所有訂閱和作廢交易事件的通知。您也會收到一次性產品購買事件,例如 ONE_TIME_PRODUCT_PURCHASEDONE_TIME_PRODUCT_CANCELED。如要進一步瞭解這些購買事件,請參閱「一次性消費生命週期」。

a266e5dec5c93cd8.png

  1. 按一下 [儲存變更]。

您現在已完成應用程式的即時開發人員通知設定,因此可以使用相關工具解決常見問題,例如透過挽回訊息解決使用者流失問題,或防範詐欺和濫用行為。在下一節中,我們會在安全的後端伺服器中建構訂閱者,以便取用傳送至 Cloud Pub/Sub 主題的訊息。

4. 接收通知

為了在應用程式中提供最佳使用者體驗,請務必讓後端伺服器保持購買交易狀態的最新狀態。舉例來說,如果使用者在應用程式中成功完成付款購買交易,則應盡快將內容傳送至使用者的帳戶。

這需要及時偵測並處理完成的交易。Play 帳款服務程式庫提供多種方法,可在應用程式中偵測購買交易。偵測到完成的購買交易後,應用程式必須通知後端伺服器驗證購買交易,將內容授予正確的使用者,然後通知 Google 已處理購買交易。不過,應用程式可能會因為各種原因,未能及時偵測到購買交易。舉例來說,使用者可以成功完成購買交易並收到 Google 的確認通知,但在裝置和應用程式透過 Play 帳款服務程式庫介面收到通知前,裝置就失去網路連線。RTDN 提供其他伺服器端控制項,即使使用者的用戶端發生問題,也能協助您管理購買交易。RTDN 會在購買狀態變更時,向您的伺服器發送獨立通知,讓您透過第二個路徑幾乎立即得知購買狀態變更,不受潛在的用戶端問題影響,確保購買流程更可靠。

在本節中,您將使用 Cloud Pub/Sub 用戶端程式庫建立訂閱器,以便取用傳送至 Cloud Pub/Sub 主題的訊息。這些程式庫提供多種語言。在後續章節中,我們會新增訂閱者來驗證購買交易、授予正確使用者的授權,並在伺服器上確認/使用購買交易。在本程式碼研究室中,我們使用的是 Java。

每次發布至 Cloud Pub/Sub 主題的內容都會包含一個 Base64 編碼的資料欄位。

{
 "message": {
   "attributes": {
     "key": "value"
   },
   "data": "eyAidmVyc2lvbiI6IHN0cmluZywgInBhY2thZ2VOYW1lIjogc3RyaW5nLCAiZXZlbnRUaW1lTWlsbGlzIjogbG9uZywgIm9uZVRpbWVQcm9kdWN0Tm90aWZpY2F0aW9uIjogT25lVGltZVByb2R1Y3ROb3RpZmljYXRpb24sICJzdWJzY3JpcHRpb25Ob3RpZmljYXRpb24iOiBTdWJzY3JpcHRpb25Ob3RpZmljYXRpb24sICJ0ZXN0Tm90aWZpY2F0aW9uIjogVGVzdE5vdGlmaWNhdGlvbiB9",
   "messageId": "136969346945"
 },
 "subscription": "projects/myproject/subscriptions/mysubscription"
}

將 Base64 編碼的資料欄位解碼後,DeveloperNotification 會包含以下欄位:

{
 "version": string,
 "packageName": string,
 "eventTimeMillis": long,
 "oneTimeProductNotification": OneTimeProductNotification,
 "subscriptionNotification": SubscriptionNotification,
 "voidedPurchaseNotification": VoidedPurchaseNotification,
 "testNotification": TestNotification
}

詳情請參閱即時開發人員通知參考資料

以下是 NotificationReceiver 的範例程式碼,可讓安全的後端伺服器處理 Pub/Sub 訊息。如要向 Security Command Center 進行驗證,請設定應用程式預設憑證,請參閱「為本機開發環境設定驗證」。

import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.Base64;
import org.json.JSONObject;

/** Real-time developer notifications receiver. */
public class NotificationReceiver {

 private NotificationReceiver() {}

 /*
  * Receive notification messages from the subscription.
  *
  * @param projectId The project ID of your Google Cloud Project.
  * @param subscriptionId The subscription ID of the subscriber to the pub/sub topic.
  */
 public static void receiveNotificationMessages(String projectId, String subscriptionId) {
   ProjectSubscriptionName subscriptionName =
       ProjectSubscriptionName.of(projectId, subscriptionId);

   try {
     Subscriber subscriber =
         Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
     // Start the subscriber.
     subscriber.startAsync().awaitRunning();

     subscriber.awaitTerminated();
   } catch (IllegalStateException e) {
     System.out.println("Subscriber stopped: " + e);
   }
 }

 static class NotificationMessageReceiver implements MessageReceiver {

   @Override
   public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
     // Decode the data into a String from the message data field.
     String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
     // Parse the String into a JSON object.
     JSONObject messageJson = new JSONObject(jsonString);

     // Fetch the value for certain fields.
     String version = messageJson.getString("version");
     String packageName = messageJson.getString("packageName");
     System.out.println("version: " + version);
     System.out.println("packageName: " + packageName);

     // Validate the purchase and grant the entitlement as needed.
     // More details in the following sections.
     // ......

     // Acknowledge the message to avoid repeated delivery.
     consumer.ack();
   }
 }
}

您現在已擁有通知接收器,可在安全的後端伺服器中取用傳送至 Cloud Pub/Sub 主題的訊息。在後續章節中,我們將說明在後端伺服器中處理 RTDN 訊息的最佳做法。

5. 在應用程式的購買流程中附加使用者 ID

當伺服器收到有關購買狀態更新的 RTDN 訊息時,就需要知道哪位使用者完成購買交易,以便處理相關事宜,例如將內容傳送給正確的使用者。如要達成這項目標,您可以在應用程式中啟動購買流程時,使用 obfuscatedAccountId 附加購買者所使用的任何使用者 ID。舉例來說,您可以將系統中使用者登入資訊的經過模糊處理的版本,當做使用者 ID。設定這個參數有助於 Google 偵測詐欺行為。此外,您也可以透過這項功能,確保購買交易歸給正確的使用者,詳情請參閱為使用者授予授權

以下是範例程式碼,說明如何在應用程式中啟動購買流程時,透過設定 obfuscatedAccountId 附加使用者 ID。

// An activity reference from which the billing flow will be launched.
Activity activity = ...;
// A user identifier, e.g. an obfuscated user id in your system.
String obfuscatedAccountId = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
            // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // set the offer token to specify the offer to purchase when applicable, e.g., subscription products
            // .setOfferToken(offerToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .setObfuscatedAccountId(obfuscatedAccountId)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

如您在下一節所見,購買流程中設定的使用者 ID 會納入購買交易,並可用於向正確使用者授予授權。

6. 授權前請先驗證購買交易

在本節中,我們將說明在安全的後端伺服器中授予授權前,驗證購買交易的最佳做法。

使用者購買一次性產品後,安全後端伺服器中的 Pub/Sub 訂閱者會收到 Pub/Sub 訊息。您應在後端伺服器中執行下列操作:

  1. 從 Pub/Sub 訊息解析 purchaseToken。您應為所有購買交易維護所有 purchaseToken 值的記錄。
  2. 確認目前購買交易的 purchaseToken 值沒有與先前的任何 purchaseToken 值重複。purchaseToken 全域唯一,因此您可以放心將這個值做為資料庫中的主鍵。
  3. 使用 Google Play Developer API 中的 purchases.products:get 端點,向 Google 驗證購買交易是否符合規定。
  1. 如果購買交易合規,且從未使用過,就可以授予對交易內容的權限。
  2. 只有在購買狀態為 PURCHASED 時才可授權,並務必正確處理 PENDING 購買交易。詳情請參閱「處理未完成的交易」。

以下程式碼範例會為 Google Play Developer API 建立 API 用戶端。我們稍後會用它來進行 API 呼叫。

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;

/** Helper class to initialize the publisher APIs client library. */
public class AndroidPublisherHelper {
 /* Your application name */
 private static final String APPLICATION_NAME = "YourApplicationName";

 /* Load credentials from a JSON key file. Replace with the actual path to your downloaded service
  * account key file.
  */
 private static final String RESOURCES_CLIENT_SECRETS_JSON =
     "/path/to/your/service_account_key.json";

 /** Global instance of the JSON factory. */
 private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

 /* The API client */
 private static final AndroidPublisher ANDROID_PUBLISHER = init();

 /**
  * Performs all necessary setup steps for running requests against the API.
  *
  * @return the {@link AndroidPublisher} service
  */
 private static AndroidPublisher init(){
   try {
     // Authorization.
     Credential credential =
         GoogleCredential.fromStream(
                 AndroidPublisherHelper.class.getResourceAsStream(RESOURCES_CLIENT_SECRETS_JSON))
             .createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));

     HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

     // Set up and return API client.
     return new AndroidPublisher.Builder(httpTransport, JSON_FACTORY, credential)
         .setApplicationName(ApplicationConfig.APPLICATION_NAME)
         .build();
   } catch (GeneralSecurityException | IOException ex) {
     throw new RuntimeException("fail to initialize the publisher APIs client library", ex);
   }
 }
}

接著,我們會新增邏輯來進行 API 呼叫,並修改先前建構的接收器,以便驗證購買交易,並將授權授予正確的使用者。

AndroidPublisherHelper 中,新增下列方法,從 Google Play Developer API 中的 Purchases.products:get 端點擷取 ProductPurchase。

 /* Fetch the ProductPurchase for the one-time product purchase from
  * Purchases.products.get endpoint in the Google Play Developer API
  */
 public static ProductPurchase executeProductPurchasesGet(
     String packageName, String sku, String purchaseToken) {
   try {
     ProductPurchase productPurchase =
         ANDROID_PUBLISHER.purchases().products().get(packageName, sku, purchaseToken).execute();
     return productPurchase;
   } catch (IOException ex) {
     log.error("Exception was thrown while getting a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to fetch the purchase in case of transient failures.
     return null;
   }
 }

NotificationMessageReceiver 中,根據通知中的資料驗證購買交易,並將授權授予系統中的正確使用者。您應持續追蹤伺服器中的 purchaseToken,以免重複處理。

 @Override
 public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
   // Decode the data into a String from the message data field.
   String jsonString = new String(Base64.getDecoder().decode(message.getData().toStringUtf8()));
   // Parse the String into a JSON object.
   JSONObject messageJson = new JSONObject(jsonString);

   // Fetch the value for certain fields.
   String version = messageJson.getString("version");
   String packageName = messageJson.getString("packageName");

   // Process notification data based on your business requirements.
   // Process oneTimeProductNotification in the message.
   JSONObject oneTimeProductNotificationJson =
       messageJson.getJSONObject("oneTimeProductNotification");
   if (oneTimeProductNotificationJson != null) {
     String purchaseToken = oneTimeProductNotificationJson.getString("purchaseToken");
     String sku = oneTimeProductNotificationJson.getString("sku");
     int notificationType = oneTimeProductNotificationJson.getInt("notificationType");

     if (notificationType == 1) {
       // ONE_TIME_PRODUCT_PURCHASED - A one-time product was successfully purchased by a user.
       // Verify that the purchaseToken value does not match any previous purchaseToken values in
       // your backend system to avoid duplicate processing.
       ......
       // Fetch the ProductPurchase from Purchases.products.get endpoint
       ProductPurchase productPurchase =
         AndroidPublisherHelper.executeProductPurchasesGet(packageName, sku, purchaseToken);
       if (productPurchase != null && productPurchase.getPurchaseState() == 0) {
         // The purchase is valid and in PURCHASED state.

         // The account Id set in the App when launching the billing flow.
         String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
         // Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
         // system.
       ......
       }
     }
     // Process subscriptionNotification in the message.
     JSONObject subscriptionNotificationJson = messageJson.getJSONObject("subscriptionNotification");
     if (subscriptionNotificationJson != null) {
       ......
     }
     // Process other notification data in the message as needed.
     ......
   }

   // Acknowledge the message to avoid repeated delivery.
   consumer.ack();
 }

7. 通知 Google 購買交易已處理完畢

授權後,您應透過安全的後端伺服器,呼叫 Play Developer API 中的 purchases.products:consumepurchases.products:acknowledge 端點,以便消耗消耗性產品或確認非消耗性產品,通知 Google 已處理購買交易。

AndroidPublisherHelper 中,新增下列方法,以便呼叫 Google Play Developer API 中的 purchases.products:consumepurchases.products:acknowledge

 /* Consume the one-time product purchase by calling
  * Purchases.products.consume endpoint in the Google Play Developer API
  */
 public static void executeProductPurchasesConsume(
     String packageName, String sku, String purchaseToken) {
   try {
     ANDROID_PUBLISHER
       .purchases().products().consume(packageName, sku, purchaseToken).execute();
   } catch (IOException ex) {
     log.error("Exception was thrown while consuming a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly consumed in case of transient failures.
   }
 }

 /* Acknowledge the one-time product purchase by calling
  * Purchases.products.acknowledge endpoint in the Google Play Developer API
  */
 public static void executeProductPurchasesAcknowledge(
     String packageName, String sku, String purchaseToken) {
   try {
     ANDROID_PUBLISHER
       .purchases().products().acknowledge(packageName, sku, purchaseToken, new ProductPurchasesAcknowledgeRequest()).execute();
   } catch (IOException ex) {
     log.error("Exception was thrown while acknowledging a product purchase", ex);
     // It is recommended to apply some retry mechanism, such as exponential backoff, to ensure the purchase is correctly acknowledged in case of transient failures.
   }
 }

NotificationMessageReceiver 中,在後端伺服器中授予授權後,消耗消耗性產品購買交易,或確認非消耗性產品購買交易。

 @Override
 public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
   ......
       String obfuscatedExternalAccountId = productPurchase.getObfuscatedExternalAccountId();
       // Grant the entitlement to the correct account for obfuscatedExternalAccountId in your
       // system.
       ......
       // If the product is a consumable product, consume the purchase.
       AndroidPublisherHelper.executeProductPurchasesConsume(packageName, sku, purchaseToken);
       // Or if the product is a non-consumable product, acknowledge the purchase.
       // AndroidPublisherHelper.executeProductPurchasesAcknowledge(packageName, sku, purchaseToken);
  ......

 }

確認為必要動作,因為這可通知 Google Play,使用者已取得購買交易的授權。您應在授權後立即確認購買交易。

做得好!您已成功整合即時開發人員通知,可如本程式碼研究室所示,進行可靠的購買交易處理。為了確保一切正常運作,我們將介紹 Play Billing Lab。這是一項方便使用者使用的工具,可協助您測試 Play 帳款服務整合。

8. 使用 Play Billing Lab 進行測試

為了確保順利推出,您應在整個開發過程中測試整合。Play 帳款服務研究室是一款免費的 Android 應用程式,可協助開發人員測試整合 Google Play 結帳系統的功能,提供簡單又方便的測試方式,讓開發人員更有信心地快速整合並推出應用程式。

Play 帳款資料實驗室提供多種測試功能,協助您測試各種情境,包括:

我們會持續在 Play Billing Lab 應用程式中新增測試功能。您可以從 Play 商店下載並安裝 Play Billing Lab,也可以參閱「測試您的整合」一文,進一步瞭解如何使用 Play Billing Lab 進行測試。

使用 Play Billing Lab 測試 BillingResponseCode

將應用程式與 Play 帳款服務程式庫整合時,測試所有 BillingResponseCode 流程通常是一大挑戰,因為您無法有效控制 Play 商店和 Play 後端之間的通訊。Play 帳款資料庫實驗室應用程式中的回應模擬器功能,可讓您為 Play 帳款資料庫設定錯誤代碼回應,以便測試各種複雜的錯誤情況。

舉例來說,您在應用程式中實作邏輯,在應用程式偵測到成功購買交易後,即可使用購買交易。您想測試以下情境:應用程式因網路故障而無法使用購買交易,後端伺服器中的 RTDN 接收器會接收訊息並正確處理購買交易。您可以利用回應模擬器模擬測試情境。以下將引導您透過 Play Billing Lab 回應模擬器進行測試。

使用回應模擬器進行測試

使用回應模擬器進行測試時,應用程式會與 Play Billing Lab 通訊,取得您在 Play Billing Lab 回應模擬器中設定的回應代碼。

啟用 Play 帳款服務程式庫的計費覆寫測試

如要啟用回應模擬器與應用程式之間的通訊,您必須先在應用程式中啟用 Play 帳款服務程式庫的結帳覆寫測試。如要執行這項操作,請將下列中繼資料標記新增至應用程式的 AndroidManifest.xml 檔案。

<manifest ... >
  <application ... >
    ...
     <meta-data
      android:name="com.google.android.play.largest_release_audience.NONPRODUCTION"
      android:value="" />
    <meta-data
      android:name="com.google.android.play.billingclient.enableBillingOverridesTesting"
      android:value="true" />
  </application>
</manifest>

使用更新後的 AndroidManifest.xml 檔案建構應用程式。您的應用程式現在已可使用 Play Billing Lab 回應模擬器。

在測試後將應用程式部署至實際環境時,請使用不含這些中繼資料標記的獨立 AndroidManifest.xml 檔案,或是確保已從 AndroidManifest.xml 檔案中移除這些標記。

模擬 Play 帳款服務程式庫錯誤

如要使用模擬的 Google Play Billing Library 錯誤進行測試,請先在 Play Billing Lab 應用程式中設定回應代碼,然後在應用程式中執行測試。

設定回應代碼

  1. 使用應用程式的授權測試人員帳戶登入 Play Billing Lab 應用程式。下圖顯示 Play Billing Lab 資訊主頁,包括回應模擬器資訊卡。

Play Billing Lab 資訊主頁搭配回應模擬器

  1. 按一下回應模擬器資訊卡上的「管理」,前往回應模擬器畫面。
  2. 出現提示時,允許 Play Billing Lab 發送通知,以便查看應用程式的連線狀態。
  3. 啟用「模擬 Google Play Billing Library 回應」切換鈕 (如果尚未啟用)。

c841baa4c96bf306.png

  1. 選取要測試的 Play Billing 程式庫 API 回應代碼。如要模擬消費購買交易的錯誤,請選取 consumeAsync API 的錯誤代碼。系統會自動儲存您的選項。回應模擬器現在已準備好將所選回應代碼傳送至應用程式。

測試應用程式

您現在可以測試應用程式,確認在設定的錯誤情境中,一切是否都能正常運作。開啟應用程式並觸發 Play 帳款服務程式庫 API 方法。如果應用程式發出 consumeAsync 呼叫來使用購買交易,應用程式會收到您剛剛設定的錯誤代碼。您可以根據錯誤代碼驗證應用程式是否正常運作,以及後端伺服器是否正確處理購買交易。

測試完成後,只要關閉「模擬 Google Play Billing Library 回應」切換鈕,即可停止模擬回應。

如要進一步瞭解如何使用 Play Billing Lab 進行測試,請參閱說明中心的這篇文章,瞭解如何使用授權測試人員測試應用程式內結帳功能。

9. 恭喜!

您已完成本程式碼研究室,現在可以採取策略性做法來提升應用程式營利成效,進而改善使用者體驗,提高使用者滿意度、購買轉換率和訂閱者流失率。

您可以利用即時開發人員通知和 Play Billing Lab 隨附應用程式,主動處理一次性購買交易訂閱項目的購買交易生命週期事件。

有了這些工具,您就能有效實施吸引回流的策略、迅速解決整合問題,進而改善使用者體驗和收益來源,並放心推出應用程式或遊戲。

完成這個程式碼研究室後,您現在已具備管理整個購買歷程的相關技能,並能透過 Play 帳款服務研究室嚴格測試導入作業,確保使用者享有流暢的體驗,並充分發揮在 Google Play 的營利潛力。