Google Play Billing Library in deine App integrieren

Mit Play Billing können Sie digitale Produkte verkaufen und so Einnahmen mit Ihrem Spiel erzielen. Das SDK bietet APIs, um zum Kauf verfügbare Produkte anzuzeigen, den Kaufvorgang zu starten und Käufe zu verarbeiten. Aufrufe dieser Abrechnungs-APIs erfolgen über das Google-Konto, mit dem das Spiel im Google Play Spiele-Client gestartet wurde. Es sind keine zusätzlichen Anmeldeschritte erforderlich.

Wenn Sie die Android Play Billing Library eingebunden haben, sollten Ihnen diese Play Billing APIs bekannt vorkommen. Alle serverseitigen Einbindungen in die Play-Abrechnung können für PC-Titel wiederverwendet werden, da sie für Android und PC identisch sind.

Voraussetzungen

Schritt 1: Vorherige Käufe und Käufe abfragen, die außerhalb Ihrer Anwendung abgeschlossen wurden

Wenn Ihre Anwendung gestartet wird oder wieder in den Vordergrund wechselt, können Sie nach Käufen fragen. Dies ist erforderlich, um Käufe zu erkennen, die außerhalb Ihres Spiels stattgefunden haben, oder um den Zugriff auf Käufe zu entsperren, die der Nutzer zuvor getätigt hat.

  1. Erstellen Sie eine Abfrage für Käufe mit BillingClient::QueryPurchases.

  2. Verarbeite die Käufe.

// Query for purchases when:
// - Application starts up
// - Application window re-enters the foreground
auto promise = std::make_shared<std::promise<QueryPurchasesResult>>();
billing_client.QueryPurchases([promise](QueryPurchasesResult result) {
   promise->set_value(std::move(result));
});

auto query_purchases_result = promise->get_future().get();
if (query_purchases_result.ok()) {
  auto purchases = query_purchases_result.value().product_purchase_details;
  // Process the purchases
} else {
  // Handle the error
}

Schritt 2: Zum Kauf verfügbare Produkte anzeigen

Sie können jetzt nach Ihren verfügbaren Produkten suchen und sie Ihren Nutzern präsentieren. Die Abfrage von Produktdetails ist ein wichtiger Schritt, bevor Ihre Produkte Nutzern präsentiert werden, da so lokalisierte Produktinformationen zurückgegeben werden.

Bevor du ein Produkt zum Verkauf anbietest, solltest du prüfen, ob der Nutzer das Produkt bereits besitzt. Wenn der Nutzer ein Verbrauchsprodukt hat, das sich noch in seinem bisherigen Kaufverlauf befindet, muss er es aufbrauchen, bevor er es noch einmal kaufen kann.

  1. Abfrage von Produktdetails mit BillingClient::QueryProductDetails Gib die Produkt-IDs ein, die du in der Google Play Console registriert hast.
  2. Rendere den ProductDetails, der den lokalisierten Namen und Angebotspreis des Produkts enthält.
  3. Behalten Sie den Verweis auf die offer_token des Produkts bei. Damit wird ein Kaufvorgang für das Angebot gestartet.
QueryProductDetailsParams params;
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_costmetic_1", ProductType::kTypeInApp});
params.product_ids.push_back({"example_battle_pass", ProductType::kTypeInApp});

auto promise = std::make_shared<std::promise<QueryProductDetailsResult>>();
billing_client.QueryProductDetails(params, [promise](QueryProductDetailsResult result) {
   promise->set_value(std::move(result));
});

auto query_product_details_result = promise->get_future().get();
if (query_product_details_result.ok()) {
   auto product_details = query_product_details_result.value().product_details;
   // Display the available products and their offers to the user
} else {
   // Handle the error
}

Schritt 3: Kaufvorgang starten

Wenn der Nutzer die Absicht zeigt, ein Produkt zu kaufen, das Sie ihm präsentiert haben, sind Sie bereit, den Kaufvorgang zu starten.

  1. Rufen Sie zuerst BillingClient::LaunchPurchaseFlow() an. Gib die offer_token ein, die du bei der Abfrage der Produktdetails erhalten hast.
  2. Sobald der Kauf abgeschlossen ist, wird die Fortsetzungsfunktion mit dem Ergebnis aufgerufen.
  3. Bei Erfolg enthält die Fortsetzung eine ProductPurchaseDetails. Fahren Sie mit der Verarbeitung des Kaufs fort.
LaunchPurchaseFlowParams params { product_offer.offer_token };

auto promise = std::make_shared<std::promise<LaunchPurchaseFlowResult>>();
billing_client.LaunchPurchaseFlow(params, [promise](LaunchPurchaseFlowResult result) {
   promise->set_value(std::move(result));
});
// The purchase flow has started and is now in progress.

auto launch_purchase_flow_result = promise->get_future().get();

// The purchase flow has now completed.
if (launch_purchase_flow_result.ok()) {
   auto purchase = launch_purchase_flow_result.value().product_purchase_details;
   // Process the purchase
} else if (launch_purchase_flow_result.code() == BillingError::kUserCanceled) {
   // Handle an error caused by the user canceling the purchase flow
} else {
   // Handle any other error codes
}

