外部優惠計畫的應用程式內整合指南

本指南說明如何整合 API,以便在符合資格的應用程式和區域中支援外部優惠。如要進一步瞭解外部優惠計畫,包括資格規定和地理位置範圍,請參閱計畫規定

Play 帳款服務程式庫設定

如要使用外部優惠 API,請將 Play 帳款服務程式庫依附元件 8.2 以上版本新增至 Android 應用程式。如需從舊版遷移至新版,請先按照遷移指南的指示操作,再嘗試導入外部優惠。

連線至 Google Play

整合程序的前幾個步驟如同帳款服務整合指南所述,但您必須在初始化 BillingClient 時呼叫 enableBillingProgram,指出您要使用外部優惠:

以下示範如何透過變更後的做法初始化 BillingClient

Kotlin

val billingClient = BillingClient.newBuilder(context)
  .enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
  .build()

Java

private BillingClient billingClient = BillingClient.newBuilder(context)
    .enableBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

初始化 BillingClient 後,請按照整合指南的說明與 Google Play 建立連線

檢查是否可用

如要確認目前使用者是否可使用外部優惠,請呼叫 isBillingProgramAvailableAsync

如果外部優惠可用,這個 API 會傳回 BillingResponseCode.OK。 如要進一步瞭解應用程式應如何回應其他回應代碼,請參閱「回應處理」。

Kotlin


billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_OFFER,
  object : BillingProgramAvailabilityListener {
    override fun onBillingProgramAvailabilityResponse(
      billingResult: BillingResult,
      billingProgramAvailabilityDetails: BillingProgramAvailabilityDetails) {
        if (billingResult.responseCode !=  BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external offers unavailable, etc.
            return
        }

        // External offers are available. Continue with steps in the
        // guide.
      }
  })

Java


billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_OFFER,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      BillingResult billingResult,
      BillingProgramAvailabilityDetails billingProgramAvailabilityDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external offers being unavailable, etc.
            return;
        }
        // External offers are available. Continue with steps in the
        // guide.
      }
  });

準備外部交易權杖

如要向 Google Play 回報外部交易,您必須擁有 Play 帳款服務程式庫產生的外部交易憑證。您可以呼叫 createBillingProgramReportingDetailsAsync API 取得這個權杖。引導使用者前往其他平台時,必須先為每個外部優惠產生新權杖。權杖不得跨交易快取。

Kotlin

val params =
  BillingProgramReportingDetailsParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  object : BillingProgramReportingDetailsListener {
    override fun onCreateBillingProgramReportingDetailsResponse(
      billingResult: BillingResult,
      billingProgramReportingDetails: BillingProgramReportingDetails?) {
        if (billingResult.responseCode !=  BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return
        }
        val externalTransactionToken =
            billingProgramReportingDetails?.externalTransactionToken
        // Persist the transaction token in your backend. You may pass it
        // to the external website when calling the launchExternalLink API.
    }
})

Java

BillingProgramReportingDetailsParams params =
  BillingProgramReportingDetailsParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  new BillingProgramReportingDetailsListener() {
    @Override
    public void onCreateBillingProgramReportingDetailsResponse(
      BillingResult billingResult,
      @Nullable BillingProgramReportingDetails
        billingProgramReportingDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return;
        }

        String transactionToken =
          billingProgramReportingDetails.getExternalTransactionToken();
        // Persist the transaction token in your backend. You may pass it
        // to the external website when calling the launchExternalLink API.
      }
});

此外,您也可以使用 Kotlin 擴充功能查詢暫停函式 createBillingProgramReportingDetailsAsync,這樣就不必定義監聽器:

  val createBillingProgramReportingDetailsResult =
    withContext(context) {
      billingClient
        .createBillingProgramReportingDetails(params)
    }
  // Process the result

啟動外部優惠流程

如要啟動外部優惠流程,符合資格的應用程式必須從應用程式的主要執行緒呼叫 launchExternalLink() API。這個 API 會採用 LaunchExternalLinkParams 物件做為輸入內容。如要建立 LaunchExternalLinkParams 物件,請使用 LaunchExternalLinkParams.Builder 類別。這個類別包含下列參數:

  • linkUri - 提供數位內容或應用程式下載的外部網站連結。如要追蹤應用程式下載次數,請務必在 Play 管理中心註冊並核准這個連結。
  • linkType - 提供給使用者的內容類型。
  • launchMode - 指定連結的啟動方式。如要增加應用程式下載量,請務必將這個值設為 LAUNCH_IN_EXTERNAL_BROWSER_OR_APP
  • billingProgram - 將此值設為 BillingProgram.EXTERNAL_OFFER

