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

এই ডকুমেন্টে বর্ণনা করা হয়েছে কিভাবে পণ্য বিক্রি শুরু করার জন্য আপনার অ্যাপে Google Play বিলিং লাইব্রেরি সংহত করবেন।

একটি ক্রয়ের জীবন

এককালীন কেনাকাটা বা সাবস্ক্রিপশনের জন্য এখানে একটি সাধারণ ক্রয় প্রবাহ দেওয়া হল।

  1. ব্যবহারকারীকে দেখান যে তারা কী কিনতে পারে।
  2. ব্যবহারকারী যাতে ক্রয়টি গ্রহণ করতে পারেন তার জন্য ক্রয় প্রবাহ চালু করুন।
  3. আপনার সার্ভারে ক্রয়টি যাচাই করুন।
  4. ব্যবহারকারীকে কন্টেন্ট দিন।
  5. সামগ্রী সরবরাহের বিষয়টি স্বীকার করুন। ব্যবহারযোগ্য পণ্যের ক্ষেত্রে, ক্রয়কৃত পণ্যটি ব্যবহার করুন যাতে ব্যবহারকারী আবার আইটেমটি কিনতে পারেন।

সাবস্ক্রিপশন বাতিল না হওয়া পর্যন্ত স্বয়ংক্রিয়ভাবে নবায়ন হয়। একটি সাবস্ক্রিপশন নিম্নলিখিত অবস্থার মধ্য দিয়ে যেতে পারে:

  • সক্রিয় : ব্যবহারকারীর অবস্থা ভালো এবং সাবস্ক্রিপশনে অ্যাক্সেস আছে।
  • বাতিল করা হয়েছে : ব্যবহারকারী বাতিল করেছেন কিন্তু মেয়াদ শেষ না হওয়া পর্যন্ত অ্যাক্সেস থাকবে।
  • অতিরিক্ত সময়ের মধ্যে : ব্যবহারকারীর পেমেন্টের সমস্যা হয়েছে কিন্তু Google যখন পেমেন্ট পদ্ধতিটি পুনরায় চেষ্টা করছে তখনও তার অ্যাক্সেস থাকবে।
  • হোল্ডে রাখা হয়েছে : ব্যবহারকারীর পেমেন্টের সমস্যা হয়েছে এবং Google যখন পেমেন্ট পদ্ধতিটি পুনরায় চেষ্টা করছে তখন তিনি আর অ্যাক্সেস করতে পারছেন না।
  • বিরতি : ব্যবহারকারী তাদের অ্যাক্সেস বিরতি দিয়েছেন এবং পুনরায় শুরু না হওয়া পর্যন্ত অ্যাক্সেস পাবেন না।
  • মেয়াদোত্তীর্ণ : ব্যবহারকারী সাবস্ক্রিপশন বাতিল করেছেন এবং অ্যাক্সেস হারিয়েছেন। মেয়াদোত্তীর্ণ হওয়ার সময় ব্যবহারকারীকে মন্থর বলে মনে করা হবে।

গুগল প্লেতে একটি সংযোগ শুরু করুন

গুগল প্লে-এর বিলিং সিস্টেমের সাথে একীভূত হওয়ার প্রথম ধাপ হল আপনার অ্যাপে গুগল প্লে বিলিং লাইব্রেরি যোগ করা এবং একটি সংযোগ শুরু করা।

Google Play বিলিং লাইব্রেরি নির্ভরতা যোগ করুন

আপনার অ্যাপের build.gradle ফাইলে Google Play Billing Library নির্ভরতা যোগ করুন যেমন দেখানো হয়েছে:

গ্রোভি

dependencies {
    def billing_version = "8.1.0"

    implementation "com.android.billingclient:billing:$billing_version"
}

কোটলিন

dependencies {
    val billing_version = "8.1.0"

    implementation("com.android.billingclient:billing:$billing_version")
}

যদি আপনি Kotlin ব্যবহার করেন, তাহলে Google Play Billing Library KTX মডিউলে Kotlin এক্সটেনশন এবং coroutines সাপোর্ট রয়েছে যা আপনাকে Google Play Billing Library ব্যবহার করার সময় ইডিওম্যাটিক Kotlin লিখতে সক্ষম করে। আপনার প্রোজেক্টে এই এক্সটেনশনগুলি অন্তর্ভুক্ত করতে, আপনার অ্যাপের build.gradle ফাইলে নিম্নলিখিত নির্ভরতা যোগ করুন যেমন দেখানো হয়েছে:

গ্রোভি

dependencies {
    def billing_version = "8.1.0"

    implementation "com.android.billingclient:billing-ktx:$billing_version"
}

কোটলিন

dependencies {
    val billing_version = "8.1.0"

    implementation("com.android.billingclient:billing-ktx:$billing_version")
}

একটি বিলিং ক্লায়েন্ট শুরু করুন

একবার আপনি Google Play Billing Library-তে একটি নির্ভরতা যোগ করলে, আপনাকে একটি BillingClient ইনস্ট্যান্স শুরু করতে হবে। BillingClient হল Google Play Billing Library এবং আপনার অ্যাপের বাকি অংশের মধ্যে যোগাযোগের প্রধান ইন্টারফেস। BillingClient অনেক সাধারণ বিলিং ক্রিয়াকলাপের জন্য সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস উভয় সুবিধাজনক পদ্ধতি প্রদান করে। নিম্নলিখিতগুলি মনে রাখবেন:

  • একটি ইভেন্টের জন্য একাধিক PurchasesUpdatedListener কলব্যাক এড়াতে, একসাথে একটি সক্রিয় BillingClient সংযোগ খোলা রাখা বাঞ্ছনীয়।
  • আপনার অ্যাপটি যখন চালু হয় বা সামনে আসে তখন BillingClient-এর জন্য একটি সংযোগ শুরু করার পরামর্শ দেওয়া হয় যাতে আপনার অ্যাপটি সময়মতো কেনাকাটা প্রক্রিয়া করে। registerActivityLifecycleCallbacks দ্বারা নিবন্ধিত ActivityLifecycleCallbacks ব্যবহার করে এবং যখন আপনি প্রথমবার কোনও কার্যকলাপ পুনরায় শুরু হচ্ছে তা সনাক্ত করেন তখন onActivityResumed শুনে সংযোগ শুরু করে এটি করা যেতে পারে। কেন এই সর্বোত্তম অনুশীলন অনুসরণ করা উচিত সে সম্পর্কে আরও বিশদ জানতে ক্রয় প্রক্রিয়াকরণ বিভাগটি দেখুন। আপনার অ্যাপটি বন্ধ হয়ে গেলে সংযোগটি বন্ধ করতে ভুলবেন না।

