外部決済のアプリ内統合のガイダンス

このドキュメントでは、Play Billing Library の API を統合して、対象アプリで外部決済を提供する方法について説明します。このプログラムについて詳しくは、 プログラムの要件をご覧ください。

Play Billing Library のセットアップ

Android アプリに Play Billing Library の依存関係を追加します。 外部決済 API を使用するには、バージョン 8.3 以降を使用する必要があります。以前のバージョンから 移行する必要がある場合は、 移行ガイドの手順に沿ってアップグレードしてから統合を開始してください。

BillingClient を初期化する

統合プロセスの最初のステップは、 Google Play 請求サービスの統合ガイドに記載のステップと同じですが、 BillingClient の初期化の際にいくつかの違いがあります。

次の例は、これらの変更を行った BillingClient の初期化方法を示しています。

Kotlin

val purchasesUpdatedListener =
    PurchasesUpdatedListener { billingResult, purchases ->
        // Handle new Google Play purchase.
    }

val developerProvidedBillingListener =
    DeveloperProvidedBillingListener { details ->
        // Handle user selection for developer provided billing option.
    }

val billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private DeveloperProvidedBillingListener developerProvidedBillingListener =
    new DeveloperProvidedBillingListener() {
        @Override
        public void onUserSelectedDeveloperBilling(
            DeveloperProvidedBillingDetails details) {
            // Handle user selection for developer provided billing option.
        }
    };

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build();

Google Play に接続する

BillingClient を初期化したら、Google Play に接続するの説明のとおりに Google Play への接続を確立します。

ユーザーの資格を確認する

Google Play に接続したら、ユーザーが 外部決済プログラムの対象かどうかを isBillingProgramAvailableAsync() メソッドを呼び出して確認できます。ユーザーが対象の場合は、このメソッドから BillingResponseCode.OKが返されます。 次のサンプルは、資格を確認する方法を示しています。

Kotlin

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

        // External payments are available. Can proceed with generating an
        // external transaction token.
})

Java

billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_PAYMENTS,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      int billingProgram, BillingResult billingResult) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external payments unavailable, etc.
            return;
        }

        // External payments are available. Can proceed with generating an external transaction token.
      }

    });

他のレスポンス コードに対応する方法については、レスポンス処理のセクションをご覧ください。Kotlin 拡張機能を使用している場合は、Kotlin コルーチンを使用できるため、リスナーを別に定義する必要はありません。

購入可能な商品を表示する

Google Play の課金システムの統合と同様に、 購入可能な商品をユーザーに表示できます。ユーザーが購入可能な商品を確認し、購入する商品を選択したら、外部 決済フローを開始するのセクションで説明するように、外部決済フローを開始します。

外部取引トークンを準備する

外部取引を Google Play に報告するには、Play Billing Library で生成された外部取引トークンが必要です。ユーザーが外部決済 API を介して外部のウェブサイトまたはアプリにアクセスするたびに、新しい外部取引トークンを生成する必要があります。これは、 createBillingProgramReportingDetailsAsync API を呼び出すことで行えます。トークンは、launchBillingFlow が呼び出される直前に生成する必要があります。

Kotlin

val params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .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 external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
    }
})

Java

BillingProgramReportingDetailsParams params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .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 external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
      }
});

Kotlin 拡張機能を使用している場合は、Kotlin コルーチンを使用できるため、リスナーを別に定義する必要はありません。

外部決済フローを開始する

Google Play の課金システムの統合でlaunchBillingFlow() 購入フローを開始する場合と同様に、DeveloperBillingOptionParams を呼び出して外部決済フローを開始します。ただし、追加のパラメータを指定して、この購入で外部決済フローを有効にすることをアプリが希望していることを示します。

DeveloperBillingOptionParams には、次のものを含める必要があります。

  • billingProgramEXTERNAL_PAYMENTS 課金プログラムに設定
  • linkURI をリンク先に設定
  • launchMode を Google Play がリンクを開始する場合は LAUNCH_IN_EXTERNAL_BROWSER_OR_APP に、アプリがリンクを開始する場合は CALLER_WILL_LAUNCH_LINK に設定

