Integrowanie Biblioteki płatności w Google Play z aplikacją

Zarabiaj na swojej grze, sprzedając produkty cyfrowe za pomocą Płatności w Google Play. Pakiet SDK udostępnia interfejsy API do wyświetlania produktów dostępnych do kupienia, uruchamiania procesu zakupu i przetwarzania zakupów. Wywołania tych interfejsów API do rozliczeń są wykonywane za pomocą konta Google, na którym uruchomiono grę w ramach klienta Google Play Games, i nie wymagają żadnych dodatkowych czynności logowania.

Jeśli masz już za sobą integrację z Biblioteką płatności w Google Play, te interfejsy API powinny być Ci znane. Wszelkie integracje z systemem płatności Play Billing można ponownie wykorzystać w tytułach na PC, ponieważ są one takie same na Androida i PC.

Wymagania wstępne

Krok 1. Zapytanie o wcześniejsze zakupy i zakupy dokonane poza aplikacją

Gdy aplikacja uruchamia się lub wraca na pierwszy plan, wysyła zapytanie o zakupy. Jest to konieczne do wykrywania zakupów dokonanych poza grą lub do odblokowania dostępu do zakupów dokonanych wcześniej przez użytkownika.

  1. Zapytanie o zakupy przy użyciu BillingClient::QueryPurchases.

  2. Kontynuuj przetwarzanie zakupów.

// 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
}

Krok 2. Pokaż produkty dostępne do kupienia

Możesz już wysyłać zapytania o dostępne produkty i wyświetlać je użytkownikom. Wysyłanie zapytań o szczegóły produktów jest ważnym krokiem przed wyświetleniem produktów użytkownikom, ponieważ zwraca ono zlokalizowane informacje o produktach.

Zanim zaoferujesz produkt do sprzedaży, sprawdź, czy użytkownik nie ma już tego produktu. Jeśli użytkownik ma produkt jednorazowy, który nadal znajduje się w jego historii zakupów, musisz go zużyć, zanim będzie mógł go kupić ponownie.

  1. Wyszukaj szczegóły produktu za pomocą zapytania BillingClient::QueryProductDetails. Przekaż identyfikatory produktów zarejestrowane w Konsoli Google Play.
  2. Wyrenderuj element ProductDetails, który zawiera lokalizowaną nazwę produktu i cenę oferty.
  3. Zachowaj odwołanie do offer_token produktu. Służy on do uruchomienia procesu zakupu oferty.
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
}

Krok 3. Uruchom proces zakupu

Gdy użytkownik wyrazi chęć zakupu produktu, który mu wyświetliłeś, możesz rozpocząć proces zakupu.

  1. Zacznij od zadzwonienia na numer BillingClient::LaunchPurchaseFlow(). Przekaż offer_token uzyskany podczas zapytania o szczegóły produktu.
  2. Po zakończeniu zakupu zostanie wywołana funkcja kontynuacji z otrzymanym wynikiem.
  3. W przypadku powodzenia ciąg dalszy zawiera element ProductPurchaseDetails. Kontynuuj, przetwarzając zakup.
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
}

Krok 4. Przeprowadź zakup.

Przetwarzanie na serwerze backend

W przypadku gier z serwerem backendu przetwarzanie można dokończyć, wysyłając purchase_token na serwer backendu. Dokończ pozostałą część przetwarzania za pomocą interfejsów Play Billing API po stronie serwera. Ta integracja po stronie serwera jest taka sama jak w przypadku gry na Androida zintegrowanej z Płatnościami w Play.

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
}

Przetwarzanie bez serwera backendowego

  1. Upewnij się, że płatność użytkownika nie jest oczekująca, sprawdzając, czy parametr ProductPurchaseDetails::purchase_state ma wartość PurchaseState::kPurchaseStatePurchased. Jeśli stan zakupu to „Oczekuje”, poinformuj użytkownika, że musi wykonać dodatkowe czynności, zanim otrzyma zakupiony produkt.

  2. Przyznasz użytkownikowi dostęp do zakupionego produktu i zaktualizujesz pamięć uprawnień gry.

  3. W przypadku zakupów niekonsumpcyjnych (produktów, które można kupić tylko raz) sprawdź, czy zakup został już potwierdzony za pomocą ProductPurchaseDetails::is_acknowledged.

    1. Jeśli zakup nie został potwierdzony, poinformuj Google, że użytkownikowi przyznano uprawnienia do produktu, dzwoniąc pod numer BillingClient::AcknowledgePurchase.
  4. W przypadku zakupów produktów konsumpcyjnych (produktów, które można kupić więcej niż raz) poinformuj Google, że użytkownikowi przyznano uprawnienia do produktu, dzwoniąc pod numer BillingClient::ConsumePurchase.

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;
}

Krok 5. Sprawdź integrację

Możesz teraz przetestować integrację z płatnościami w Google Play. Aby przetestować aplikację na etapie rozwoju, zalecamy skorzystanie z usługi Tester licencji. Testerzy licencji mają dostęp do testowych form płatności, które umożliwiają uniknięcie pobierania prawdziwych pieniędzy za zakupy.

Instrukcje konfigurowania testerów licencji i pakietu testów ręcznych znajdziesz w dokumentacji Testowanie integracji z Biblioteką płatności w Google Play.