একটি BillingClient তৈরি করতে, newBuilder ব্যবহার করুন। আপনি যেকোনো প্রসঙ্গ newBuilder() এ পাস করতে পারেন, এবং BillingClient এটি ব্যবহার করে একটি অ্যাপ্লিকেশন প্রসঙ্গ পেতে পারে। এর অর্থ হল আপনাকে মেমরি লিক সম্পর্কে চিন্তা করতে হবে না। কেনাকাটার আপডেট পেতে, আপনাকে setListener কল করতে হবে, PurchasesUpdatedListener এর একটি রেফারেন্স পাঠাতে হবে। এই শ্রোতা আপনার অ্যাপে সমস্ত কেনাকাটার আপডেট পাবেন।

কোটলিন

private val purchasesUpdatedListener =
   PurchasesUpdatedListener { billingResult, purchases ->
       // To be implemented in a later section.
   }

private var billingClient = BillingClient.newBuilder(context)
   .setListener(purchasesUpdatedListener)
   // Configure other settings.
   .build()

জাভা

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // To be implemented in a later section.
    }
};

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    // Configure other settings.
    .build();

গুগল প্লেতে সংযোগ করুন

একটি BillingClient তৈরি করার পরে, আপনাকে Google Play এর সাথে একটি সংযোগ স্থাপন করতে হবে।

গুগল প্লেতে সংযোগ করতে, startConnection কল করুন। সংযোগ প্রক্রিয়াটি অ্যাসিঙ্ক্রোনাস, এবং ক্লায়েন্টের সেটআপ সম্পূর্ণ হয়ে গেলে এবং এটি আরও অনুরোধ করার জন্য প্রস্তুত হলে কলব্যাক পেতে আপনাকে একটি BillingClientStateListener প্রয়োগ করতে হবে।

Google Play-তে হারিয়ে যাওয়া সংযোগগুলি পরিচালনা করার জন্য আপনাকে retry logic প্রয়োগ করতে হবে। retry logic প্রয়োগ করতে, onBillingServiceDisconnected() কলব্যাক পদ্ধতিটি ওভাররাইড করুন এবং আরও অনুরোধ করার আগে নিশ্চিত করুন যে BillingClient Google Play-তে পুনরায় সংযোগ করার জন্য startConnection() পদ্ধতিটি কল করে।

নিম্নলিখিত উদাহরণটি দেখায় যে কীভাবে একটি সংযোগ শুরু করতে হয় এবং এটি ব্যবহারের জন্য প্রস্তুত কিনা তা পরীক্ষা করতে হয়:

কোটলিন

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(billingResult: BillingResult) {
        if (billingResult.responseCode ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    override fun onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
})

জাভা

billingClient.startConnection(new BillingClientStateListener() {
    @Override
    public void onBillingSetupFinished(BillingResult billingResult) {
        if (billingResult.getResponseCode() ==  BillingResponseCode.OK) {
            // The BillingClient is ready. You can query purchases here.
        }
    }
    @Override
    public void onBillingServiceDisconnected() {
        // Try to restart the connection on the next request to
        // Google Play by calling the startConnection() method.
    }
});

স্বয়ংক্রিয়ভাবে একটি সংযোগ পুনঃস্থাপন করুন

৮.০.০ সংস্করণে BillingClient.BuilderenableAutoServiceReconnection() পদ্ধতি প্রবর্তনের মাধ্যমে, Play Billing Library এখন স্বয়ংক্রিয়ভাবে পরিষেবা সংযোগ পুনঃস্থাপন করতে পারে যদি পরিষেবাটি সংযোগ বিচ্ছিন্ন থাকা অবস্থায় একটি API কল করা হয়। এর ফলে SERVICE_DISCONNECTED প্রতিক্রিয়া হ্রাস পেতে পারে কারণ API কল করার আগে পুনরায় সংযোগটি অভ্যন্তরীণভাবে পরিচালনা করা হয়।

কীভাবে স্বয়ংক্রিয় পুনঃসংযোগ সক্ষম করবেন

একটি BillingClient ইনস্ট্যান্স তৈরি করার সময়, স্বয়ংক্রিয় পুনঃসংযোগ সক্ষম করতে BillingClient.BuilderenableAutoServiceReconnection() পদ্ধতিটি ব্যবহার করুন।

কোটলিন

val billingClient = BillingClient.newBuilder(context)
    .setListener(listener)
    .enablePendingPurchases()
    .enableAutoServiceReconnection() // Add this line to enable reconnection
    .build()

জাভা

BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(listener)
    .enablePendingPurchases()
    .enableAutoServiceReconnection() // Add this line to enable reconnection
    .build();

কিনতে পাওয়া পণ্যগুলি দেখান

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

আপনার ব্যবহারকারীদের কাছে আপনার পণ্য প্রদর্শনের আগে পণ্যের বিবরণের জন্য জিজ্ঞাসা করা একটি গুরুত্বপূর্ণ পদক্ষেপ, কারণ এটি স্থানীয় পণ্যের তথ্য প্রদান করে। সাবস্ক্রিপশনের জন্য, যাচাই করুন যে আপনার পণ্য প্রদর্শন সমস্ত Play নীতি অনুসরণ করে

এককালীন পণ্যের বিবরণ জানতে, queryProductDetailsAsync পদ্ধতিতে কল করুন। এই পদ্ধতিটি আপনার এককালীন পণ্য কনফিগারেশনের উপর ভিত্তি করে একাধিক অফার ফেরত দিতে পারে। আরও তথ্যের জন্য, এককালীন পণ্যের জন্য একাধিক ক্রয় বিকল্প এবং অফার দেখুন।

অ্যাসিঙ্ক্রোনাস অপারেশনের ফলাফল পরিচালনা করার জন্য, আপনাকে এমন একটি শ্রোতাও নির্দিষ্ট করতে হবে যা ProductDetailsResponseListener ইন্টারফেসটি প্রয়োগ করে। এরপর আপনি onProductDetailsResponse ওভাররাইড করতে পারেন, যা কোয়েরি শেষ হলে শ্রোতাকে অবহিত করে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

কোটলিন

val queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build()

billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
    billingResult,
    queryProductDetailsResult ->
      if (billingResult.getResponseCode() == BillingResponseCode.OK) {
               for (ProductDetails productDetails : queryProductDetailsResult.getProductDetailsList()) {
                 // Process successfully retrieved product details here.
               }

               for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) {
                 // Handle any unfetched products as appropriate.
               }
            }
}

জাভা

