外部特典プログラムのアプリ内統合のガイダンス

このガイドでは、API と統合して、対象となるアプリと地域で外部提案をサポートする方法について説明します。資格要件や対象地域など、外部提案プログラムの詳細については、プログラムの要件をご覧ください。

Play Billing Library のセットアップ

外部提案 API を使用するには、Android アプリに バージョン 8.2 以降の Play Billing Library の依存関係を追加します。以前のバージョンから移行する必要がある場合は、移行ガイドの手順に沿って外部提案を実装してください。

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 Billing Library で生成された外部取引トークンが必要です。このトークンは、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 拡張機能を使用して suspend 関数 createBillingProgramReportingDetailsAsync をクエリすることもできます。これにより、リスナーを定義する必要がなくなります。

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

外部提案フローを開始する

外部提案フローを開始するには、対象となるアプリがアプリのメインスレッドから launchExternalLink() API を呼び出す必要があります。この API は、LaunchExternalLinkParams オブジェクトを入力として受け取ります。LaunchExternalLinkParams オブジェクトを作成するには、LaunchExternalLinkParams.Builder クラスを使用します。このクラスには次のパラメータが含まれています。

  • linkUri - デジタル コンテンツやアプリのダウンロードが提供されている外部ウェブサイトへのリンク。アプリのダウンロードの場合、このリンクは Google Play Console で登録および承認されている必要があります。
  • linkType - ユーザーに提供されるコンテンツのタイプ。
  • launchMode - リンクの起動方法を指定します。アプリのダウンロードの場合、この値を LAUNCH_IN_EXTERNAL_BROWSER_OR_APP に設定する必要があります。
  • billingProgram - BillingProgram.EXTERNAL_OFFER に設定します。

launchExternalLink() を呼び出すと、ユーザー設定に基づいて追加情報ダイアログがユーザーに表示されることがあります。launchMode パラメータに応じて、Google Play はリンク URI を外部ブラウザで起動するか、フローをアプリに戻して URI を起動します。ほとんどの場合、Play が URI を起動する LAUNCH_IN_EXTERNAL_BROWSER_OR_APP モードを使用できます。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);

LaunchModeCALLER_WILL_LAUNCH_LINK に設定した場合は、onLaunchExternalLinkResponseBillingResponseCode.OK を提供する場合にのみ、ユーザーをアプリ外に誘導する必要があります。

Google Play に取引を報告する

すべての外部取引を、バックエンドから Google Play Developer API を呼び出して Google Play に報告する必要があります。取引を報告する際は、createBillingProgramReportingDetailsAsync API から取得した externalTransactionToken を指定する必要があります。ユーザーが複数回購入した場合は、同じ externalTransactionToken を使用して各購入をレポートできます。取引を報告する方法については、バックエンド統合ガイドをご覧ください。

レスポンス処理

エラーが発生した場合、メソッド isBillingProgramAvailableAsync()createBillingProgramReportingDetailsAsync()launchExternalLink()BillingResponseCode.OK 以外のレスポンスを返すことがあります。これらのレスポンス コードは次のように処理することを検討してください。

  • ERROR: これは内部エラーです。取引や外部ウェブサイトのオープンを続行しないでください。launchExternalLink() を呼び出して再試行し、ユーザーをアプリ外に誘導しようとしたときに、次回ユーザーに情報ダイアログを表示します。
  • FEATURE_NOT_SUPPORTED: 外部提案 API が、現在のデバイスの Google Play ストアでサポートされていません。取引や外部ウェブサイトのオープンを続行しないでください。
  • USER_CANCELED: 外部ウェブサイトを開く処理を続行しません。次にユーザーをアプリ外に誘導しようとしたときに、launchExternalLink() を再度呼び出して情報ダイアログをユーザーに表示します。
  • BILLING_UNAVAILABLE: 取引が外部提案の対象ではないため、このプログラムでは進めることができません。このエラーは、ユーザーがこのプログラムの対象国に居住していないか、アカウントがプログラムに正常に登録されていない場合に発生します。後者の場合は、Google Play Console で登録ステータスを確認してください。
  • DEVELOPER_ERROR: リクエストでエラーが発生しています。先に進む前に、デバッグ メッセージを使用してエラーを特定および修正してください。
  • NETWORK_ERROR, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE: 適切な再試行ポリシーで処理する必要がある一時的なエラーです。SERVICE_DISCONNECTED の場合は、Google Play との接続を再確立してから再試行してください。

外部提案をテストする

ライセンス テスターは、外部提案の統合をテストするために使用する必要があります。ライセンス テスター アカウントによって開始されたトランザクションに対しては請求されません。ライセンス テスターの構成について詳しくは、アプリ ライセンスを使用したアプリ内課金のテストをご覧ください。

次のステップ

アプリ内統合が完了すると、バックエンドを統合する準備が整います。