運用區域產品價格,開拓新市場

1. 簡介

在本程式碼研究室中,您將專注於建立買斷制產品、定義購買選項、設定特定區域的價格,以及測試買斷制產品的購買流程。

觀眾

本程式碼研究室適用於想使用 Play 管理中心管理一次性產品目錄的 Android 應用程式開發人員。

課程內容...

  • 單次產品物件模型
  • 瞭解如何瀏覽及使用 Google Play 管理中心,管理一次性產品目錄。
  • 如何免費將買斷制產品詳細資料翻譯成各種語言。
  • 如何為一次性產品設定區域供應情形和價格
  • 如何使用 Play 帳款服務程式庫 API 查詢一次性產品詳細資料。
  • 如何使用 Play Billing Lab 測試一次性產品。

事前準備

2. 買斷制產品首映

單次產品物件模型可讓您更有彈性地銷售產品,並降低管理這類產品的複雜度。物件模型會將銷售內容與銷售方式分開,因此同一項授權可有多個價位,並以不同方式向使用者行銷。物件模型有三個階層:

  • 單次產品:產品物件是指使用者要購買的產品。
  • 購買選項:用於定義向使用者授權的方式、授權價格,以及產品供應區域。一項產品可以有多個購買選項,在不同區域提供不同價格。
  • 優惠 - 優惠會影響所連結購買選項的價格,可用於模擬折扣或預購。一個購買選項可有多項優惠。

下圖顯示一次性產品物件模型。

codelab-otp-model.png 圖 1:單次物件模型。

詳情請參閱買斷制產品總覽

3. 建構範例應用程式

本程式碼研究室會使用 Android 範例應用程式,說明如何管理一次性產品。這個範例應用程式是功能齊全的 Android 應用程式,提供完整原始碼,可展示下列各方面:

  • 將應用程式與 PBL 整合
  • 擷取一次性產品和相關購買選項
  • 使用區域價格執行購買流程

以下示範影片顯示範例應用程式部署及執行後的樣貌和行為。

如果您已熟悉一次性產品和 Play 帳款服務程式庫 (PBL),可以下載範例應用程式並試用。

必備條件

建構及部署範例應用程式前,請先完成下列步驟:

建構

這個建構步驟的目標是產生範例應用程式的已簽署 Android App Bundle 檔案。

如要產生 Android 應用程式套件,請按照下列步驟操作:

  1. GitHub 下載範例應用程式
  2. 建構範例應用程式。建構前,請先變更範例應用程式的套件名稱,然後再建構。如果 Play 管理中心中還有其他應用程式的套件,請確保您為範例應用程式提供的套件名稱是專屬的。

    注意:建構範例應用程式只會建立 APK 檔案,可用於本機測試。不過,由於產品尚未在 Play 管理中心設定,因此執行應用程式不會擷取產品和價格。
  3. 產生已簽署的 Android App Bundle。
    1. 產生上傳金鑰和 KeyStore
    2. 使用上傳金鑰簽署應用程式
    3. 設定 Play 應用程式簽署功能

接下來,請將 Android 應用程式套件上傳至 Google Play 管理中心。

4. 在 Play 管理中心建立一次性產品

如要在 Google Play 管理中心建立一次性產品,您必須在 Play 管理中心擁有應用程式。在 Play 管理中心建立應用程式,然後上傳先前建立的已簽署應用程式套件。

建立應用程式

如要建立應用程式,請按照下列步驟操作:

  1. 使用開發人員帳戶登入 Google Play 管理中心
  2. 按一下「建立應用程式」,開啟「建立應用程式」頁面。
  3. 輸入應用程式名稱、選取預設語言,以及其他應用程式相關詳細資料。
  4. 按一下「建立應用程式」,即可在 Google Play 管理中心建立應用程式。

現在可以上傳範例應用程式的已簽署應用程式套件。

