Integra la Libreria Fatturazione Google Play nella tua app

Monetizza il tuo gioco vendendo prodotti digitali tramite la Fatturazione Google Play. L'SDK offre API per mostrare i prodotti disponibili per l'acquisto, avviare il flusso di acquisto ed elaborare gli acquisti. Le chiamate a queste API di fatturazione vengono eseguite utilizzando l'Account Google con cui è stato lanciato il gioco all'interno del client Google Play Games e non richiedono ulteriori passaggi di accesso.

Se hai eseguito l'integrazione con la libreria Android Play Billing, queste API Play Billing dovrebbero sembrarti familiari. Qualsiasi integrazione lato server con Play Billing può essere riutilizzata dai titoli per PC, in quanto sono uguali su Android e PC.

Prerequisiti

Passaggio 1: esegui una query per gli acquisti precedenti e quelli completati al di fuori della tua applicazione

Quando l'applicazione si avvia o quando torna in primo piano, effettua una query per gli acquisti. Questo è necessario per rilevare gli acquisti effettuati al di fuori del tuo gioco o per sbloccare l'accesso agli acquisti effettuati in precedenza dall'utente.

  1. Esegui query per gli acquisti utilizzando BillingClient::QueryPurchases.

  2. Continua elaborando gli acquisti.

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

Passaggio 2: mostra i prodotti disponibili per l'acquisto

Ora puoi eseguire query sui prodotti disponibili e mostrarli ai tuoi utenti. La query per i dettagli del prodotto è un passaggio importante prima di mostrare i prodotti agli utenti, in quanto restituisce informazioni sui prodotti localizzate.

Prima di offrire un prodotto in vendita, controlla che l'utente non lo possieda già. Se l'utente ha un prodotto di consumo ancora nella sua cronologia acquisti, devi consumarlo prima che possa acquistarlo di nuovo.

  1. Esegui una query per i dettagli del prodotto utilizzando BillingClient::QueryProductDetails. Passa gli ID prodotto che hai registrato in Google Play Console.
  2. Mostra ProductDetails, che include il nome e il prezzo dell'offerta localizzati del prodotto.
  3. Conserva un riferimento a offer_token del prodotto. Viene utilizzato per avviare un flusso di acquisto per l'offerta.
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
}

Passaggio 3: avvia un flusso di acquisto

Quando l'utente mostra l'intenzione di acquistare un prodotto che gli hai mostrato, significa che è pronto per avviare il flusso di acquisto.

  1. Per iniziare, chiama BillingClient::LaunchPurchaseFlow(). Passa il valore offer_token ottenuto quando esegui una query sui dettagli del prodotto.
  2. Una volta completato l'acquisto, verrà chiamata la funzione di continuazione con il risultato.
  3. In caso di esito positivo, il messaggio di continuazione contiene un ProductPurchaseDetails. Continua elaborando l'acquisto.
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
}

Passaggio 4: elabora un acquisto

Elaborazione con un server di backend

Per i giochi con un server di backend, completa l'elaborazione inviando il messaggio purchase_token al server di backend. Completa il resto dell'elaborazione utilizzando le API di fatturazione Play lato server. Questa integrazione lato server è la stessa utilizzata per un gioco per Android integrato con Fatturazione 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
}

Elaborazione senza un server di backend

  1. Assicurati che il pagamento dell'utente non sia in attesa controllando se ProductPurchaseDetails::purchase_state è PurchaseState::kPurchaseStatePurchased. Se lo stato dell'acquisto è in attesa, comunica all'utente che deve completare ulteriori passaggi prima di poter ricevere il prodotto acquistato.

  2. Concedi all'utente l'accesso al prodotto acquistato e aggiorna lo spazio di archiviazione dei diritti del tuo gioco.

  3. Per gli acquisti non di consumo (prodotti che possono essere acquistati una sola volta), controlla se l'acquisto è già stato confermato utilizzando ProductPurchaseDetails::is_acknowledged.

    1. Se l'acquisto non è stato confermato, comunica a Google che all'utente viene concesso un diritto per il prodotto chiamando BillingClient::AcknowledgePurchase.
  4. Per gli acquisti di prodotti di consumo (prodotti che possono essere acquistati più volte), informa Google che all'utente viene concesso un diritto al prodotto chiamando il numero 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;
}

Passaggio 5: testa l'integrazione

Ora è tutto pronto per testare l'integrazione con Fatturazione Play. Per eseguire test durante la fase di sviluppo, ti consigliamo di utilizzare i tester delle licenze. I tester delle licenze hanno accesso ai pagamenti di prova che evitano l'addebito di denaro reale per gli acquisti.

Per istruzioni su come configurare i tester delle licenze e una suite di test manuali, consigliamo di consultare la documentazione su come testare l'integrazione della Libreria Fatturazione Google Play.