In dieser Anleitung wird beschrieben, wie Sie Ihre App in die Play Billing Library APIs einbinden, damit Sie Ihren Nutzern die Möglichkeit geben können, zwischen verschiedenen Abrechnungsoptionen zu wählen.
Einbindung in die PBL
Sie können die Abrechnung mit Auswahlmöglichkeit in vier Szenarien in die PBL einbinden. Die Szenarien unterscheiden sich darin, wer den Bildschirm mit den Auswahlmöglichkeiten rendert und wo die Zahlung erfolgt. In der folgenden Tabelle sind die Einbindungsszenarien aufgeführt:
| Wo erfolgt die Zahlung? | |||
| In-App | Externer Weblink | ||
| Welchen Bildschirm mit Abrechnungsmöglichkeiten möchten Sie rendern? | Google Play | Szenario 1A
Google rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App. |
Szenario 1B
Der App-Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App. |
| Ihr eigener (gemäß den UX-Richtlinien) | Szenario 2A
Google rendert den Bildschirm mit den Auswahlmöglichkeiten und der Nutzer wird für Käufe von Ihrer App zu Ihren eigenen Websites weitergeleitet. |
Szenario 2B
Der App-Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und der Nutzer wird für Käufe von Ihrer App zu Ihren eigenen Websites weitergeleitet. |
|
Die folgende Abbildung veranschaulicht den Ablauf der Abrechnung mit Auswahlmöglichkeit für jedes dieser Szenarien:
PBL-Einbindungsszenarien
Je nach Einbindungsszenario folgen Sie der Anleitung in diesem Abschnitt, um die Abrechnung mit Auswahlmöglichkeit in Ihrer App zu implementieren.
Szenario 1A verarbeiten
Google rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App. Führen Sie die folgenden Schritte aus, um die Abrechnung mit Auswahlmöglichkeit in diesem Szenario zu aktivieren:
Rufen Sie
enableBillingProgrammitEnableBillingProgramParamsauf, wenn Sie Ihre BillingClient-Instanz erstellen, und starten Sie dann die Verbindung. Beispiel:Kotlin
// Build the parameters to enable the Billing Choice program and assign the listener // to handle user selection of the developer-provided billing option. val params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperProvidedBillingListener(developerProvidedBillingListener) .build() // Build the parameters to enable support for pending purchases. val pendingPurchasesParams = PendingPurchasesParams.newBuilder() .enableOneTimeProducts() .build() // Construct the BillingClient instance with the purchases updated listener, // pending purchases support, and the billing choice params. val billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases(pendingPurchasesParams) .enableBillingProgram(params) .build() // Establish a connection to Google Play val billingResult = suspendCancellableCoroutine{ continuation -> billingClient.startConnection(object : BillingClientStateListener { // Called when the connection setup process completes. override fun onBillingSetupFinished(billingResult: BillingResult) { // Resume the coroutine and pass back the BillingResult to the caller. continuation.resume(billingResult) } // Called if the connection to the Play Store service is dropped. // This prevents the await or suspension point from hanging indefinitely. override fun onBillingServiceDisconnected() { continuation.resume( BillingResult.newBuilder() .setResponseCode(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED) .setDebugMessage("Billing service disconnected during connection setup") .build() ) } }) } Java
EnableBillingProgramParams params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperProvidedBillingListener(developerProvidedBillingListener) .build(); BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases( PendingPurchasesParams.newBuilder() .enableOneTimeProducts() .build() ) .enableBillingProgram(params) .build();Prüfen Sie, ob die von Google gerenderte Abrechnung mit Auswahlmöglichkeit für den Nutzer verfügbar ist.
Rufen Sie
isBillingProgramAvailableAsyncauf, um die Programm verfügbarkeit zu prüfen, und rufen Sie dannqueryProductDetailsAsyncauf, um verfügbare Produkte anzuzeigen. Beispiel:Kotlin
val (billingResult, billingProgramAvailabilityDetails) = billingClient.isBillingProgramAvailable(BillingProgram.BILLING_CHOICE) if (billingResult.responseCode == BillingResponseCode.OK) { val billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.billingChoiceAvailabilityDetails if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.choiceScreenType == ChoiceScreenType.GOOGLE_RENDERED ) { // Billing choice is available. Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. }Java
// ... billingClient.isBillingProgramAvailableAsync( BillingProgram.BILLING_CHOICE, (billingResult, billingProgramAvailabilityDetails) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { BillingChoiceAvailabilityDetails billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.getBillingChoiceAvailabilityDetails(); if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.getChoiceScreenType() == ChoiceScreenType.GOOGLE_RENDERED) { // Billing choice is available. Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. } } );Hinweis:
billingProgramAvailabilityDetailsgibt an, ob der von Google gerenderte oder vom Entwickler gerenderte Bildschirm mit Abrechnungsmöglichkeiten verfügbar ist.Rufen Sie
launchBillingFlowauf, um den Kaufvorgang auszulösen, wenn der Nutzer auf „Kaufen“ klickt. Wenn die Abrechnung mit Auswahlmöglichkeit verfügbar ist, übergeben SieDeveloperBillingOptionParamsanBillingFlowParams. Beispiel:Kotlin
val developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build() val billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .enableDeveloperBillingOption(developerBillingOptionParams) .build() val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)Java
DeveloperBillingOptionParams developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build(); BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder() .setProductDetailsParamsList(productDetailsParamsList) .enableDeveloperBillingOption(developerBillingOptionParams) .build(); BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);Hinweis: Für Nutzer mit Elternaufsicht werden Jugendschutzeinstellungen angezeigt.
Verarbeiten Sie die Auswahl des Abrechnungstyps durch den Nutzer so:
- Wenn der Nutzer Google Play Billing auswählt, wird das Abrechnungsergebnis an den
PurchasesUpdatedListenerin Schritt 1 registriert zurückgegeben. - Wenn der Nutzer Ihre alternative Abrechnung auswählt, wird das Abrechnungsergebnis an den in Schritt 1 registrierten
DeveloperProvidedBillingListenerzurückgegeben. In diesem Fall enthältDeveloperProvidedBillingDetailseinexternalTransactionToken. Das Token wird für die Transaktionsberichterstellung verwendet.
- Wenn der Nutzer Google Play Billing auswählt, wird das Abrechnungsergebnis an den
Szenario 1B verarbeiten
Der Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App. Führen Sie die folgenden Schritte aus, um die Abrechnung mit Auswahlmöglichkeit in diesem Szenario zu aktivieren:
Rufen Sie
enableBillingProgramohne dasDeveloperProvidedBillingListenerinEnableBillingProgramParamsbeim Erstellen einerBillingClientInstanz auf und starten Sie dann die Verbindung. Beispiel:Kotlin
// Build the parameters to enable the Billing Choice program. val params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build() // Construct the BillingClient instance with the purchases updated listener, // pending purchases support, and the billing choice params. val billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .enableBillingProgram(params) .build() // Establish a connection to Google Play val billingResult = suspendCancellableCoroutine<BillingResult> { continuation -> billingClient.startConnection(object : BillingClientStateListener { // Called when the connection setup process completes. override fun onBillingSetupFinished(billingResult: BillingResult) { // Resume the coroutine and pass back the BillingResult to the caller. continuation.resume(billingResult) } // Called if the connection to the Play Store service is dropped. // This prevents the await or suspension point from hanging indefinitely. override fun onBillingServiceDisconnected() { continuation.resume( BillingResult.newBuilder() .setResponseCode(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED) .setDebugMessage("Billing service disconnected during connection setup") .build() ) } }) }Java
EnableBillingProgramParams params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build(); BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .enableBillingProgram(params) .build();Prüfen Sie, ob die vom Entwickler gerenderte Abrechnung mit Auswahlmöglichkeit für den Nutzer verfügbar ist.
Rufen Sie
isBillingProgramAvailableAsyncauf, um die Programm verfügbarkeit zu prüfen, und rufen Sie dannqueryProductDetailsAsyncauf, um verfügbare Produkte anzuzeigen. Beispiel:Kotlin
val (billingResult, billingProgramAvailabilityDetails) = billingClient.isBillingProgramAvailable(BillingProgram.BILLING_CHOICE) if (billingResult.responseCode == BillingResponseCode.OK) { val billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.billingChoiceAvailabilityDetails if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.choiceScreenType == ChoiceScreenType.DEVELOPER_RENDERED ) { // Billing choice is available. Query products and proceed. // You can inspect details such as: // - billingChoiceAvailabilityDetails.choiceScreenType // - billingChoiceAvailabilityDetails.isExternalLinkAvailable } else { // Fallback to other available programs. } } else { // Fallback to other available programs. }Java
// ... billingClient.isBillingProgramAvailableAsync( BillingProgram.BILLING_CHOICE, (billingResult, billingProgramAvailabilityDetails) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { BillingChoiceAvailabilityDetails billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.getBillingChoiceAvailabilityDetails(); if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.getChoiceScreenType() == ChoiceScreenType.DEVELOPER_RENDERED) { // Billing choice is available. Query products and proceed. // You can inspect details such as: // - billingChoiceAvailabilityDetails.getChoiceScreenType() // - billingChoiceAvailabilityDetails.isExternalLinkAvailable() } else { // Fallback to other available programs. } } else { // Fallback to other available programs. } } );Hinweis:
billingProgramAvailabilityDetailsgibt an, ob der von Google gerenderte oder vom Entwickler gerenderte Bildschirm mit Abrechnungsmöglichkeiten verfügbar ist.Rufen Sie die Methode
getBillingChoiceInfoAsyncauf, um das Google Play Billing-Banner und Informationen zum Treueprogramm abzurufen. Beispiel:Kotlin
// 1. Create the params required for the request val params = GetBillingChoiceInfoParams.newBuilder() .setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE) .setPlayBillingChoiceImageLayout(GetBillingChoiceInfoParams.ImageLayout.RECTANGULAR_FOUR_BY_ONE) .build() // 2. Call the suspend method on your billingClient instance val (billingResult, playBillingChoiceInfo) = billingClient.getBillingChoiceInfo(params) if (billingResult.responseCode == BillingResponseCode.OK && playBillingChoiceInfo != null) { // Access the URL of the image associated with the Play Billing Choice val imageUrl = playBillingChoiceInfo.playBillingChoiceImageUrl // Access the Play Loyalty string information, if available val loyaltyInfo = playBillingChoiceInfo.playBillingLoyaltyInfo // Populate your developer-rendered UI elements playBillingLoyaltyTextView.text = loyaltyInfo loadImage(imageUrl, playBillingImageView) } else { // Handle error scenarios }Java
// 1. Create the params required for the request GetBillingChoiceInfoParams params = GetBillingChoiceInfoParams.newBuilder() .setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE) .setPlayBillingChoiceImageLayout(GetBillingChoiceInfoParams.ImageLayout.RECTANGULAR_FOUR_BY_ONE) .build(); // 2. Call the method asynchronously on your billingClient instance billingClient.getBillingChoiceInfoAsync(params, (billingResult, playBillingChoiceInfo) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK && playBillingChoiceInfo != null) { // Access the URL of the image associated with the Play Billing Choice String imageUrl = playBillingChoiceInfo.getPlayBillingChoiceImageUrl(); // Access the Play Loyalty string information, if available String loyaltyInfo = playBillingChoiceInfo.getPlayBillingLoyaltyInfo(); // Populate your developer-rendered UI elements playBillingLoyaltyTextView.setText(loyaltyInfo); loadImage(imageUrl, playBillingImageView); } else { // Handle error scenarios } });Erstellen Sie ein externes Transaktionstoken, wobei „DeveloperBillingType“ auf IN_APP festgelegt ist. Beispiel:
Kotlin
// Build the parameters specifying the billing program and that the billing type is IN_APP. val params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.IN_APP) .build() // Call the suspending extension function to request the reporting details val (billingResult, billingProgramReportingDetails) = billingClient.createBillingProgramReportingDetails(params) if (billingResult.responseCode != BillingResponseCode.OK) { // Handle failures such as retrying due to network errors. return } // Extract the transaction token from the returned reporting details val transactionToken = billingProgramReportingDetails?.externalTransactionToken // Persist the external transaction token locally. Pass it to // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external websiteJava
BillingProgramReportingDetailsParams params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.IN_APP) .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 // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external website } } );Wenn der Nutzer auf „Kaufen“ klickt, rufen Sie
showBillingProgramInformationDialogauf, um ein Informationsdialogfeld anzuzeigen. Ein Beispiel finden Sie unter Informationsdialogfeld für Nutzer. BillingProgram und transactionToken aus Schritt 4 müssen in der Anfrage festgelegt werden.Hinweis: Für Nutzer mit Elternaufsicht werden Jugendschutzeinstellungen angezeigt.
Starten Sie Ihren Bildschirm mit der alternativen Abrechnung mit Auswahlmöglichkeit, wenn das Ergebnis aus dem vorherigen Schritt
OKist.Verarbeiten Sie die Auswahl des Abrechnungstyps durch den Nutzer so:
- Wenn der Nutzer Google Play Billing auswählt, rufen Sie
launchBillingFlowgemäß der Standardanleitung für Google Play Billing auf. Das Abrechnungsergebnis wird an denPurchasesUpdatedListenerin Schritt 1 zurückgegeben. - Wenn der Nutzer Ihre alternative Abrechnung auswählt, müssen Sie die Transaktion selbst verarbeiten und mit dem in Schritt 4 generierten Token an Google Play melden.
- Wenn der Nutzer Google Play Billing auswählt, rufen Sie
Szenario 2A verarbeiten
Google rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt außerhalb Ihrer App. Führen Sie die folgenden Schritte aus, um die Abrechnung mit Auswahlmöglichkeit in diesem Szenario zu aktivieren:
Rufen Sie
enableBillingProgrammitEnableBillingProgramParamsauf, wenn Sie Ihre BillingClient-Instanz erstellen, und starten Sie dann die Verbindung. Beispiel:Kotlin
// Build the parameters to enable the Billing Choice program and assign the listener // to handle user selection of the developer-provided billing option. val params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperProvidedBillingListener(developerProvidedBillingListener) .build() // Build the parameters to enable support for pending purchases. val pendingPurchasesParams = PendingPurchasesParams.newBuilder() .enableOneTimeProducts() .build() // Construct the BillingClient instance with the purchases updated listener, // pending purchases support, and the billing choice params. val billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases(pendingPurchasesParams) .enableBillingProgram(params) .build() // Establish a connection to Google Play val billingResult = suspendCancellableCoroutine{ continuation -> billingClient.startConnection(object : BillingClientStateListener { // Called when the connection setup process completes. override fun onBillingSetupFinished(billingResult: BillingResult) { // Resume the coroutine and pass back the BillingResult to the caller. continuation.resume(billingResult) } // Called if the connection to the Play Store service is dropped. // This prevents the await or suspension point from hanging indefinitely. override fun onBillingServiceDisconnected() { continuation.resume( BillingResult.newBuilder() .setResponseCode(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED) .setDebugMessage("Billing service disconnected during connection setup") .build() ) } }) } Java
EnableBillingProgramParams params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperProvidedBillingListener(developerProvidedBillingListener) .build(); BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases( PendingPurchasesParams.newBuilder() .enableOneTimeProducts() .build() ) .enableBillingProgram(params) .build();Prüfen Sie die Verfügbarkeit der folgenden Elemente:
- Von Google gerenderte Abrechnung mit Auswahlmöglichkeit
- Externer Weblink
Rufen Sie
isBillingProgramAvailableAsyncauf, um die Verfügbarkeit des Programms zu prüfen, und rufen Sie dannqueryProductDetailsAsyncauf, um verfügbare Produkte anzuzeigen. Beispiel:Kotlin
// Check the availability of the billing choice program asynchronously using coroutines val (billingResult, billingProgramAvailabilityDetails) = billingClient.isBillingProgramAvailable(BillingProgram.BILLING_CHOICE) // Ensure the billing program query succeeded if (billingResult.responseCode == BillingResponseCode.OK) { // Retrieve the availability details specific to the billing choice program val billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.billingChoiceAvailabilityDetails // Check if billing choice is available, renders via Google Play, and external link is supported if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.choiceScreenType == ChoiceScreenType.GOOGLE_RENDERED && billingChoiceAvailabilityDetails.isExternalLinkAvailable ) { // Billing choice is available and external transaction links are supported. Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. }Java
// ... billingClient.isBillingProgramAvailableAsync( BillingProgram.BILLING_CHOICE, (billingResult, billingProgramAvailabilityDetails) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { BillingChoiceAvailabilityDetails billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.getBillingChoiceAvailabilityDetails(); if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.getChoiceScreenType() == ChoiceScreenType.GOOGLE_RENDERED && billingChoiceAvailabilityDetails.isExternalLinkAvailable()) { // Billing choice is available and external transaction links are supported. // Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. } } );Rufen Sie
createBillingProgramReportingDetailsAsyncauf, um ein externes Transaktionstoken zu erstellen, wenn der Nutzer Kaufinteresse zeigt. Beispiel:Kotlin
// Build the parameters for creating reporting details val params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK) .build() // Call the suspend function to create billing program reporting details val (billingResult, billingProgramReportingDetails) = billingClient.createBillingProgramReportingDetails(params) // Handle response failure cases if (billingResult.responseCode != BillingResponseCode.OK) { // Handle failures such as retrying due to network errors. return } // Retrieve the external transaction token val transactionToken = billingProgramReportingDetails?.externalTransactionToken // Persist the external transaction token locally. Pass it to // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external websiteJava
BillingProgramReportingDetailsParams params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK) .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 // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external website. } } );Rufen Sie
launchBillingFlowauf, um den Kaufvorgang auszulösen, wenn der Nutzer auf „Kaufen“ klickt. Wenn die Abrechnung mit Auswahlmöglichkeit für den Nutzer verfügbar ist, führen Sie die folgenden Schritte aus:- Übergeben Sie DeveloperBillingOptionParams an
BillingFlowParams. - Übergeben Sie das externe Transaktionstoken aus Schritt 3 an
DeveloperBillingOptionParams.
Beispiel:
Kotlin
// Build the developer billing option parameters with the external link URI, // the transaction token, and browser/app launch mode. val developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setLinkUri(Uri.parse("https://www.example.com/external/purchase")) .setExternalTransactionToken(transactionToken) .setLaunchMode( DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP ) .build()Java
DeveloperBillingOptionParams developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setLinkUri(Uri.parse("https://www.example.com/external/purchase")) .setExternalTransactionToken(transactionToken) .setLaunchMode( DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP) .build();Hinweis: Für Nutzer mit Elternaufsicht werden Jugendschutzeinstellungen angezeigt.
- Übergeben Sie DeveloperBillingOptionParams an
Verarbeiten Sie die Auswahl des Abrechnungstyps durch den Nutzer so:
- Wenn der Nutzer Google Play Billing auswählt, rufen Sie
launchBillingFlowgemäß der Standardanleitung für Google Play Billing auf. Das Abrechnungsergebnis wird an denPurchasesUpdatedListenerin Schritt 1 zurückgegeben. - Wenn der Nutzer Ihre alternative Abrechnung auswählt, wird das Abrechnungsergebnis an den
DeveloperProvidedBillingListenerregistrierten in Schritt- zurückgegeben.
- In diesem Fall enthält
DeveloperProvidedBillingDetailsdasexternalTransactionToken, das in Schritt 4 anDeveloperBillingOptionParamsübergeben wurde, sofern es sich um ein gültiges Token handelt.
- In diesem Fall enthält
- Wenn der Nutzer Google Play Billing auswählt, rufen Sie
Szenario 2B verarbeiten
Der Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt außerhalb der App. Führen Sie die folgenden Schritte aus, um die Abrechnung mit Auswahlmöglichkeit in diesem Szenario zu aktivieren:
Rufen Sie
enableBillingProgrambeim Erstellen einer BillingClient Instanz ohne dasDeveloperProvidedBillingListenerinEnableBillingProgramParamsauf und starten Sie dann die Verbindung. Beispiel:Kotlin
// Build the parameters to enable the Billing Choice program. val params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build() // Construct the BillingClient instance with the purchases updated listener, // pending purchases support, and the billing choice params. val billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .enableBillingProgram(params) .build() // Establish a connection to Google Play val billingResult = suspendCancellableCoroutine<BillingResult> { continuation -> billingClient.startConnection(object : BillingClientStateListener { // Called when the connection setup process completes. override fun onBillingSetupFinished(billingResult: BillingResult) { // Resume the coroutine and pass back the BillingResult to the caller. continuation.resume(billingResult) } // Called if the connection to the Play Store service is dropped. // This prevents the await or suspension point from hanging indefinitely. override fun onBillingServiceDisconnected() { continuation.resume( BillingResult.newBuilder() .setResponseCode(BillingClient.BillingResponseCode.SERVICE_DISCONNECTED) .setDebugMessage("Billing service disconnected during connection setup") .build() ) } }) }Java
EnableBillingProgramParams params = EnableBillingProgramParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .build(); BillingClient billingClient = BillingClient.newBuilder(context) .setListener(purchasesUpdatedListener) .enablePendingPurchases() .enableBillingProgram(params) .build();Prüfen Sie die Verfügbarkeit der folgenden Elemente:
- Von Google gerenderte Abrechnung mit Auswahlmöglichkeit
- Externer Weblink
Rufen Sie
isBillingProgramAvailableAsyncauf, um die Verfügbarkeit des Programms zu prüfen, und rufen Sie dannqueryProductDetailsAsyncauf, um verfügbare Produkte anzuzeigen. Beispiel:Kotlin
// Check the availability of the billing choice program asynchronously using a coroutine val (billingResult, billingProgramAvailabilityDetails) = billingClient.isBillingProgramAvailable(BillingProgram.BILLING_CHOICE) // Ensure the response code is OK if (billingResult.responseCode == BillingResponseCode.OK) { // Retrieve the billing choice availability details val billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.billingChoiceAvailabilityDetails // Check if billing choice details are available, choice screen is developer-rendered, // and external transaction links are supported. if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.choiceScreenType == ChoiceScreenType.DEVELOPER_RENDERED && billingChoiceAvailabilityDetails.isExternalLinkAvailable ) { // Billing choice is available and external transaction links are supported. // Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. }Java
// ... billingClient.isBillingProgramAvailableAsync( BillingProgram.BILLING_CHOICE, (billingResult, billingProgramAvailabilityDetails) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK) { BillingChoiceAvailabilityDetails billingChoiceAvailabilityDetails = billingProgramAvailabilityDetails.getBillingChoiceAvailabilityDetails(); if (billingChoiceAvailabilityDetails != null && billingChoiceAvailabilityDetails.getChoiceScreenType() == ChoiceScreenType.DEVELOPER_RENDERED && billingChoiceAvailabilityDetails.isExternalLinkAvailable()) { // Billing choice is available and external transaction links are supported. Query products and proceed. } else { // Fallback to other available programs. } } else { // Fallback to other available programs. } } );Rufen Sie die Methode
getBillingChoiceInfoAsyncauf, um das Google Play Billing-Banner und Informationen zum Treueprogramm abzurufen.Kotlin
// 1. Create the params required for the request val params = GetBillingChoiceInfoParams.newBuilder() .setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE) .setPlayBillingChoiceImageLayout(GetBillingChoiceInfoParams.ImageLayout.RECTANGULAR_FOUR_BY_ONE) .build() // 2. Call the suspend method on your billingClient instance val (billingResult, playBillingChoiceInfo) = billingClient.getBillingChoiceInfo(params) if (billingResult.responseCode == BillingResponseCode.OK && playBillingChoiceInfo != null) { // Access the URL of the image associated with the Play Billing Choice val imageUrl = playBillingChoiceInfo.playBillingChoiceImageUrl // Access the Play Loyalty string information, if available val loyaltyInfo = playBillingChoiceInfo.playBillingLoyaltyInfo // Populate your developer-rendered UI elements playBillingLoyaltyTextView.text = loyaltyInfo loadImage(imageUrl, playBillingImageView) } else { // Handle error scenarios }Java
// 1. Create the params required for the request GetBillingChoiceInfoParams params = GetBillingChoiceInfoParams.newBuilder() .setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE) .setPlayBillingChoiceImageLayout(GetBillingChoiceInfoParams.ImageLayout.RECTANGULAR_FOUR_BY_ONE) .build(); // 2. Call the method asynchronously on your billingClient instance billingClient.getBillingChoiceInfoAsync(params, (billingResult, playBillingChoiceInfo) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK && playBillingChoiceInfo != null) { // Access the URL of the image associated with the Play Billing Choice String imageUrl = playBillingChoiceInfo.getPlayBillingChoiceImageUrl(); // Access the Play Loyalty string information, if available String loyaltyInfo = playBillingChoiceInfo.getPlayBillingLoyaltyInfo(); // Populate your developer-rendered UI elements playBillingLoyaltyTextView.setText(loyaltyInfo); loadImage(imageUrl, playBillingImageView); } else { // Handle error scenarios } });Rufen Sie
createBillingProgramReportingDetailsAsyncauf, um ein externes Transaktionstoken zu erstellen, wenn der Nutzer Kaufinteresse zeigt. Beispiel:Kotlin
// Build the parameters for creating reporting details val params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK) .build() // Call the suspend function to create billing program reporting details val (billingResult, billingProgramReportingDetails) = billingClient.createBillingProgramReportingDetails(params) // Handle response failure cases if (billingResult.responseCode != BillingResponseCode.OK) { // Handle failures such as retrying due to network errors. return } // Retrieve the external transaction token val transactionToken = billingProgramReportingDetails?.externalTransactionToken // Persist the external transaction token locally. Pass it to // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external websiteJava
BillingProgramReportingDetailsParams params = BillingProgramReportingDetailsParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) .setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK) .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 // DeveloperBillingOptionParams when launchBillingFlow is called. // It can also be used as part of your external website. } } );Starten Sie Ihren Bildschirm mit der alternativen Abrechnung mit Auswahlmöglichkeit, wenn der Nutzer auf „Kaufen“ klickt.
Verarbeiten Sie die Auswahl des Abrechnungstyps durch den Nutzer so:
Wenn der Nutzer Google Play Billing auswählt, rufen Sie
launchBillingFlowgemäß der Standardanleitung für Google Play Billing auf. Das Abrechnungsergebnis wird an denPurchasesUpdatedListenerin Schritt 1 zurückgegeben.Für Nutzer mit Elternaufsicht werden Jugendschutzeinstellungen angezeigt.
Wenn der Nutzer Ihre alternative Abrechnung auswählt, rufen Sie `launchExternalLink` auf. Beispiel:
Kotlin
// An activity reference from which the purchase flow will be launched. val activity: Activity = ... val params = LaunchExternalLinkParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) // You can pass along the external transaction token from // BillingProgramReportingDetails as a URL parameter in the URI .setLinkUri(yourLinkUri) .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_DIGITAL_CONTENT_OFFER) .setLaunchMode( LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP ) .build() // Call launchExternalLink with a callback billingClient.launchExternalLink(activity, params) { billingResult -> if (billingResult.responseCode == BillingResponseCode.OK) { // Proceed with the rest of the purchase 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. } }Java
// An activity reference from which the purchase flow will be launched. Activity activity = ...; LaunchExternalLinkParams params = LaunchExternalLinkParams.newBuilder() .setBillingProgram(BillingProgram.BILLING_CHOICE) // You can pass along the external transaction token from // BillingProgramReportingDetails as a URL parameter in the URI .setLinkUri(yourLinkUri) .setLinkType(LaunchExternalLinkParams.LinkType.LINK_TO_DIGITAL_CONTENT_OFFER) .setLaunchMode( LaunchExternalLinkParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP) .setExternalTransactionToken(transactionToken) .build(); LaunchExternalLinkResponseListener listener = new LaunchExternalLinkResponseListener() { @Override public void onLaunchExternalLinkResponse(BillingResult billingResult) { if (billingResult.getResponseCode() == BillingResponseCode.OK) { // Proceed with the rest of the purchase 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);Übergeben Sie das externe Transaktionstoken aus Schritt 4 an
LaunchExternalLinkParams. Wenn „OK“ zurückgegeben wird, fahren Sie mit der Transaktion fort und melden Sie sie Google Play.Für Nutzer mit Elternaufsicht werden Jugendschutzeinstellungen angezeigt.
Abrechnung mit Auswahlmöglichkeit beim Ersetzen eines Abos
Beim Ersetzen eines Abos sollte der Bildschirm mit der Nutzerauswahl nicht angezeigt werden, da die Nutzerauswahl für den ursprünglichen Kauf für Upgrades und Downgrades beibehalten wird.
Wenn der ursprüngliche Kauf über Google Play Billing abgewickelt wurde, sollten Sie
launchBillingFlow mit den Standardinformationen zum Ersetzen von Abos in Google Play Billing
aufrufen.
Wenn der ursprüngliche Kauf jedoch über eine alternative Abrechnung abgewickelt wurde, unterscheidet sich die Verarbeitung von Abo-Ersetzungen je nach den Szenarien leicht.
Abo-Ersetzung in Szenario 1A
Nutzer, die ein Upgrade oder Downgrade anfordern, sollten das alternative Abrechnungssystem des Entwicklers verwenden, ohne noch einmal die Nutzerauswahl durchlaufen zu müssen.
Rufen Sie dazu launchBillingFlow auf, wenn der Nutzer ein Upgrade oder ein
Downgrade anfordert. Verwenden Sie setOriginalExternalTransactionId im Objekt SubscriptionUpdateParams in den Parametern, um die externe Transaktions-ID für den ursprünglichen Kauf anzugeben. Der Bildschirm mit der Nutzerauswahl wird nicht angezeigt, da die Nutzerauswahl für den ursprünglichen Kauf für Upgrades und Downgrades beibehalten wird. Der Aufruf von launchBillingFlow generiert in diesem Fall
ein neues externes Transaktionstoken für die Transaktion, das Sie
über den Callback abrufen können.
Kotlin
// The external transaction ID from the current
// alternative billing subscription.
val externalTransactionId = //... ;
val developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder()
.setBillingProgram(BillingProgram.BILLING_CHOICE)
.build()
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
// Fetched using queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails.
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
BillingFlowParams.SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build()
)
.enableDeveloperBillingOption(developerBillingOptionParams)
.build()
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)
// When the user selects the alternative billing flow,
// the DeveloperProvidedBillingListener is triggered.
Java
// The external transaction ID from the current
// alternative billing subscription.
String externalTransactionId = //... ;
DeveloperBillingOptionParams developerBillingOptionParams =
DeveloperBillingOptionParams.newBuilder()
.setBillingProgram(BillingProgram.BILLING_CHOICE)
.build();
List<ProductDetailsParams> productDetailsParamsList = new ArrayList<>();
productDetailsParamsList.add(
ProductDetailsParams.newBuilder()
// Fetched using queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in
// ProductDetails=>SubscriptionOfferDetails
.setOfferToken(offerTokenNewPlan)
.build());
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setSubscriptionUpdateParams(
SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build())
.enableDeveloperBillingOption(developerBillingOptionParams)
.build();
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);
// When the user selects the alternative billing flow,
// the DeveloperProvidedBillingListener is triggered.
Abo-Ersetzung in Szenario 1B
In diesem Szenario muss ein neues externes Transaktionstoken generiert werden. Der einzige Unterschied zu einem normalen Kauf besteht darin, dass in diesem Szenario die Nutzerauswahl beibehalten wird und Sie den Bildschirm mit den Auswahlmöglichkeiten für das Upgrade oder Downgrade nicht anzeigen müssen. Sie müssen jedoch das einmalige Informationsdialogfeld und die Bestätigung der Eltern anzeigen.
Beispielcode für die Einbindung finden Sie in Schritt 4 unter Szenario 1B: Der Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App.
Abo-Ersetzung in Szenario 2A
Bei Abos, die ursprünglich nach der Nutzerauswahl über die Website des Entwicklers oder eine Zahlungs-App gekauft wurden, sollten Nutzer, die ein Upgrade oder Downgrade anfordern, die Website des Entwicklers oder eine Zahlungs-App verwenden, ohne noch einmal die Nutzerauswahl durchlaufen zu müssen.
Rufen Sie dazu launchBillingFlow auf, wenn der Nutzer ein Upgrade oder ein
Downgrade anfordert. Anstatt andere Parameter im
SubscriptionUpdateParams Objekt anzugeben, verwenden Sie setOriginalExternalTransactionId,
und geben Sie die externe Transaktions-ID für den ursprünglichen Kauf an.
DeveloperBillingOptionParams muss ebenfalls in diesem Aufruf angegeben werden. Der Bildschirm mit den Nutzerauswahlmöglichkeiten wird nicht angezeigt, da die Nutzerauswahl für den ursprünglichen Kauf für Upgrades und Downgrades beibehalten wird. Beispiel:
Kotlin
val externalTransactionId = //... ;
// 1. Construct DeveloperBillingOptionParams indicating the billing program
val developerBillingOptionParams = DeveloperBillingOptionParams.newBuilder()
.setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE)
.build()
// 2. Build BillingFlowParams combining DeveloperBillingOptionParams and SubscriptionUpdateParams
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
listOf(
BillingFlowParams.ProductDetailsParams.newBuilder()
// Fetched using queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in ProductDetails=>SubscriptionOfferDetails.
.setOfferToken(offerTokenNewPlan)
.build()
)
)
.setSubscriptionUpdateParams(
SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build()
)
.enableDeveloperBillingOption(developerBillingOptionParams)
.build()
Java
String externalTransactionId = //... ;
// 1. Construct DeveloperBillingOptionParams indicating the billing program
DeveloperBillingOptionParams developerBillingOptionParams =
DeveloperBillingOptionParams.newBuilder()
.setBillingProgram(BillingClient.BillingProgram.BILLING_CHOICE)
.build();
// 2. Add ProductDetailsParams
List productDetailsParamsList = new ArrayList<>();
productDetailsParamsList.add(
ProductDetailsParams.newBuilder()
// Fetched using queryProductDetailsAsync.
.setProductDetails(productDetailsNewPlan)
// offerIdToken can be found in ProductDetails=>SubscriptionOfferDetails
.setOfferToken(offerTokenNewPlan)
.build());
// 3. Build BillingFlowParams combining DeveloperBillingOptionParams and SubscriptionUpdateParams
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetailsParamsList)
.setSubscriptionUpdateParams(
SubscriptionUpdateParams.newBuilder()
.setOriginalExternalTransactionId(externalTransactionId)
.build())
.enableDeveloperBillingOption(developerBillingOptionParams)
.build();
Sie müssen auch ein neues externes Transaktionstoken generieren. Beispiel:
Kotlin
val params =
BillingProgramReportingDetailsParams.newBuilder()
.setBillingProgram(BillingProgram.BILLING_CHOICE)
.setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK)
.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.BILLING_CHOICE)
.setDeveloperBillingType(DeveloperBillingType.EXTERNAL_LINK)
.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.
}
});
Nachdem Sie das neue Token generiert haben, müssen Sie die launchBillingFlow
Methode aufrufen, um den Kaufvorgang zu starten.
Abo-Ersetzung in Szenario 2B
Die Schritte zum Verarbeiten von Abo-Ersetzungen in diesem Szenario ähneln den Schritten, die unter Abo-Ersetzung in Szenario 2A beschrieben sind. Der einzige
Unterschied besteht darin, dass Sie nach dem Generieren des Transaktionstokens anstelle der Methode launchBillingFlow die Methode launchExternalLink aufrufen müssen, um
das Dialogfeld mit dem Haftungsausschluss für externe Links anzuzeigen. In diesem Szenario wird die Nutzerauswahl beibehalten und Sie müssen den Bildschirm mit den Auswahlmöglichkeiten für das Upgrade oder Downgrade nicht anzeigen.
Beispielcode für die Einbindung finden Sie in Schritt 6 unter Szenario 2B: Der Entwickler rendert den Bildschirm mit den Auswahlmöglichkeiten und die alternative Abrechnung erfolgt in Ihrer App.