上傳已簽署的應用程式套件

  1. 將已簽署的應用程式套件上傳至 Google Play 管理中心的內部測試群組。上傳後,您才能在 Play 管理中心設定營利相關功能。
  2. 依序點選「測試及發布」>「測試」>「內部測試版本」>「建立新版本」
  3. 輸入發布版本名稱,然後上傳已簽署的 APK 檔案。
  4. 依序點選「下一步」和「儲存並發布」

現在可以建立單次產品了。

建立一次性產品

如何建立單次產品:

  1. Google Play 管理中心的左側導覽選單中,依序前往「透過 Google Play 營利」 >「產品」 >「單次產品」
  2. 按一下「建立單次產品」
  3. 輸入下列產品詳細資料:
    • 產品 ID:輸入專屬 ID。例如 trending_movie_1
    • (選用) 標記:新增相關標記。
    • 名稱:輸入產品名稱。例如 Product Movie
    • 說明:輸入產品說明。例如 Product Description
    手動翻譯產品名稱和說明
    根據預設,產品名稱和說明會以英文 (美國) - en-US 顯示。你也可以手動輸入其他語言的名稱和說明。如要輸入詳細資料,請按一下「管理其他語言版本的翻譯內容」,選取要輸入翻譯文字的語言,然後按一下「套用」。下圖顯示「管理翻譯」選項:manage-translations.png圖 2:管理翻譯。

    所選語言會顯示在語言下拉式選單中。選取每種語言,然後以所選語言輸入相應名稱和說明。你也可以免費自動翻譯產品名稱和說明。詳情請參閱本程式碼實驗室的「翻譯一次性產品」一節。

    注意:在本程式碼實驗室中,您可以略過設定「圖示」欄位和「稅金、法規遵循和計畫」部分。
  4. 點選 [下一步]。
  5. 新增購買選項,並設定區域供應情形。單次產品至少須有一個購買選項,用於定義授權方式、價格和區域供應情形。在本程式碼研究室中,我們將為產品新增標準的「購買」選項。

    在「購買選項」部分,輸入下列詳細資料:
    • 購買選項 ID:輸入專屬 ID。例如 buy-movie
    • 交易類型:選取「購買」
    • (選用) 標記:新增這個購買選項專屬的標記。
    • (選用) 按一下「進階選項」,設定進階選項。在本程式碼研究室中,您可以略過進階選項設定。
  6. 接著,您必須設定購買選項的區域供應情形和價格。在區域供應情形中,你可以指定產品的供應區域,包括尚未發布應用程式的區域。根據預設,購買選項會在所有地區提供。

    在「供應情形和價格」部分中,按一下「編輯供應情形和存取權」>「設為『不適用』」。請注意,所有區域預設都會設為「可用」
    1. 選取 FranceSpainUnited States 以外的所有國家/地區,然後按一下「設為『不適用』」
    2. 從「所有區域」下拉式選單中,選取「適用國家/地區和區域」。系統只會顯示您在上一步選取的國家/地區。
    3. 針對每個適用國家/地區,點選「價格」欄中的編輯圖示,系統會顯示對話方塊,供你編輯價格。輸入並儲存下列價格:
      • 在「France」中輸入 10 歐元
      • 在「」Spain中輸入 8 歐元
      • 在「United States」中輸入 13 美元
  7. 按一下「啟用」。這樣一來,單次產品就會提供「購買」購買選項。

注意:系統會根據使用者的 Play 國家/地區設定,顯示區域價格幣別。舉例來說,如果使用者的 Play 國家/地區設定為法國,系統就會以歐元顯示單次產品價格。

一次性產品建立影片

以下影片會逐步說明先前所述的一次性產品建立步驟。

新增租借購買選項