QueryProductDetailsParams queryProductDetailsParams =
    QueryProductDetailsParams.newBuilder()
        .setProductList(
            ImmutableList.of(
                Product.newBuilder()
                    .setProductId("product_id_example")
                    .setProductType(ProductType.SUBS)
                    .build()))
        .build();

billingClient.queryProductDetailsAsync(
    queryProductDetailsParams,
    new ProductDetailsResponseListener() {
        public void onProductDetailsResponse(BillingResult billingResult,
                QueryProductDetailsResult queryProductDetailsResult) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
               for (ProductDetails productDetails : queryProductDetailsResult().getProductDetailsList()) {
                 // Process success retrieved product details here.
               }

               for (UnfetchedProduct unfetchedProduct : queryproductDetailsResult.getUnfetchedProductList()) {
                 // Handle any unfetched products as appropriate.
               }
            }
        }
    }
)

পণ্যের বিবরণের জন্য জিজ্ঞাসা করার সময়, QueryProductDetailsParams এর একটি উদাহরণ দিন যা Google Play Console-এ তৈরি পণ্য আইডি স্ট্রিংগুলির একটি তালিকা এবং একটি ProductType নির্দিষ্ট করে। ProductType এককালীন পণ্যের জন্য ProductType.INAPP অথবা সাবস্ক্রিপশনের জন্য ProductType.SUBS হতে পারে।

কোটলিন এক্সটেনশনের সাহায্যে কোয়েরি

আপনি যদি Kotlin এক্সটেনশন ব্যবহার করেন , তাহলে আপনি queryProductDetails() এক্সটেনশন ফাংশনে কল করে এককালীন পণ্যের বিবরণের জন্য অনুসন্ধান করতে পারেন।

queryProductDetails() Kotlin coroutine ব্যবহার করে যাতে আপনাকে আলাদা শ্রোতা নির্ধারণ করতে না হয়। পরিবর্তে, ফাংশনটি স্থগিত থাকে যতক্ষণ না কোয়েরি সম্পন্ন হয়, যার পরে আপনি ফলাফল প্রক্রিয়া করতে পারেন:

suspend fun processPurchases() {
    val productList = listOf(
        QueryProductDetailsParams.Product.newBuilder()
            .setProductId("product_id_example")
            .setProductType(BillingClient.ProductType.SUBS)
            .build()
    )
    val params = QueryProductDetailsParams.newBuilder()
    params.setProductList(productList)

    // leverage queryProductDetails Kotlin extension function
    val productDetailsResult = withContext(Dispatchers.IO) {
        billingClient.queryProductDetails(params.build())
    }

    // Process the result.
}

কদাচিৎ, কিছু ডিভাইস ProductDetails এবং queryProductDetailsAsync() সমর্থন করতে অক্ষম হয়, সাধারণত Google Play Services এর পুরানো সংস্করণের কারণে। এই পরিস্থিতিতে সঠিক সহায়তা প্রদানের জন্য, Play Billing Library 7 মাইগ্রেশন গাইডে ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বৈশিষ্ট্যগুলি কীভাবে ব্যবহার করবেন তা শিখুন।

ফলাফল প্রক্রিয়া করুন

গুগল প্লে বিলিং লাইব্রেরি কোয়েরির ফলাফলগুলিকে একটি QueryProductDetailsResult অবজেক্টে সংরক্ষণ করে। QueryProductDetailsResult ProductDetails অবজেক্টের একটি List থাকে। এরপর আপনি তালিকার প্রতিটি ProductDetails অবজেক্টে বিভিন্ন পদ্ধতিতে কল করতে পারেন যাতে সফলভাবে আনা এককালীন পণ্য সম্পর্কে প্রাসঙ্গিক তথ্য, যেমন এর দাম বা বিবরণ দেখা যায়। উপলব্ধ পণ্যের বিস্তারিত তথ্য দেখতে, ProductDetails ক্লাসে পদ্ধতিগুলির তালিকা দেখুন।

QueryProductDetailsResult UnfetchedProduct অবজেক্টের একটি List রয়েছে। এরপর আপনি প্রতিটি UnfetchedProduct-কে জিজ্ঞাসা করে ফেচ ব্যর্থতার কারণের সাথে সম্পর্কিত একটি স্ট্যাটাস কোড পেতে পারেন। উপলব্ধ আনফেট করা পণ্যের তথ্য দেখতে, UnfetchedProduct ক্লাসে পদ্ধতির তালিকা দেখুন।

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

সাবস্ক্রিপশন অফার করার আগে, ব্যবহারকারী ইতিমধ্যেই সাবস্ক্রাইব নন কিনা তা যাচাই করুন। এছাড়াও নিম্নলিখিত বিষয়গুলি মনে রাখবেন:

  • সাবস্ক্রিপশনের জন্য, queryProductDetailsAsync() পদ্ধতিটি সাবস্ক্রিপশন পণ্যের বিবরণ এবং প্রতি সাবস্ক্রিপশনে সর্বাধিক ৫০ জন ব্যবহারকারীর জন্য যোগ্য অফার প্রদান করে। যদি ব্যবহারকারী একটি অযোগ্য অফার কেনার চেষ্টা করেন (উদাহরণস্বরূপ, যদি অ্যাপটি যোগ্য অফারগুলির একটি পুরানো তালিকা প্রদর্শন করে), তাহলে Play ব্যবহারকারীকে জানায় যে তারা অযোগ্য, এবং ব্যবহারকারী পরিবর্তে বেস প্ল্যানটি কিনতে পারেন।

  • এককালীন পণ্যের জন্য, queryProductDetailsAsync() পদ্ধতি শুধুমাত্র ব্যবহারকারীর জন্য উপযুক্ত অফারগুলি ফেরত দেয়। যদি ব্যবহারকারী এমন কোনও অফার কেনার চেষ্টা করেন যার জন্য তারা অযোগ্য (উদাহরণস্বরূপ, যদি ব্যবহারকারী ক্রয়ের পরিমাণের সীমায় পৌঁছে যান), তাহলে Play ব্যবহারকারীকে জানায় যে তারা অযোগ্য, এবং ব্যবহারকারী তার পরিবর্তে তার ক্রয় বিকল্প অফারটি কিনতে পারেন।

ক্রয় প্রবাহ চালু করুন

আপনার অ্যাপ থেকে ক্রয়ের অনুরোধ শুরু করতে, আপনার অ্যাপের মূল থ্রেড থেকে launchBillingFlow() পদ্ধতিতে কল করুন। এই পদ্ধতিটি একটি BillingFlowParams অবজেক্টের রেফারেন্স নেয় যাতে queryProductDetailsAsync কল করার মাধ্যমে প্রাপ্ত প্রাসঙ্গিক ProductDetails অবজেক্ট থাকে। একটি BillingFlowParams অবজেক্ট তৈরি করতে, BillingFlowParams.Builder ক্লাস ব্যবহার করুন।