當您呼叫 launchExternalLink() 時,系統可能會根據使用者設定,向使用者顯示額外資訊對話方塊。視 launchMode 參數而定,Play 會在外部瀏覽器中啟動連結 URI,或將流程傳回應用程式以啟動 URI。在大多數情況下,您可以使用 LAUNCH_IN_EXTERNAL_BROWSER_OR_APP 模式,讓 Play 為您啟動 URI。如要進一步自訂行為,例如在 WebView 中啟動 URI 或在特定瀏覽器中開啟 URI,可以使用 CALLER_WILL_LAUNCH_LINK 模式。為保護使用者隱私,請確保 URI 中未傳送任何個人識別資訊 (PII)。

Kotlin


// An activity reference from which the external offers flow will be launched.
val activity = ...;

val params =
  LaunchExternalLinkParams.newBuilder()
    .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
    // You can pass along the external transaction token from
    // BillingProgramReportingDetails as a URL parameter in the URI
    .setLinkUri(yourLinkUri)
    .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
    .setLaunchMode(
      LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
    .build()

val listener : LaunchExternalLinkResponseListener =
  LaunchExternalLinkResponseListener {
      override fun onLaunchExternalLinkResponse(billingResult: BillingResult) {
    if (billingResult.responseCode == BillingResponseCode.OK) {
      // Proceed with the rest of the external offer flow. If the user
      // purchases an item, be sure to report the transaction to Google Play.
    } else {
      // Handle failures such as retrying due to network errors.
    }
  }
}

billingClient.launchExternalLink(activity, params, listener)

Java


// An activity reference from which the external offers flow will be launched.
Activity activity = ...;

LaunchExternalLinkParams params = LaunchExternalLinkParams.newBuilder()
  .setBillingProgram(BillingProgram.EXTERNAL_OFFER)
  // You can pass along the external transaction token from  
  // BillingProgramReportingDetails as a URL parameter in the URI
  .setLinkUri(yourLinkUri)
  .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_APP_DOWNLOAD)
  .setLaunchMode(
    LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
  .build();

LaunchExternalLinkResponseListener listener =
  new LaunchExternalLinkResponseListener() {
    @Override
    public void onLaunchExternalLinkResponse(BillingResult billingResult) {
      if (billingResult.responseCode == BillingResponseCode.OK) {
        // Proceed with the rest of the external offer flow. If the user
        // purchases an item, be sure to report the transaction to Google
        // Play.
      } else {
        // Handle failures such as retrying due to network errors.
      }
    }
  }

billingClient.launchExternalLink(activity, params, listener);

如果將 LaunchMode 設為 CALLER_WILL_LAUNCH_LINK,只有在 onLaunchExternalLinkResponse 提供 BillingResponseCode.OK 時,才應將使用者導向應用程式外部。

向 Google Play 回報交易

您必須從後端呼叫 Google Play Developer API,向 Google Play 回報所有外部交易。回報交易時,您必須提供從 createBillingProgramReportingDetailsAsync API 取得的 externalTransactionToken。如果使用者進行多筆交易,您可以使用相同的 externalTransactionToken 回報每筆交易。如要瞭解如何回報交易,請參閱後端整合指南

回應處理

發生錯誤時,方法 isBillingProgramAvailableAsync()createBillingProgramReportingDetailsAsync()launchExternalLink() 可能會傳回 BillingResponseCode.OK 以外的回應。建議您按照下列方式處理這些回應碼:

  • ERROR:這是內部錯誤。請勿繼續交易或開啟外部網站。下次嘗試將使用者導向應用程式外部時,請呼叫 launchExternalLink(),向使用者顯示資訊對話方塊,然後重試。
  • FEATURE_NOT_SUPPORTED:目前裝置的 Play 商店不支援外部優惠 API。請勿繼續交易或開啟外部網站。
  • USER_CANCELED:請勿繼續開啟外部網站。下次嘗試將使用者導向應用程式外部時,請再次呼叫 launchExternalLink(),向使用者顯示資訊對話方塊。
  • BILLING_UNAVAILABLE:無法使用外部優惠完成交易,因此不應以本計畫名義繼續進行。這是因為使用者不在本計畫適用的國家/地區,或是您的帳戶未成功註冊加入計畫。如果原因是後者,請前往 Play 管理中心查看註冊狀態。
  • DEVELOPER_ERROR:要求出錯。請先使用偵錯訊息找出並修正錯誤,然後再繼續操作。
  • NETWORK_ERROR, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE:這些是暫時性錯誤,應使用適當的重試政策處理。當出現 SERVICE_DISCONNECTED 時,請在重試前重新建立與 Google Play 的連線。

測試外部優惠

授權測試人員可用於測試外部優惠整合。系統不會針對授權測試人員帳戶發起的交易開立月結單。如要進一步瞭解如何設定授權測試人員,請參閱「透過應用程式授權來測試應用程式內結帳服務」。

後續步驟

完成應用程式內整合作業後,即可開始整合後端