Schritt 4: Kauf abwickeln

Mit einem Backend-Server verarbeiten

Bei Spielen mit einem Backend-Server müssen Sie die Verarbeitung abschließen, indem Sie die purchase_token an Ihren Backend-Server senden. Führen Sie die restliche Verarbeitung mit den serverseitigen Play Billing APIs durch. Diese serverseitige Integration entspricht der für ein Android-Spiel, das Play Billing integriert hat.

void ProcessPurchasesWithServer(std::vector<ProductPurchaseDetails> purchases) {
   std::vector<std::string> purchase_tokens;
   for (const auto& purchase : purchases) {
      purchase_tokens.push_back(purchase.purchase_token);
   }

   // Send purchase tokens to backend server for processing
}

Prozess ohne Backend-Server

  1. Prüfe, ob die Zahlung des Nutzers nicht ausstehend ist. Dazu vergleiche ProductPurchaseDetails::purchase_state mit PurchaseState::kPurchaseStatePurchased. Wenn der Kaufstatus ausstehend ist, informiere den Nutzer, dass er zusätzliche Schritte ausführen muss, bevor er sein gekauftes Produkt erhalten kann.

  2. Gewähren Sie dem Nutzer Zugriff auf das gekaufte Produkt und aktualisieren Sie den Berechtigungsspeicher Ihres Spiels.

  3. Prüfe bei Käufen von nicht verbrauchbaren Produkten (Produkten, die nur einmal gekauft werden können), ob der Kauf bereits mit ProductPurchaseDetails::is_acknowledged bestätigt wurde.

    1. Wenn der Kauf nicht bestätigt wurde, teile Google mit, dass dem Nutzer eine Berechtigung für das Produkt gewährt wird, indem du BillingClient::AcknowledgePurchase anrufst.
  4. Bei Käufen von Verbrauchsgütern (Produkten, die mehrmals gekauft werden können) müssen Sie Google darüber informieren, dass dem Nutzer ein Anspruch auf das Produkt gewährt wird. Rufen Sie dazu BillingClient::ConsumePurchase auf.

void ProcessPurchasesWithoutServer(std::vector<ProductPurchaseDetails> purchases) {
   std::vector<std::string> entitled_product_ids;
   for (const auto& purchase : purchases) {
      auto was_successful = ProcessPurchasePurchaseWithoutServer(purchase);
      if (was_successful) {
         entitled_product_ids.push_back(purchase.product_id);
      }
   }

   // Note that non-consumable products that were previously purchased may have
   // been refunded. These purchases will stop being returned by
   // `QueryPurchases()`. If your game has given a user access to one of these
   // products storage they should be revoked.
   //
   // ...
}

bool ProcessPurchasePurchaseWithoutServer(ProductPurchaseDetails purchase) {
   auto is_purchase_completed =
      purchase.purchase_state == PurchaseState::kPurchaseStatePurchased;
   if (!is_purchase_completed) {
      // Notify the user that they need to take additional steps to complete
      // this purchase.
      return false;
   }

   // Determine if the product ID is associated with a consumable product.
   auto is_consumable = IsConsumableProductId(purchase.product_id);
   if (is_consumable) {
      // Grant an entitlement to the product to the user.
      // ...
      // Then, notify Google by consuming the purchase.

      ConsumePurchaseParams params { purchase.purchase_token };
      auto promise = std::make_shared<std::promise<ConsumePurchaseResult>>();
      billing_client.ConsumePurchase(params, [promise](ConsumePurchaseResult result) {
         promise->set_value(std::move(result));
      });

      auto consume_purchase_result = promise->get_future().get();
      if (!consume_purchase_result.ok()) {
         // Examine the failure code & message for more details & notify user
         // of failure.
         // ...
         return false;
      }

      return true;
   }

   // Otherwise the product is assumed to be a non-consumable.

   // Grant an entitlement to the product to the user.
   // ...
   // Then, notify Google by acknowledging the purchase (if not already done).

   if (purchase.is_acknowledged) {
      return true;
   }

   AcknowledgePurchaseParams params { purchase.purchase_token };
   auto promise = std::make_shared<std::promise<AcknowledgePurchaseResult>>();
   billing_client.AcknowledgePurchase(params, [promise](AcknowledgePurchaseResult result) {
      promise->set_value(std::move(result));
   });

   auto acknowledge_purchase_result = promise->get_future().get();
   if (!acknowledge_purchase_result.ok()) {
      // Examine the failure code & message for more details & notify user
      // of failure.
      // ...
      return false;
   }

   return true;
}

Schritt 5: Integration testen

Sie können jetzt Ihre Integration mit Play Billing testen. Für Tests während der Entwicklungsphase empfehlen wir die Verwendung von Lizenztestern. Lizenztester haben Zugriff auf Testzahlungen, bei denen für Käufe kein echtes Geld berechnet wird.

Eine Anleitung zum Einrichten von Lizenztestern und eine Reihe manueller Tests finden Sie in der Dokumentation zum Testen der Einbindung der Google Play Billing Library.