কোটলিন

// An activity reference from which the billing flow will be launched.
val activity : Activity = ...;

val productDetailsParamsList = listOf(
    BillingFlowParams.ProductDetailsParams.newBuilder()
        // retrieve a value for productDetails by calling queryProductDetailsAsync()
        .setProductDetails(productDetails)
        // Get the offer token:
        // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
        // for a list of offers that are available to the user.
        // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
        // for a list of offers that are available to the user.
        .setOfferToken(selectedOfferToken)
        .build()
)

val billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build()

// Launch the billing flow
val billingResult = billingClient.launchBillingFlow(activity, billingFlowParams)

জাভা

// An activity reference from which the billing flow will be launched.
Activity activity = ...;

ImmutableList<ProductDetailsParams> productDetailsParamsList =
    ImmutableList.of(
        ProductDetailsParams.newBuilder()
             // retrieve a value for "productDetails" by calling queryProductDetailsAsync()
            .setProductDetails(productDetails)
            // Get the offer token:
            // a. For one-time products, call ProductDetails.getOneTimePurchaseOfferDetailsList()
            // for a list of offers that are available to the user.
            // b. For subscriptions, call ProductDetails.subscriptionOfferDetails()
            // for a list of offers that are available to the user.
            .setOfferToken(selectedOfferToken)
            .build()
    );

BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
    .setProductDetailsParamsList(productDetailsParamsList)
    .build();

// Launch the billing flow
BillingResult billingResult = billingClient.launchBillingFlow(activity, billingFlowParams);

launchBillingFlow() পদ্ধতিটি BillingClient.BillingResponseCode এ তালিকাভুক্ত বেশ কয়েকটি প্রতিক্রিয়া কোডের মধ্যে একটি প্রদান করে। ক্রয় প্রবাহ চালু করার সময় কোনও ত্রুটি ছিল কিনা তা যাচাই করতে এই ফলাফলটি পরীক্ষা করে দেখুন। OK এর একটি BillingResponseCode একটি সফল লঞ্চ নির্দেশ করে।

launchBillingFlow() এ সফল কল করলে, সিস্টেমটি Google Play ক্রয় স্ক্রিন প্রদর্শন করে। চিত্র 1 সাবস্ক্রিপশনের জন্য একটি ক্রয় স্ক্রিন দেখায়:

গুগল প্লে ক্রয় স্ক্রিনে একটি সাবস্ক্রিপশন দেখা যাচ্ছে যা কেনার জন্য উপলব্ধ।
চিত্র ১. গুগল প্লে ক্রয় স্ক্রিনে একটি সাবস্ক্রিপশন দেখানো হয়েছে যা কেনার জন্য উপলব্ধ।

Google Play onPurchasesUpdated() কে ক্রয় অপারেশনের ফলাফল এমন একটি শ্রোতার কাছে পৌঁছে দেওয়ার জন্য কল করে যা PurchasesUpdatedListener ইন্টারফেস প্রয়োগ করে। যখন আপনি আপনার ক্লায়েন্ট শুরু করেন তখন setListener() পদ্ধতি ব্যবহার করে শ্রোতা নির্দিষ্ট করা হয়।

সম্ভাব্য রেসপন্স কোডগুলি পরিচালনা করার জন্য আপনাকে onPurchasesUpdated() প্রয়োগ করতে হবে। নিম্নলিখিত উদাহরণটি দেখায় কিভাবে onPurchasesUpdated() ওভাররাইড করতে হয়:

কোটলিন

override fun onPurchasesUpdated(billingResult: BillingResult, purchases: List<Purchase>?) {
   if (billingResult.responseCode == BillingResponseCode.OK && purchases != null) {
       for (purchase in purchases) {
           // Process the purchase as described in the next section.
       }
   } else if (billingResult.responseCode == BillingResponseCode.USER_CANCELED) {
       // Handle an error caused by a user canceling the purchase flow.
   } else {
       // Handle any other error codes.
   }
}

জাভা

@Override
void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
    if (billingResult.getResponseCode() == BillingResponseCode.OK
        && purchases != null) {
        for (Purchase purchase : purchases) {
            // Process the purchase as described in the next section.
        }
    } else if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
        // Handle an error caused by a user canceling the purchase flow.
    } else {
        // Handle any other error codes.
    }
}

একটি সফল ক্রয় চিত্র ২-এর মতো একটি গুগল প্লে ক্রয় সাফল্যের স্ক্রিন তৈরি করে।

গুগল প্লে-এর ক্রয় সাফল্যের স্ক্রিন
চিত্র ২। গুগল প্লে-এর ক্রয় সাফল্যের স্ক্রিন।

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

ব্যবহারকারীকে লেনদেনের একটি রসিদ ইমেল করা হয় যাতে একটি অর্ডার আইডি অথবা লেনদেনের একটি অনন্য আইডি থাকে। ব্যবহারকারীরা প্রতিটি এককালীন পণ্য ক্রয়ের জন্য এবং প্রাথমিক সাবস্ক্রিপশন ক্রয় এবং পরবর্তী পুনরাবৃত্ত স্বয়ংক্রিয় পুনর্নবীকরণের জন্য একটি অনন্য অর্ডার আইডি সহ একটি ইমেল পান। আপনি Google Play Console-এ রিফান্ড পরিচালনা করতে অর্ডার আইডি ব্যবহার করতে পারেন।

একটি ব্যক্তিগতকৃত মূল্য নির্দেশ করুন

যদি আপনার অ্যাপটি ইউরোপীয় ইউনিয়নের ব্যবহারকারীদের কাছে বিতরণ করা যায়, তাহলে launchBillingFlow কল করার সময় setIsOfferPersonalized() পদ্ধতি ব্যবহার করে ব্যবহারকারীদের কাছে প্রকাশ করুন যে কোনও আইটেমের দাম স্বয়ংক্রিয় সিদ্ধান্ত গ্রহণের মাধ্যমে ব্যক্তিগতকৃত করা হয়েছে।

গুগল প্লে ক্রয় স্ক্রিনটি নির্দেশ করে যে দামটি ব্যবহারকারীর জন্য কাস্টমাইজ করা হয়েছে।
চিত্র ৩। গুগল প্লে ক্রয় স্ক্রিনটি নির্দেশ করে যে মূল্যটি ব্যবহারকারীর জন্য কাস্টমাইজ করা হয়েছে।

