আপনার অ্যাপে Google Play বিলিং লাইব্রেরি সংহত করুন

প্লে বিলিং ব্যবহার করে ডিজিটাল পণ্য বিক্রি করে আপনার গেম নগদীকরণ করুন। SDK কেনার জন্য উপলব্ধ পণ্যগুলি দেখাতে, ক্রয় প্রবাহ চালু করতে এবং কেনাকাটা প্রক্রিয়া করার জন্য API অফার করে। এই বিলিং APIগুলিতে কলগুলি Google অ্যাকাউন্ট ব্যবহার করে করা হয় যা Google Play Games ক্লায়েন্টের ভিতরে গেমটি চালু করেছে এবং এর জন্য কোনও অতিরিক্ত সাইন-ইন পদক্ষেপের প্রয়োজন নেই৷

আপনি যদি অ্যান্ড্রয়েড প্লে বিলিং লাইব্রেরির সাথে একত্রিত হয়ে থাকেন তাহলে এই প্লে বিলিং এপিআইগুলি পরিচিত দেখা উচিত৷ প্লে বিলিং এর সাথে যেকোনো সার্ভার-সাইড ইন্টিগ্রেশন পিসি শিরোনাম দ্বারা পুনরায় ব্যবহার করা যেতে পারে কারণ সেগুলি অ্যান্ড্রয়েড এবং পিসি উভয় ক্ষেত্রেই একই।

পূর্বশর্ত

ধাপ 1 : আপনার আবেদনের বাইরে সম্পন্ন পূর্ববর্তী কেনাকাটা এবং কেনাকাটার জন্য ক্যোয়ারী

আপনার অ্যাপ্লিকেশান যখন শুরু হয় বা যখন এটি ফোরগ্রাউন্ডে পুনরায় প্রবেশ করে তখন কেনাকাটার জন্য জিজ্ঞাসা করুন৷ এটি আপনার গেমের বাইরে সংঘটিত কেনাকাটাগুলি সনাক্ত করতে বা ব্যবহারকারীর দ্বারা পূর্বে করা কেনাকাটাগুলিতে অ্যাক্সেস আনলক করতে প্রয়োজনীয়৷

  1. BillingClient::QueryPurchases ব্যবহার করে কেনাকাটার জন্য ক্যোয়ারী।

  2. ক্রয় প্রক্রিয়াকরণ করে চালিয়ে যান।

// 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 : কেনার জন্য উপলব্ধ পণ্য দেখান

আপনি আপনার উপলব্ধ পণ্যগুলির জন্য অনুসন্ধান করতে এবং আপনার ব্যবহারকারীদের কাছে সেগুলি প্রদর্শন করতে প্রস্তুত৷ আপনার ব্যবহারকারীদের কাছে আপনার পণ্যগুলি প্রদর্শন করার আগে পণ্যের বিবরণের জন্য অনুসন্ধান করা একটি গুরুত্বপূর্ণ পদক্ষেপ, কারণ এটি স্থানীয় পণ্যের তথ্য প্রদান করে।

বিক্রয়ের জন্য একটি পণ্য অফার করার আগে, ব্যবহারকারী ইতিমধ্যে পণ্যটির মালিক না কিনা তা পরীক্ষা করুন। যদি ব্যবহারকারীর কাছে একটি ভোগ্য জিনিস থাকে যা এখনও তাদের ক্রয়ের ইতিহাসে থাকে, তাহলে তারা এটি আবার কেনার আগে আপনাকে অবশ্যই পণ্যটি ব্যবহার করতে হবে।

  1. BillingClient::QueryProductDetails ব্যবহার করে পণ্যের বিবরণের জন্য প্রশ্ন করুন। Google Play Console-এ আপনি যে প্রোডাক্ট আইডি রেজিস্টার করেছেন সেগুলি পাস করুন।
  2. ProductDetails রেন্ডার করুন যাতে পণ্যের স্থানীয় নাম এবং অফার মূল্য অন্তর্ভুক্ত থাকে।
  3. পণ্যের offer_token একটি রেফারেন্স রাখুন। এটি অফারের জন্য একটি ক্রয় প্রবাহ চালু করতে ব্যবহৃত হয়।
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 : একটি ক্রয় প্রবাহ চালু করুন

