Google Play Faturalandırma Kitaplığı'nı (Yerel PC) uygulamanıza entegre etme

Play Faturalandırma'yı kullanarak dijital ürünler satarak oyununuzdan para kazanın. SDK, satın alınabilecek ürünleri göstermek, satın alma akışını başlatmak ve satın alma işlemlerini işlemek için API'ler sunar. Bu faturalandırma API'lerine yapılan çağrılar, Google Play Games istemcisinde oyunu başlatan Google Hesabı kullanılarak gerçekleştirilir ve ek oturum açma adımı gerektirmez.

Android Play Faturalandırma Kitaplığı ile entegrasyon yaptıysanız bu Play Faturalandırma API'leri size tanıdık gelecektir. Play Faturalandırma ile yapılan tüm sunucu tarafı entegrasyonları, hem Android hem de PC'de aynı olduğu için PC oyunlarında yeniden kullanılabilir.

Ön koşullar

1. adım: Önceki satın alma işlemleri ve uygulamanızın dışında tamamlanan satın alma işlemleri için sorgu oluşturun

Uygulamanız başlatıldığında veya tekrar ön plana getirildiğinde satın alma işlemlerini sorgulayın. Bu, oyununuzun dışında yapılan satın alma işlemlerini tespit etmek veya kullanıcının daha önce yaptığı satın alma işlemlerine erişimi açmak için gereklidir.

  1. BillingClient::QueryPurchases kullanılarak yapılan satın alma işlemleri için sorgu.

  2. Satın alma işlemlerini işleyerek devam edin.

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

2. adım: Satın alınabilecek ürünleri gösterin

Kullanılabilir ürünlerinizle ilgili sorgu göndermeye ve bunları kullanıcılarınıza göstermeye hazırsınız. Ürün ayrıntıları için sorgu göndermek, ürünlerinizi kullanıcılarınıza göstermeden önce önemli bir adımdır. Bu adım, yerelleştirilmiş ürün bilgilerini döndürür.

Bir ürünü satışa sunmadan önce kullanıcının bu ürüne sahip olup olmadığını kontrol edin. Kullanıcının satın alma geçmişinde hala kullanılmamış bir tüketilebilir ürün varsa kullanıcı ürünü tekrar satın almadan önce ürünü tüketmeniz gerekir.

  1. BillingClient::QueryProductDetails kullanarak ürün ayrıntılarını sorgulayın. Google Play Console'da kaydettiğiniz ürün kimliklerini iletin.
  2. Ürünün yerelleştirilmiş adını ve teklif fiyatını içeren ProductDetails öğesini oluşturun.
  3. Ürünün offer_token için referansı koruyun. Bu özellik, teklif için satın alma sürecini başlatmak üzere kullanılır.
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
}

3. adım: Satın alma akışı başlatın

Kullanıcı, gösterdiğiniz bir ürünü satın alma niyeti gösterdiğinde satın alma akışını başlatmaya hazır olduğunuzu belirtin.

  1. BillingClient::LaunchPurchaseFlow() numaralı telefonu arayarak başlayın. Ürün ayrıntıları sorgulanırken alınan offer_token iletilmelidir.
  2. Satın alma işlemi tamamlandıktan sonra devam ettirme işlevi sonuçla birlikte çağrılır.
  3. Başarılı olursa devamlılık, ProductPurchaseDetails öğesini içerir. Satın alma işlemini yaparak devam edin.
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
}

4. adım: Satın alma işlemini gerçekleştirin

Arka uç sunucusuyla işleme

Arka uç sunucusu olan oyunlarda, purchase_token öğesini arka uç sunucunuza göndererek işlemi tamamlayın. Sunucu tarafı Play Faturalandırma API'lerini kullanarak işlemin geri kalanını tamamlayın. Bu sunucu tarafı entegrasyonu, Play Faturalandırma ile entegre edilmiş bir Android oyunu için yapılan entegrasyonla aynıdır.

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
}

Arka uç sunucusu olmadan işleme

  1. ProductPurchaseDetails::purchase_state değerinin PurchaseState::kPurchaseStatePurchased olup olmadığını kontrol ederek kullanıcının ödemesinin beklemede olmadığından emin olun. Satın alma durumu beklemede ise kullanıcıya, satın aldığı ürünü alabilmesi için ek adımları tamamlaması gerektiğini bildirin.

  2. Kullanıcıya satın alınan ürüne erişim izni verin ve oyununuzun hak depolama alanını güncelleyin.

  3. Tüketilebilir olmayan satın alma işlemleri (yalnızca bir kez satın alınabilen ürünler) için ProductPurchaseDetails::is_acknowledged kullanarak satın alma işleminin zaten kabul edilip edilmediğini kontrol edin.

    1. Satın alma işlemi onaylanmadıysa BillingClient::AcknowledgePurchase numaralı telefonu arayarak Google'a kullanıcının ürünü kullanma yetkisi aldığını bildirin.
  4. Tüketilebilir satın alma işlemleri (birden fazla kez satın alınabilen ürünler) için BillingClient::ConsumePurchase işlevini çağırarak kullanıcıya ürün için hak verildiğini Google'a bildirin.

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

5. adım: Entegrasyonunuzu test edin

Artık Google Play Faturalandırma ile entegrasyonunuzu test etmeye hazırsınız. Geliştirme aşamasında test yapmak için lisans test kullanıcılarından yararlanmanızı öneririz. Lisans test kullanıcıları, satın alma işlemlerinde gerçek para alınmasını önleyen test ödemelerine erişebilir.

Lisans test kullanıcılarını ve bir dizi manuel testi nasıl ayarlayacağınıza ilişkin talimatlar için Google Play Faturalandırma Kitaplığı entegrasyonunuzu test etme ile ilgili dokümanları incelemenizi öneririz.