ব্যবহারকারীদের জন্য আপনি যে মূল্য অফার করছেন তা ব্যক্তিগতকৃত কিনা তা নির্ধারণ করতে আপনাকে অবশ্যই ভোক্তা অধিকার নির্দেশিকা 2011/83/EU এর ধারা 6 (1) (ea) CRD দেখতে হবে।

setIsOfferPersonalized() একটি বুলিয়ান ইনপুট নেয়। যখন true , তখন Play UI-তে প্রকাশ অন্তর্ভুক্ত থাকে। যখন false , তখন UI প্রকাশ বাদ দেয়। ডিফল্ট মান হল false

আরও তথ্যের জন্য গ্রাহক সহায়তা কেন্দ্র দেখুন।

ব্যবহারকারী শনাক্তকারী সংযুক্ত করুন

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

কেনাকাটা সনাক্ত করুন এবং প্রক্রিয়া করুন

এই বিভাগে বর্ণিত কোনও ক্রয় সনাক্তকরণ এবং প্রক্রিয়াকরণ সকল ধরণের ক্রয়ের ক্ষেত্রে প্রযোজ্য, যার মধ্যে প্রচারের রিডিম্পশনের মতো অ্যাপের বাইরের ক্রয়ও অন্তর্ভুক্ত।

আপনার অ্যাপটি নিম্নলিখিত উপায়গুলির মধ্যে একটিতে নতুন কেনাকাটা এবং সম্পূর্ণ মুলতুবি কেনাকাটা সনাক্ত করে:

  1. যখন আপনার অ্যাপটি launchBillingFlow কল করার ফলে onPurchasesUpdated কল করা হয় (যেমনটি পূর্ববর্তী বিভাগে আলোচনা করা হয়েছে) অথবা যদি আপনার অ্যাপটি একটি সক্রিয় বিলিং লাইব্রেরি সংযোগের সাথে চলছে যখন আপনার অ্যাপের বাইরে কোনও কেনাকাটা করা হয় বা কোনও মুলতুবি কেনাকাটা সম্পন্ন হয়। উদাহরণস্বরূপ, পরিবারের একজন সদস্য অন্য ডিভাইসে একটি মুলতুবি কেনাকাটার অনুমোদন দেন।
  2. যখন আপনার অ্যাপ ব্যবহারকারীর কেনাকাটা সম্পর্কে জিজ্ঞাসা করার জন্য queryPurchasesAsync কল করে।

#1 এর জন্য, যদি আপনার অ্যাপটি চলমান থাকে এবং একটি সক্রিয় Google Play বিলিং লাইব্রেরি সংযোগ থাকে, তাহলে নতুন বা সম্পন্ন কেনাকাটার জন্য onPurchasesUpdated স্বয়ংক্রিয়ভাবে কল করা হবে। যদি আপনার অ্যাপ্লিকেশনটি চলমান না থাকে বা আপনার অ্যাপটিতে একটি সক্রিয় Google Play বিলিং লাইব্রেরি সংযোগ না থাকে, তাহলে onPurchasesUpdated আহ্বান করা হবে না। মনে রাখবেন, আপনার অ্যাপটি যতক্ষণ ফোরগ্রাউন্ডে থাকে ততক্ষণ একটি সক্রিয় সংযোগ রাখার চেষ্টা করার জন্য আপনার অ্যাপকে পরামর্শ দেওয়া হচ্ছে যাতে আপনার অ্যাপটি সময়মত ক্রয়ের আপডেট পায়।

#২ এর জন্য আপনাকে অবশ্যই BillingClient.queryPurchasesAsync() কল করতে হবে যাতে আপনার অ্যাপটি সমস্ত কেনাকাটা প্রক্রিয়া করে। যখন আপনার অ্যাপটি Google Play Billing Library এর সাথে সফলভাবে সংযোগ স্থাপন করে (যা আপনার অ্যাপটি চালু হওয়ার সময় বা BillingClient initialize এ আলোচনা করা হয়েছে তখন অগ্রভাগে আসার সময় সুপারিশ করা হয়) তখন এটি করার পরামর্শ দেওয়া হয়। onServiceConnected এ সফল ফলাফল পাওয়ার সময় queryPurchasesAsync কল করে এটি করা যেতে পারে। এই সুপারিশ অনুসরণ করা ইভেন্ট এবং পরিস্থিতি পরিচালনা করার জন্য অত্যন্ত গুরুত্বপূর্ণ যেমন:

  • ক্রয়ের সময় নেটওয়ার্ক সমস্যা : একজন ব্যবহারকারী সফলভাবে ক্রয় করতে পারেন এবং গুগল থেকে নিশ্চিতকরণ পেতে পারেন, কিন্তু তাদের ডিভাইসটি তাদের ডিভাইসের আগেই নেটওয়ার্ক সংযোগ বিচ্ছিন্ন করে এবং আপনার অ্যাপটি PurchasesUpdatedListener এর মাধ্যমে ক্রয়ের বিজ্ঞপ্তি পায়।
  • একাধিক ডিভাইস : একজন ব্যবহারকারী একটি ডিভাইসে একটি জিনিস কিনতে পারেন এবং তারপর ডিভাইস পরিবর্তন করার সময় জিনিসটি দেখতে আশা করতে পারেন।
  • আপনার অ্যাপের বাইরে করা কেনাকাটা পরিচালনা করা : কিছু কেনাকাটা, যেমন প্রচারের রিডিম্পশন, আপনার অ্যাপের বাইরেও করা যেতে পারে।
  • ক্রয়ের অবস্থা পরিবর্তন পরিচালনা করা : আপনার অ্যাপ্লিকেশনটি চলমান না থাকাকালীন একজন ব্যবহারকারী একটি মুলতুবি ক্রয়ের জন্য অর্থ প্রদান করতে পারেন এবং আপনার অ্যাপ্লিকেশনটি খোলার সময় তারা ক্রয় সম্পন্ন করেছেন বলে নিশ্চিতকরণ পাওয়ার আশা করেন।
  • সাসপেন্ডেড সাবস্ক্রিপশন : সাবস্ক্রিপশন লাইফসাইকেল চলাকালীন একটি সাবস্ক্রিপশন সাসপেন্ড হয়ে যেতে পারে। BillingClient.queryPurchasesAsync() শুধুমাত্র তখনই সাসপেন্ডেড সাবস্ক্রিপশন ফেরত দেবে যদি includeSuspendedSubscriptions প্যারামিটার QueryPurchasesParams.Builder এ সেট করা থাকে। PurchasesUpdatedListener এ সাসপেন্ডেড সাবস্ক্রিপশন ফেরত দেওয়া হয় না।