現在,請為先前建立的單次產品新增租借購買選項。

  1. Google Play 管理中心的左側導覽選單中,依序前往「透過 Google Play 營利」 >「產品」 >「單次產品」
  2. 找出在先前步驟中建立的產品 ID 為 trending_movie_1 的產品,然後按一下向右箭頭。
  3. 按一下「新增購買選項」
  4. 在「購買選項」部分,輸入下列詳細資料:
    • 購買選項 ID:輸入 rent-movie
    • 交易類型:選取「租借」
    • 租借期限:選取 48 小時。
    • 租借品啟用期限:選取 24 小時。
    • (選用) 標記:新增這個購買選項專屬的標記。
    • (選用) 按一下「進階選項」,設定進階選項。在本程式碼研究室中,您可以略過進階選項設定。
  5. 接著,與購買選項類似,設定租借購買選項的區域供應情形。請參閱上一節的步驟 6 和 7。設定區域價格時,請為租借設定不同價格。例如:
    • France - 5 歐元
    • Spain - 4 歐元
    • United States - 7 美元。

5. 翻譯一次性產品詳細資料

您可以使用 Google Play 管理中心的機器翻譯功能,免費翻譯產品名稱和說明。

如要翻譯標題和說明,請按照下列步驟操作:

  1. Google Play 管理中心,依序前往左側導覽選單的「拓展使用者」 >「翻譯」 >「商店和應用程式內產品」
  2. 按一下「建立訂單」
  3. 選取「免費機器翻譯」選項,然後按一下「下一步」
  4. 從「Translate to」語言中,選取「French - fr-FR」和「Spanish -es-ES」,然後按一下「Next」
  5. 選取「一次性產品和訂閱項目」,然後按一下「翻譯並查看譯文」。系統會顯示免責事項橫幅。確認免責事項。
  6. 現在畫面會顯示翻譯語言清單。按一下語言的「檢查並套用」。檢查文字,然後按一下「套用所有翻譯」。針對所有要翻譯的語言重複這個步驟。

翻譯完成後,您可以在 Play 管理中心編輯譯文。如要編輯翻譯文字,請按照下列步驟操作:

  1. 開啟「單次產品」>「[您的單次產品]」>「編輯單次產品」>「編輯單次產品詳細資料」頁面。
  2. 從語言下拉式選單中選取所需語言。這會以所選語言顯示文字。下圖顯示如何選取語言來編輯翻譯文字:

    edit-translations.png 圖 3:編輯翻譯文字。
  3. 視需要編輯文字,然後按一下「儲存變更」

系統會根據使用者的手機語言偏好設定,向使用者顯示翻譯文字。舉例來說,如果使用者手機的語言設為法文,單次產品的名稱和說明就會以法文顯示。下圖顯示翻譯文字在不同語言中的顯示方式和位置。

post-translation.png圖 4:應用程式中的翻譯文字。

翻譯設定影片

以下影片顯示先前說明的翻譯設定步驟。

6. 與 PBL 整合