যখন ব্যবহারকারী একটি পণ্য কেনার অভিপ্রায় দেখান তখন আপনি তাদের দেখিয়েছেন যে আপনি ক্রয় প্রবাহ চালু করতে প্রস্তুত৷

  1. BillingClient::LaunchPurchaseFlow() কল করে শুরু করুন। পণ্যের বিবরণ জিজ্ঞাসা করার সময় প্রাপ্ত offer_token পাস করুন।
  2. একবার ক্রয় সম্পন্ন হলে ফলাফলের সাথে ধারাবাহিকতা ফাংশন কল করা হবে।
  3. সফল হলে, ধারাবাহিকতায় একটি ProductPurchaseDetails থাকে। ক্রয় প্রক্রিয়া করে চালিয়ে যান।
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 : একটি ক্রয় প্রক্রিয়া

একটি ব্যাকএন্ড সার্ভারের সাথে প্রক্রিয়া করুন

ব্যাকএন্ড সার্ভার সহ গেমগুলির জন্য, আপনার ব্যাকএন্ড সার্ভারে purchase_token পাঠিয়ে প্রক্রিয়াকরণ সম্পূর্ণ করুন। সার্ভার-সাইড প্লে বিলিং এপিআই ব্যবহার করে প্রক্রিয়াকরণের অবশিষ্ট অংশ সম্পূর্ণ করুন। এই সার্ভার-সাইড ইন্টিগ্রেশনটি প্লে বিলিং-এর সাথে ইন্টিগ্রেট করা Android গেমের মতোই।

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
}

একটি ব্যাকএন্ড সার্ভার ছাড়া প্রক্রিয়া

  1. ProductPurchaseDetails::purchase_state কি PurchaseState::kPurchaseStatePurchased চেক করে ব্যবহারকারীর অর্থপ্রদান মুলতুবি নেই তা নিশ্চিত করুন। ক্রয় অবস্থা মুলতুবি থাকলে ব্যবহারকারীকে অবহিত করুন যে তাদের ক্রয়কৃত পণ্য গ্রহণ করার আগে তাদের অতিরিক্ত পদক্ষেপগুলি সম্পূর্ণ করতে হবে।

  2. ব্যবহারকারীকে ক্রয়কৃত পণ্যে অ্যাক্সেস দিন এবং আপনার গেমের এনটাইটেলমেন্ট স্টোরেজ আপডেট করুন।

  3. অ-ভোগযোগ্য কেনাকাটার জন্য (যে পণ্যগুলি শুধুমাত্র একবার কেনা যায়) ProductPurchaseDetails::is_acknowledged ব্যবহার করে ইতিমধ্যেই ক্রয় স্বীকার করা হয়েছে কিনা তা পরীক্ষা করুন।

    1. যদি ক্রয়টি স্বীকৃত না হয়ে থাকে তাহলে Google-কে জানান যে ব্যবহারকারীকে BillingClient::AcknowledgePurchase কল করে পণ্যটির একটি এনটাইটেলমেন্ট দেওয়া হচ্ছে।
  4. ব্যবহারযোগ্য কেনাকাটার জন্য (যে পণ্যগুলি একাধিকবার কেনা হতে পারে) Google-কে জানান যে ব্যবহারকারীকে 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;
}

ধাপ 5 : আপনার ইন্টিগ্রেশন পরীক্ষা করুন

আপনি এখন প্লে বিলিং এর সাথে আপনার ইন্টিগ্রেশন পরীক্ষা করার জন্য প্রস্তুত৷ উন্নয়ন পর্বের সময় পরীক্ষা করার জন্য, আমরা লাইসেন্স পরীক্ষকদের ব্যবহার করার পরামর্শ দিই। লাইসেন্স পরীক্ষকদের পরীক্ষার অর্থপ্রদানের অ্যাক্সেস রয়েছে যা ক্রয়ের জন্য আসল অর্থ চার্জ করা এড়ায়।

লাইসেন্স পরীক্ষক এবং ম্যানুয়াল পরীক্ষার একটি স্যুট সেটআপ করার নির্দেশাবলীর জন্য আমরা অনুশীলন করার পরামর্শ দিই কিভাবে আপনার Google Play বিলিং লাইব্রেরি ইন্টিগ্রেশন পরীক্ষা করবেন তার ডকুমেন্টেশন দেখুন।