একবার আপনার অ্যাপটি একটি নতুন বা সম্পন্ন ক্রয় শনাক্ত করলে, আপনার অ্যাপের উচিত:

  • ক্রয়টি যাচাই করুন।
  • সম্পূর্ণ কেনাকাটার জন্য ব্যবহারকারীকে সামগ্রী প্রদান করুন।
  • ব্যবহারকারীকে অবহিত করুন।
  • আপনার অ্যাপটি সম্পন্ন কেনাকাটা প্রক্রিয়া করেছে বলে Google কে জানান।

এই ধাপগুলি সম্পর্কে পরবর্তী বিভাগগুলিতে বিস্তারিত আলোচনা করা হয়েছে, তারপরে সমস্ত ধাপের সংক্ষিপ্তসারের জন্য একটি বিভাগ রয়েছে।

ক্রয়টি যাচাই করুন

আপনার অ্যাপের উচিত সর্বদা ব্যবহারকারীকে সুবিধা প্রদানের আগে ক্রয়ের বৈধতা যাচাই করা। এনটাইটেলমেন্ট প্রদানের আগে ক্রয় যাচাই করুন -এ বর্ণিত নির্দেশিকা অনুসরণ করে এটি করা যেতে পারে। ক্রয় যাচাই করার পরেই আপনার অ্যাপটি ক্রয় প্রক্রিয়া চালিয়ে যেতে হবে এবং ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করতে হবে, যা পরবর্তী বিভাগে আলোচনা করা হয়েছে।

ব্যবহারকারীকে অধিকার প্রদান করুন

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

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

প্রি-অর্ডারের ক্ষেত্রে, রিলিজের সময় পৌঁছানোর আগে ক্রয়টি মুলতুবি অবস্থায় থাকে। প্রি-অর্ডার ক্রয়টি রিলিজের সময় সম্পন্ন হবে এবং অতিরিক্ত পদক্ষেপ ছাড়াই অবস্থাটি PURCHASED এ পরিবর্তিত হবে।

ব্যবহারকারীকে অবহিত করুন

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

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

ব্যবহারকারীকে কোনও ক্রয় সম্পর্কে অবহিত করার সময়, Google Play নিম্নলিখিত পদ্ধতিগুলি সুপারিশ করে:

  • একটি ইন-অ্যাপ ডায়ালগ দেখান।
  • অ্যাপ-মধ্যস্থ বার্তা বাক্সে বার্তাটি পৌঁছে দিন এবং স্পষ্টভাবে উল্লেখ করুন যে অ্যাপ-মধ্যস্থ বার্তা বাক্সে একটি নতুন বার্তা রয়েছে।
  • একটি OS বিজ্ঞপ্তি বার্তা ব্যবহার করুন।

বিজ্ঞপ্তিতে ব্যবহারকারীকে তাদের প্রাপ্ত সুবিধা সম্পর্কে অবহিত করা উচিত। উদাহরণস্বরূপ, "আপনি ১০০টি সোনার কয়েন কিনেছেন!"। এছাড়াও, যদি ক্রয়টি Play Pass এর মতো কোনও প্রোগ্রামের সুবিধার ফলে হয়ে থাকে তবে আপনার অ্যাপ ব্যবহারকারীকে এটি জানিয়ে দেবে। উদাহরণস্বরূপ, "আইটেমগুলি পেয়েছে! আপনি Play Pass দিয়ে মাত্র ১০০টি রত্ন পেয়েছেন। চালিয়ে যান।"। প্রতিটি প্রোগ্রামে ব্যবহারকারীদের সুবিধাগুলি জানানোর জন্য প্রস্তাবিত পাঠ্যের উপর নির্দেশিকা থাকতে পারে।

ক্রয় প্রক্রিয়া করা হয়েছে তা Google-কে জানান

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

ভোগ্যপণ্য

consumables এর ক্ষেত্রে, যদি আপনার অ্যাপের একটি নিরাপদ ব্যাকএন্ড থাকে, তাহলে আমরা আপনাকে Purchases.products:consume ব্যবহার করার পরামর্শ দিচ্ছি যাতে আপনি নির্ভরযোগ্যভাবে কেনাকাটা করতে পারেন। Purchases.products:get কল করার ফলাফল থেকে consumptionState পরীক্ষা করে নিশ্চিত করুন যে ক্রয়টি ইতিমধ্যেই consumed হয়নি। যদি আপনার অ্যাপটি ব্যাকএন্ড ছাড়াই ক্লায়েন্ট-অনলি হয়, তাহলে Google Play Billing Library থেকে consumeAsync() ব্যবহার করুন। উভয় পদ্ধতিই স্বীকৃতির প্রয়োজনীয়তা পূরণ করে এবং নির্দেশ করে যে আপনার অ্যাপ ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করেছে। এই পদ্ধতিগুলি আপনার অ্যাপকে পুনঃক্রয়ের জন্য ইনপুট ক্রয় টোকেনের সাথে সম্পর্কিত এককালীন পণ্য তৈরি করতে সক্ষম করে। consumeAsync() এর মাধ্যমে আপনাকে এমন একটি বস্তুও পাস করতে হবে যা ConsumeResponseListener ইন্টারফেস প্রয়োগ করে। এই বস্তু consume অপারেশনের ফলাফল পরিচালনা করে। আপনি onConsumeResponse() পদ্ধতিটি ওভাররাইড করতে পারেন, যা অপারেশন সম্পূর্ণ হলে Google Play Billing Library কল করে।

নিম্নলিখিত উদাহরণটি সংশ্লিষ্ট ক্রয় টোকেন ব্যবহার করে Google Play বিলিং লাইব্রেরির সাথে একটি পণ্য গ্রহণের চিত্র তুলে ধরে:

কোটলিন

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.getPurchaseToken())
            .build()
    val consumeResult = withContext(Dispatchers.IO) {
        client.consumePurchase(consumeParams)
    }

জাভা

    ConsumeParams consumeParams =
            ConsumeParams.newBuilder()
                .setPurchaseToken(purchase.getPurchaseToken())
                .build();

    ConsumeResponseListener listener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            if (billingResult.getResponseCode() == BillingResponseCode.OK) {
                // Handle the success of the consume operation.
            }
        }
    };

    billingClient.consumeAsync(consumeParams, listener);

অব্যবহার্য পণ্য