如要將應用程式與 Play 帳款服務程式庫 (PBL) 整合,請按照下列步驟操作:

  1. 將 Play 帳款服務程式庫依附元件新增至範例應用程式。
    dependencies {
    val billing_version = "8.0.0"
    
    implementation("com.android.billingclient:billing-ktx:$billing_version")
    }
    
  2. 初始化 BillingClient。BillingClient 是位於應用程式的用戶端 SDK,可與 Play 帳款服務程式庫通訊。下列程式碼片段說明如何初始化帳單用戶端。
    private BillingClient createBillingClient() {
    return BillingClient.newBuilder(activity)
        .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
        // For one-time products, add a listener to process and acknowledge the purchases. This will notify
        // Google the purchase was processed.
        // For client-only apps, use billingClient.acknowledgePurchase().
        // If you have a secure backend, you must acknowledge purchases on your server using the
        // server-side API.
        // See https://developer.android.com/google/play/billing/security#acknowledge
        // In this sample snippet purchases aren't processed. You must
        // implement your business logic to process and acknowledge the purchases.
        .setListener((billingResult, purchases) -> {})
        .enableAutoServiceReconnection()
        .build();
     }
    
  3. 連線至 Google Play。下列程式碼片段說明如何連線至 Google Play。
    /**
    * Starts the billing connection with Google Play. This method should be called exactly once
    * before any other methods in this class.
    *
    * @param productList The list of products to query for after the connection is established.
    */
    public void startBillingConnection(List<Product> productList) {
        billingClient.startConnection(
            new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                Log.d(TAG, "Billing Client Connection Successful");
                queryProductDetails(productList);
                } else {
                Log.e(TAG, "Billing Client Connection Failed: " + billingResult.getDebugMessage());
                listener.onBillingSetupFailed(billingResult); // Propagate the error to the listener to show a message to the user.
                }
            }
    
            @Override
            public void onBillingServiceDisconnected() {
                Log.e(TAG, "Billing Client Connection Lost");
                listener.onBillingError("Billing Connection Lost");
            }
            });
    }
    
  4. 擷取一次性產品詳細資料。將應用程式與 PBL 整合後,您必須將一次性產品詳細資料擷取到應用程式中。下列程式碼片段說明如何在應用程式中擷取一次性產品詳細資料。
    private void queryProductDetails(List<Product> productList) {
        QueryProductDetailsParams queryProductDetailsParams =
            QueryProductDetailsParams.newBuilder().setProductList(productList).build();
    
        billingClient.queryProductDetailsAsync(
            queryProductDetailsParams,
            new ProductDetailsResponseListener() {
            @Override
            public void onProductDetailsResponse(
                BillingResult billingResult, QueryProductDetailsResult productDetailsResponse) {
                if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                List<ProductDetails> productDetailsList =
                    productDetailsResponse.getProductDetailsList();
                    listener.onProductDetailsResponse(productDetailsList);
                } else {
                Log.e(TAG, "QueryProductDetailsAsync Failed: " + billingResult.getDebugMessage());
                listener.onBillingError("Query Products Failed: " + billingResult.getResponseCode());
                }
            }
            });
    }
    
    ProductDetails 中擷取一次性產品 (本例為 trending_movie_1),會收到類似以下的回應:
    {
        "productId": "trending_movie_1",
        "type": "inapp",
        "title": "Purrfect Mayhem: The Rewind Protocol (Movies All Day | Play Samples)",
        "name": "Purrfect Mayhem: The Rewind Protocol",
        "description": "Dr. Arid Thorne and a smart tiger named Yolo find a mysterious tape. It's a \"Rewind Protocol\" to fix time. A shadowy group, the Clockinator, hunts them to seize the tape's power.",
        "skuDetailsToken": "<---skuDetailsToken--->",
        "oneTimePurchaseOfferDetails": {},
        "oneTimePurchaseOfferDetailsList": [
            {
                "priceAmountMicros": 13000000,
                "priceCurrencyCode": "USD",
                "formattedPrice": "$13.00",
                "offerIdToken": "<---buy offerIdToken --->",
                "purchaseOptionId": "buy-option",
                "offerTags": [
                    "adventure",
                    "mystery"
                ]
            },
            {
                "priceAmountMicros": 7000000,
                "priceCurrencyCode": "USD",
                "formattedPrice": "$7.00",
                "offerIdToken": "<---rent offerIdToken--->",
                "purchaseOptionId": "rent-option",
                "offerTags": [
                    "adventure",
                    "mystery"
                ],
                "rentalDetails": {
                    "rentalPeriod": "P30D",
                    "rentalExpirationPeriod": "PT24H"
                }
            }
        ]
    }
    
    請注意,購買和租借選項會顯示在 oneTimePurchaseOfferDetailsList 中。這個清單有 2 個購買選項 (buy-optionrent-option),都是在 Play 管理中心設定的。您可以透過 offerIdToken 識別每個購買選項。
  5. 擷取「租借」和「購買」優惠的優惠權杖。您需要優惠權杖,才能在步驟 6 中啟動結帳流程。
    @Override
    public void onProductDetailsResponse(List<ProductDetails> productDetailsList) {
    
        if (productDetailsList != null && !productDetailsList.isEmpty()) {
    
            // Iterate over all details of the queried product in step 4.
            for (ProductDetails productDetails : productDetailsList) {
    
                // Get the list of all the offers associated with the product.
                List<ProductDetails.OneTimePurchaseOfferDetails> offerDetailsList =
                        productDetails.getOneTimePurchaseOfferDetailsList();
    
                // Iterate over the offer details
                for (ProductDetails.OneTimePurchaseOfferDetails offerDetails : offerDetailsList) {
    
                    // For a Rent purchase option, the
                    // offerDetails.getRentalDetails() method returns
                    // the rent information. If this information is present,
                    // the offer corresponds to a Rent purchsae option.
                    if (offerDetails.getRentalDetails() != null) {
                        rentFormattedPrice = offerDetails.getFormattedPrice();
    
                        // Get the offerIdToken for the Rent purchase option
                        rentOfferToken = offerDetails.getOfferToken();
                        rentMovieTags = offerDetails.getOfferTags();
                    }
                    // If the offerDetails.getRentalDetails() returns
                    // null, the offer corresponds to a Buy purchsae option.
                    else {
                        buyFormattedPrice = offerDetails.getFormattedPrice();
    
                        // Get the offerIdToken for the Buy purchase option
                        buyOfferToken = offerDetails.getOfferToken();
                        buyMovieTags = offerDetails.getOfferTags();
                    }
                }
                updateUIButtons();
                return;
    
            }
        } else {
            Log.e(TAG, "No product details found for " + productId);
        }
    }
    
  6. 啟動結帳流程。
    /**
     * Launches the billing flow for the product with the given offer token.
    *
    * @param activity The activity instance from which the billing flow will be launched.
    * @param productDetails The product details of the product to purchase.
    * @param offerToken The offer token of the product to purchase.
    * @return The result of the billing flow.
    */
    public void launchPurchase(Activity activity, ProductDetails productDetails, String offerToken) {
        ImmutableList<BillingFlowParams.ProductDetailsParams> productDetailsParamsList =
            ImmutableList.of(
                BillingFlowParams.ProductDetailsParams.newBuilder()
                    .setProductDetails(productDetails)
                    .setOfferToken(offerToken)
                    .build());
        BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
            .setProductDetailsParamsList(productDetailsParamsList)
            .build();
        billingClient.launchBillingFlow(activity, billingFlowParams);
    }
    

