Integra la Libreria Fatturazione Google Play per PC nativi nella tua app

Monetizza il tuo gioco vendendo prodotti digitali tramite 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 che ha avviato il gioco all'interno del client Google Play Giochi e non richiedono passaggi di accesso aggiuntivi.

Se hai eseguito l'integrazione con la libreria Fatturazione Google Play per Android, queste API Fatturazione Play dovrebbero esserti familiari. Tutte le integrazioni lato server con Play Billing possono essere riutilizzate dai titoli per PC, in quanto sono le stesse sia su Android che su PC.

Prerequisiti

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

Quando l'applicazione viene avviata o torna in primo piano, esegui una query per gli acquisti. Ciò è 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. Eseguire 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 per i tuoi prodotti disponibili e mostrarli ai tuoi utenti. La query per i dettagli del prodotto è un passaggio importante prima di mostrare i tuoi prodotti agli utenti, in quanto restituisce informazioni localizzate sul prodotto.

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

  1. Esegui query per i dettagli del prodotto utilizzando BillingClient::QueryProductDetails. Inserisci gli ID prodotto che hai registrato in Google Play Console.
  2. Visualizza ProductDetails che include il nome localizzato e il prezzo dell'offerta del prodotto.
  3. Conserva un riferimento all'offer_token del prodotto. Questo 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, sei pronto ad avviare il flusso di acquisto.

  1. Inizia chiamando BillingClient::LaunchPurchaseFlow(). Passa in il offer_token ottenuto durante l'interrogazione dei dettagli del prodotto.
  2. Una volta completato l'acquisto, la funzione di continuazione verrà chiamata con il risultato.
  3. In caso di esito positivo, la 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 purchase_token al tuo server di backend. Completa il resto dell'elaborazione utilizzando le API di fatturazione Google Play lato server. Questa integrazione lato server è la stessa eseguita per un gioco per Android che è stato integrato con la Fatturazione Google 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
}

Elaborare senza un server di backend

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

  2. Concedi all'utente l'accesso al prodotto acquistato e aggiorna l'archivio dei diritti del tuo gioco.

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

    1. Se l'acquisto non è stato confermato, comunica a Google che all'utente viene concesso un diritto sul prodotto chiamando il numero BillingClient::AcknowledgePurchase.
  4. Per gli acquisti di prodotti di consumo (prodotti che possono essere acquistati più di una volta), comunica a Google che all'utente viene concesso un diritto sul prodotto chiamando 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 puoi testare l'integrazione con la Fatturazione Google Play. Per eseguire i 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 che ti consigliamo di eseguire, consulta la documentazione su come testare l'integrazione di Libreria Fatturazione Google Play.