যদি আপনার অ্যাপের একটি নিরাপদ ব্যাকএন্ড থাকে, তাহলে অ-ব্যবহারযোগ্য ক্রয়গুলি স্বীকার করার জন্য আমরা Purchases.products:acknowledge ব্যবহার করার পরামর্শ দিচ্ছি যাতে নির্ভরযোগ্যভাবে ক্রয়গুলি স্বীকার করা যায়। Purchases.products:get কল করার ফলাফল থেকে acknowledgementState চেক করে নিশ্চিত করুন যে ক্রয়টি পূর্বে স্বীকৃতি দেওয়া হয়নি।

যদি আপনার অ্যাপটি শুধুমাত্র ক্লায়েন্ট-এর জন্য হয়, তাহলে আপনার অ্যাপে Google Play Billing Library থেকে BillingClient.acknowledgePurchase() ব্যবহার করুন। কোনও ক্রয় স্বীকার করার আগে, আপনার অ্যাপটি Google Play Billing Library থেকে isAcknowledged() পদ্ধতি ব্যবহার করে এটি ইতিমধ্যেই স্বীকার করেছে কিনা তা পরীক্ষা করে দেখা উচিত।

নিম্নলিখিত উদাহরণে Google Play বিলিং লাইব্রেরি ব্যবহার করে কীভাবে কোনও কেনাকাটা স্বীকার করতে হয় তা দেখানো হয়েছে:

কোটলিন

val client: BillingClient = ...
val acknowledgePurchaseResponseListener: AcknowledgePurchaseResponseListener = ...

val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder()
    .setPurchaseToken(purchase.purchaseToken)
val ackPurchaseResult = withContext(Dispatchers.IO) {
     client.acknowledgePurchase(acknowledgePurchaseParams.build())
}

জাভা

BillingClient client = ...
AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = ...

AcknowledgePurchaseParams acknowledgePurchaseParams =
                AcknowledgePurchaseParams.newBuilder()
                    .setPurchaseToken(purchase.getPurchaseToken())
                    .build();
 client.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

সাবস্ক্রিপশন

সাবস্ক্রিপশনগুলি অ-ব্যবহারযোগ্য জিনিসপত্রের মতোই পরিচালনা করা হয়। সম্ভব হলে, আপনার সুরক্ষিত ব্যাকএন্ড থেকে ক্রয়টি নির্ভরযোগ্যভাবে স্বীকার করতে Google Play Developer API থেকে Purchases.subscriptions.acknowledge ব্যবহার করুন। Purchases.subscriptions:get থেকে ক্রয় রিসোর্সে acknowledgementState চেক করে যাচাই করুন যে ক্রয়টি পূর্বে স্বীকার করা হয়নি। অন্যথায়, isAcknowledged() চেক করার পরে আপনি Google Play Billing Library থেকে BillingClient.acknowledgePurchase() ব্যবহার করে সাবস্ক্রিপশনটি স্বীকার করতে পারেন। সমস্ত প্রাথমিক সাবস্ক্রিপশন ক্রয় স্বীকার করতে হবে। সাবস্ক্রিপশন পুনর্নবীকরণ স্বীকার করতে হবে না। কখন সাবস্ক্রিপশন স্বীকার করতে হবে সে সম্পর্কে আরও তথ্যের জন্য, সাবস্ক্রিপশন বিক্রি করুন বিষয় দেখুন।

সংক্ষিপ্তসার

নিম্নলিখিত কোড স্নিপেট এই পদক্ষেপগুলির একটি সংক্ষিপ্তসার দেখায়।

কোটলিন

fun handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify
.
    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

জাভা

void handlePurchase(Purchase purchase) {
    // Purchase retrieved from BillingClient#queryPurchasesAsync or your
    // onPurchasesUpdated.
    Purchase purchase = ...;

    // Step 1: Send the purchase to your secure backend to verify the purchase
    // following
    // https://developer.android.com/google/play/billing/security#verify

    // Step 2: Update your entitlement storage with the purchase. If purchase is
    // in PENDING state then ensure the entitlement is marked as pending and the
    // user does not receive benefits yet. It is recommended that this step is
    // done on your secure backend and can combine in the API call to your
    // backend in step 1.

    // Step 3: Notify the user using appropriate messaging (delaying
    // notification if needed as discussed above).

    // Step 4: Notify Google the purchase was processed using the steps
    // discussed in the processing purchases section.
}

আপনার অ্যাপটি এই পদক্ষেপগুলি সঠিকভাবে বাস্তবায়ন করেছে কিনা তা যাচাই করতে আপনি পরীক্ষার নির্দেশিকা অনুসরণ করতে পারেন।

মুলতুবি লেনদেন পরিচালনা করুন

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

উদাহরণস্বরূপ, একজন ব্যবহারকারী একটি ভৌত ​​দোকান বেছে নিয়ে লেনদেন শুরু করতে পারেন যেখানে তারা পরে নগদ অর্থ প্রদান করবেন। ব্যবহারকারী বিজ্ঞপ্তি এবং ইমেল উভয়ের মাধ্যমেই একটি কোড পাবেন। ব্যবহারকারী যখন ভৌত দোকানে পৌঁছাবেন, তখন তারা ক্যাশিয়ারের সাথে কোডটি রিডিম করতে পারবেন এবং নগদ অর্থ প্রদান করতে পারবেন। এরপর গুগল আপনাকে এবং ব্যবহারকারী উভয়কেই অবহিত করবে যে পেমেন্ট গৃহীত হয়েছে। আপনার অ্যাপটি তখন ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করতে পারে।

আপনার অ্যাপের জন্য মুলতুবি লেনদেন সক্ষম করতে BillingClient শুরু করার অংশ হিসেবে enablePendingPurchases() কল করুন। আপনার অ্যাপটিকে এককালীন পণ্যের জন্য মুলতুবি লেনদেন সক্ষম এবং সমর্থন করতে হবে। সহায়তা যোগ করার আগে, নিশ্চিত করুন যে আপনি মুলতুবি লেনদেনের জন্য ক্রয় জীবনচক্রটি বুঝতে পেরেছেন।

যখন আপনার অ্যাপটি আপনার PurchasesUpdatedListener মাধ্যমে অথবা queryPurchasesAsync কল করার ফলে একটি নতুন ক্রয় পায়, তখন getPurchaseState() পদ্ধতি ব্যবহার করে ক্রয়ের অবস্থা PURCHASED নাকি PENDING নির্ধারণ করুন। যখন অবস্থা PURCHASED থাকে তখনই আপনার এনটাইটেলমেন্ট প্রদান করা উচিত।