アプリが DeveloperBillingOptionParams を指定して launchBillingFlow() を呼び出すと、Google Play 課金システムが次のチェックを実行します。

  • システムは、ユーザーの Google Play の国が、外部決済に対応している国 (サポート対象国)かどうかをチェックします。ユーザーの Google Play の国がサポート対象国の場合、Google Play は、BillingClient の設定に基づいて外部決済が有効になっているかどうか、および DeveloperBillingOptionParams が指定されているかどうかをチェックします。
    • 外部決済が有効になっている場合は、購入フローでユーザー チョイス UX が表示されます。
    • 外部決済が有効になっていない場合、購入フローには、Google Play 課金システムの標準 UX(ユーザー チョイス型ではない)が表示されます。
  • ユーザーの Google Play の国がサポート対象国以外の場合、購入フローには、Google Play 課金システムの標準 UX(ユーザー チョイス型ではない)が表示されます。

ユーザーの Play の国がサポート対象国

ユーザーの Play の国がサポート対象国以外

外部決済が有効(BillingClient のセットアップlaunchBillingFlow

ユーザー チョイスの UX が表示される

ユーザーには標準の Google Play 課金システム UX が表示されます

外部決済が無効(BillingClient のセットアップ時に有効になっていないか、launchBillingFlow に DeveloperBillingOptionParams が指定されていない)

ユーザーには標準の Google Play 課金システム UX が表示されます

ユーザーには標準の Google Play 課金システム UX が表示されます

次のスニペットは、DeveloperBillingOptionParams を作成する方法を示しています。

Kotlin

val developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri(Uri.parse("https://www.example.com/external/purchase"))
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build()

Java

DeveloperBillingOptionParams developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri(Uri.parse("https://www.example.com/external/purchase"))
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build();

ユーザー選択を処理する

残りの購入フローの処理方法は、ユーザーが Google Play の課金システムを選択するか、ウェブサイトで支払うかによって異なります。

ユーザーがウェブサイトまたは決済アプリで支払うことを選択した場合

ユーザーがウェブサイトで支払うことを選択すると、Google Play は DeveloperProvidedBillingListener を呼び出し、ユーザーが ウェブサイトまたは決済アプリで支払うことを選択したことをアプリに通知します。特に、 onUserSelectedDeveloperBilling() メソッドが呼び出されます。

アプリが launchModeLAUNCH_IN_EXTERNAL_BROWSER_OR_APP に設定すると、Google Play がリンクを開始します。launchModeCALLER_WILL_LAUNCH_LINK に設定されている場合、リンクを開始するのはアプリの責任です。ユーザーを決済アプリにリンクする場合は、ユーザーのデバイスに決済アプリがすでにインストールされていることを確認する必要があります。

このトークンは、この選択から発生する取引を報告するために使用します。 バックエンド統合ガイドの説明のとおりです。

ユーザーが Google Play の課金システムを選択した場合

ユーザーが Google Play の課金システムを選択した場合は、Google Play で購入を続行します。

  • Google Play の課金システムで新しいアプリ内購入を処理する方法の詳細については、ライブラリ統合ガイドの購入の処理をご覧ください。
  • 定期購入に関するその他のガイダンスについては、定期購入管理ガイドの新しい定期購入をご覧ください。

定期購入の変更を処理する

外部決済を使用しているデベロッパーは、ユーザーの選択に応じて、購入を Google Play の課金システムで処理するか、externalTransactionId で報告する必要があります。デベロッパーのウェブサイトで処理された既存の定期購入に対する変更は、有効期限まで同じ課金システムで行うことができます。

このセクションでは、定期購入の変更に関する一般的なシナリオを処理する方法について説明します。

アップグレードとダウングレードのフロー

アップグレードとダウングレードのフローを含む定期購入プランの変更は、定期購入を Google Play の課金システムとデベロッパーのウェブサイトのどちらで購入したかによって、異なる処理を行う必要があります。

既存の定期購入に依存し、同じお支払い方法を共有し、定期的な請求を調整するアドオンは、アップグレードとして処理されます。その他のアドオンについては、ユーザーが使用する課金システムを選択できるようにする必要があります。外部決済フローを開始するの説明のとおりに、launchBillingFlow()を使用して新しい購入エクスペリエンスを開始します。

デベロッパーのウェブサイトまたは決済アプリで購入した定期購入

ユーザー チョイス後にデベロッパーのウェブサイトまたは決済アプリで購入した定期購入については、アップグレードまたはダウングレードをリクエストするユーザーは、再度ユーザー チョイスを行うことなくデベロッパーのウェブサイトまたは決済アプリに進む必要があります。

これを行うには、ユーザーがアップグレードまたはダウングレードをリクエストしたときに launchBillingFlow() を呼び出します。 SubscriptionUpdateParams オブジェクトで他のパラメータを指定する代わりに、 setOriginalExternalTransactionId() を使用して、元の購入の外部取引 ID を指定します。

この呼び出しでは、DeveloperBillingOptionParams も指定する必要があります。元の購入のユーザー チョイスがアップグレードとダウングレードで変わっていなければ、ユーザー選択画面は表示されません。この取引の新しい外部取引トークンは、こちらで説明されているように生成する必要があります 。

デベロッパーのウェブサイトまたは決済アプリを使用してアップグレードまたはダウングレードが完了したら、新しい定期購入に関する上記の呼び出しで取得した外部取引トークンを使用して新しい取引を報告する必要があります。

Google Play の課金システムで購入した定期購入

同様に、ユーザー チョイス後に Google Play の 課金システムで現在の定期購入を購入したユーザーには、 Google Play 請求サービスの標準請求フローが表示されます。launchBillingFlow の呼び出しで DeveloperBillingOptionParams を設定しないでください。

定期購入の解約と再開

ユーザーはいつでも定期購入を解約できる必要があります。ユーザーが定期購入を解約したとき、利用資格の停止は購入済みの期間が終了するまで延期されることがあります。たとえば、ユーザーが月の中旬で月次の定期購入を解約した場合、そのアクセス権が削除されるまで、残りの約 2 週間は引き続きサービスにアクセスできます。この期間中、定期購入は技術的に有効であるため、ユーザーはサービスを利用できます。

この有効な期間に解約が取り消されることは珍しくありません。このガイドではこれを再開と呼びます。以降のセクションでは、外部決済 API 統合で再開のシナリオを処理する方法について説明します。

デベロッパーのウェブサイトで購入した定期購入

解約された定期購入の外部取引 ID がある場合は、定期購入の再開に launchBillingFlow() の呼び出しは不要なため、このタイプの有効化には使用しないでください。解約された定期購入がまだ有効な間にユーザーが定期購入を再開した場合、その時点でトランザクションは発生しません。現在のサイクルが終了して次の更新が発生したときに更新を報告することは可能です。これには、ユーザーが再開の一環としてクレジットや特別な更新価格を受け取る場合も含まれます(定期購入を継続するようユーザーに促すプロモーションなど)。

Google Play の課金システムで購入した定期購入

通常、ユーザーは Google Play の課金システムで定期購入を再開できます。 もともと Google Play の 課金システムで購入した解約済みの定期購入については、定期購入が有効な間、ユーザーは Google Play の 再度定期購入機能で解約を取り消すことができます。その場合、バックエンドで SUBSCRIPTION_RESTARTED リアルタイム デベロッパー通知を受け取ります。また、新しい購入トークンは発行されません。元のトークンが定期購入の継続に使用されます。Google Play の課金システムで 再開を管理する方法については、定期購入管理ガイドの再開をご覧ください。

また、launchBillingFlow() を呼び出すことで、アプリから Google Play の課金システムで再開をトリガーすることもできます。その方法については、 定期購入の有効期限前 - アプリ内をご覧ください。もともとの購入のユーザー選択フロー(解約したがまだ有効)をユーザーが進めた場合、システムはその選択を自動的に検出し、その購入を再開するためのユーザー インターフェースを表示します。Google Play で定期購入の再購入を行うよう求められますが、ユーザー選択を再度行う必要はありません。この場合は、ユーザーに新しい購入トークンが発行されます。バックエンドが SUBSCRIPTION_PURCHASED リアルタイム デベロッパー通知を受信し、新しい購入ステータスの linkedPurchaseToken 値が、アップグレードまたはダウングレードの場合と同様に、解約された定期購入の以前の購入トークンに設定されます。

再度定期購入

定期購入が完全に期限切れになった場合、その理由が解約や回復しない支払い不承認(アカウントの一時停止の期限切れ)であっても、ユーザーが利用資格の再開を望む場合には再度定期購入を行う必要があります。

再度定期購入は、通常の登録と同様に、それを処理することでアプリを通じて有効にすることもできます。ユーザーが使用する課金システムを選択できるようにする必要があります。launchBillingFlow() は、 外部決済フローを開始するで説明されているように、この場合に呼び出されます。

レスポンス処理

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

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

外部決済リンクをテストする

外部決済の統合をテストするには、ライセンス テスターを使用する必要があります。 ライセンス テスター アカウントによって開始された取引は請求されません。ライセンス テスターの設定について詳しくは、 アプリ ライセンスを使用したアプリ内課金のテストをご覧ください。

次のステップ

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