提示:您也可以設定即時開發人員通知 (RTDN),以便導入回購廣告活動和其他購買交易生命週期管理策略。如要瞭解如何設定 RTDN,以及如何處理通知以準確追蹤和授權,建議您完成「充分運用 Play 帳款服務整合功能」程式碼研究室。

7. 測試購買選項

在正式版應用程式中提供一次性產品前,您可以先使用授權測試人員和 Play Billing Lab 測試 PBL 整合服務。

您將瞭解如何測試價格本地化和供應情形,其中應用程式僅在部分區域提供,且各區域的價格不同。

必備條件

測試購買選項的區域價格

如要測試購買選項的區域價格,請按照下列步驟操作:

  1. 開啟 Play Billing Lab 應用程式,然後以授權測試人員身分登入。
  2. 在「設定」中,按一下「編輯」,選取國家/地區 France,然後按一下「套用」。在此選取 Play 國家/地區,決定應用程式中顯示的幣別。
  3. 關閉並重新開啟範例應用程式。現在應該會顯示 France 的購買和租借幣別 (歐元)。

如要測試其他國家/地區,請在步驟 2 中選取 Spain,然後執行步驟 3。

Play Billing Lab 測試影片

以下影片使用範例應用程式,說明如何測試區域價格。

8. 後續步驟

參考文件

9. 恭喜!

恭喜!您已成功在 Google Play 管理中心建立新的買斷型產品、設定購買選項,並使用 Play 帳款服務實驗室測試購買流程。您現在已深入瞭解 Google Play 彈性產品目錄,可供一次性購買。

問卷調查

我們非常重視您對本程式碼研究室的意見。請考慮花幾分鐘時間填寫問卷調查。