যদি আপনার অ্যাপটি চলমান থাকে এবং ব্যবহারকারী যখন ক্রয়টি সম্পন্ন করে তখন আপনার একটি সক্রিয় Play Billing Library সংযোগ থাকে, তাহলে আপনার PurchasesUpdatedListener আবার কল করা হবে এবং PurchaseState এখন PURCHASED । এই মুহুর্তে, আপনার অ্যাপটি Purchases সনাক্তকরণ এবং প্রক্রিয়াকরণের জন্য স্ট্যান্ডার্ড পদ্ধতি ব্যবহার করে ক্রয় প্রক্রিয়া করতে পারে। আপনার অ্যাপটি চলমান না থাকাকালীন PURCHASED অবস্থায় স্থানান্তরিত কেনাকাটা পরিচালনা করার জন্য আপনার অ্যাপের onResume() পদ্ধতিতে queryPurchasesAsync() কল করা উচিত।

যখন ক্রয়টি PENDING থেকে PURCHASED এ রূপান্তরিত হয়, তখন আপনার real_time_developer_notifications ক্লায়েন্ট একটি ONE_TIME_PRODUCT_PURCHASED বা SUBSCRIPTION_PURCHASED বিজ্ঞপ্তি পাবে। যদি ক্রয়টি বাতিল করা হয়, তাহলে আপনি একটি ONE_TIME_PRODUCT_CANCELED বা SUBSCRIPTION_PENDING_PURCHASE_CANCELED বিজ্ঞপ্তি পাবেন। আপনার গ্রাহক যদি প্রয়োজনীয় সময়সীমার মধ্যে অর্থ প্রদান সম্পূর্ণ না করেন তবে এটি ঘটতে পারে। মনে রাখবেন যে আপনি ক্রয়ের বর্তমান অবস্থা পরীক্ষা করতে সর্বদা Google Play ডেভেলপার API ব্যবহার করতে পারেন।

বহু-পরিমাণে কেনাকাটা পরিচালনা করুন

গুগল প্লে বিলিং লাইব্রেরির ৪.০ এবং উচ্চতর সংস্করণে সমর্থিত, গুগল প্লে গ্রাহকদের ক্রয় কার্ট থেকে একটি পরিমাণ নির্দিষ্ট করে একই লেনদেনে একাধিক একই পণ্য কেনার সুযোগ দেয়। আপনার অ্যাপটি বহু-পরিমাণ ক্রয় পরিচালনা করবে এবং নির্দিষ্ট ক্রয়ের পরিমাণের উপর ভিত্তি করে এনটাইটেলমেন্ট প্রদান করবে বলে আশা করা হচ্ছে।

বহু-পরিমাণ ক্রয়কে সম্মান জানাতে, আপনার অ্যাপের প্রভিশনিং লজিককে একটি আইটেমের পরিমাণ পরীক্ষা করতে হবে। আপনি নিম্নলিখিত API গুলির মধ্যে একটি থেকে একটি quantity ক্ষেত্র অ্যাক্সেস করতে পারেন:

একাধিক পরিমাণের কেনাকাটা পরিচালনা করার জন্য যুক্তি যোগ করার পরে, আপনাকে Google Play Developer Console-এর এককালীন পণ্য ব্যবস্থাপনা পৃষ্ঠায় সংশ্লিষ্ট পণ্যের জন্য বহু-পরিমাণ বৈশিষ্ট্যটি সক্ষম করতে হবে।

ব্যবহারকারীর বিলিং কনফিগারেশন সম্পর্কে জিজ্ঞাসা করুন

getBillingConfigAsync() ব্যবহারকারী Google Play এর জন্য যে দেশটি ব্যবহার করেন তা প্রদান করে।

BillingClient তৈরি করার পর আপনি ব্যবহারকারীর বিলিং কনফিগারেশন জিজ্ঞাসা করতে পারেন। নিম্নলিখিত কোড স্নিপেটটি getBillingConfigAsync() এ কীভাবে কল করবেন তা বর্ণনা করে। BillingConfigResponseListener প্রয়োগ করে প্রতিক্রিয়া পরিচালনা করুন। এই শ্রোতা আপনার অ্যাপ থেকে শুরু করা সমস্ত বিলিং কনফিগারেশন প্রশ্নের আপডেট পান।

যদি ফেরত দেওয়া BillingResult কোনও ত্রুটি না থাকে, তাহলে আপনি ব্যবহারকারীর Play Country পেতে BillingConfig অবজেক্টের countryCode ফিল্ডটি পরীক্ষা করতে পারেন।

কোটলিন

// Use the default GetBillingConfigParams.
val getBillingConfigParams = GetBillingConfigParams.newBuilder().build()
billingClient.getBillingConfigAsync(getBillingConfigParams,
    object : BillingConfigResponseListener {
        override fun onBillingConfigResponse(
            billingResult: BillingResult,
            billingConfig: BillingConfig?
        ) {
            if (billingResult.responseCode == BillingResponseCode.OK
                && billingConfig != null) {
                val countryCode = billingConfig.countryCode
                ...
            } else {
                // TODO: Handle errors
            }
        }
    })

জাভা

// Use the default GetBillingConfigParams.
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build();
billingClient.getBillingConfigAsync(getBillingConfigParams,
    new BillingConfigResponseListener() {
      public void onBillingConfigResponse(
          BillingResult billingResult, BillingConfig billingConfig) {
        if (billingResult.getResponseCode() == BillingResponseCode.OK
            && billingConfig != null) {
            String countryCode = billingConfig.getCountryCode();
            ...
         } else {
            // TODO: Handle errors
        }
      }
    });

গুগল প্লে গেমস হোমে কার্ট পরিত্যক্তকরণের অনুস্মারক (ডিফল্টরূপে সক্ষম)

For Games developers that monetize through one-time products, one way in which stock-keeping units (SKUs) that are active in Google Play Console can be sold outside of your app is the Cart Abandonment Reminder feature, which nudges users to complete their previously abandoned purchases while browsing the Google Play Store. These purchases happen outside of your app, from the Google Play Games home in the Google Play Store.

This feature is enabled by default to help users pick up where they left off and to help developers maximize sales. However, you can opt your app out of this feature by submitting the Cart Abandonment Reminder feature opt-out form . For best practices on managing SKUs within the Google Play Console, see Create an in-app product .

The following images show the Cart Abandonment Reminder appearing on the Google Play Store:

the Google Play Store screen shows a
    purchase prompt for a previously abandoned purchase
Figure 2. The Google Play Store screen shows a purchase prompt for a previously abandoned purchase.

the Google Play Store screen shows a
    purchase prompt for a previously abandoned purchase
Figure 3. The Google Play Store screen shows a purchase prompt for a previously abandoned purchase.