এই ডকুমেন্ট থেকে জানতে পারবেন যে প্রোডাক্ট বিক্রি শুরু করার জন্য কীভাবে আপনার অ্যাপে Google Play Billing Library ইন্টিগ্রেট করবেন।
কেনাকাটার মেয়াদ
এককালীন কেনাকাটা বা সাবস্ক্রিপশনের জন্য এখানে একটি সাধারণ পারচেজ ফ্লো দেওয়া হল।
- ব্যবহারকারী কী কিনতে পারবেন তা দেখান।
- ব্যবহারকারী যাতে কেনাকাটা করতে পারেন তার জন্য পারচেজ ফ্লো চালু করুন।
- আপনার সার্ভারে কেনাকাটা যাচাই করুন।
- ব্যবহারকারীকে কন্টেন্ট দিন।
- কন্টেন্ট ডেলিভারি স্বীকার করুন। ব্যবহারযোগ্য প্রোডাক্টের ক্ষেত্রে, কেনাকাটা ব্যবহার করুন যাতে ব্যবহারকারী আইটেমটি আবার কিনতে পারেন।
সাবস্ক্রিপশন বাতিল না করা পর্যন্ত অটোমেটিক রিনিউ হয়। সাবস্ক্রিপশন নিম্নলিখিত অবস্থায় থাকতে পারে:
- অ্যাক্টিভ: ব্যবহারকারীর অ্যাকাউন্ট ভাল অবস্থানে আছে এবং সাবস্ক্রিপশনে অ্যাক্সেস আছে।
- বাতিল করা হয়েছে: ব্যবহারকারী বাতিল করেছেন কিন্তু মেয়াদ শেষ না হওয়া পর্যন্ত অ্যাক্সেস করতে পারবেন।
- অতিরিক্ত সময়কালে: ব্যবহারকারী পেমেন্ট সংক্রান্ত সমস্যার সম্মুখীন হয়েছেন, তবে Google পেমেন্ট পদ্ধতি আবার চেষ্টা করার সময়ও অ্যাক্সেস আছে।
- হোল্ডে আছে: ব্যবহারকারীর পেমেন্ট সংক্রান্ত সমস্যা হয়েছে এবং Google পেমেন্ট পদ্ধতি আবার চেষ্টা করার সময় তার আর অ্যাক্সেস নেই।
- পজ করা হয়েছে: ব্যবহারকারী তার অ্যাক্সেস পজ করেছেন এবং তিনি আবার চালু না করা পর্যন্ত অ্যাক্সেস করতে পারবেন না।
- মেয়াদ শেষ হয়ে গেছে: ব্যবহারকারী সাবস্ক্রিপশন বাতিল করেছেন এবং অ্যাক্সেস হারিয়েছেন। মেয়াদ শেষ হওয়ার পরে ব্যবহারকারীকে ছেড়ে চলে গেছেন হিসেবে বিবেচনা করা হয়।
Google Play-তে কানেকশন শুরু করুন
Google Play-এর বিলিং সিস্টেমের সাথে ইন্টিগ্রেট করার প্রথম ধাপ হল আপনার অ্যাপে Google Play Billing Library যোগ করা এবং কানেকশন শুরু করা।
Google Play Billing Library ডিপেন্ডেন্সি যোগ করুন
আপনার অ্যাপের build.gradle
ফাইলে Google Play Billing Library ডিপেন্ডেন্সি যোগ করুন, যেমন দেখানো হয়েছে:
গ্ৰুভি
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing:$billing_version" }
Kotlin
dependencies { val billing_version = "9.1.0" implementation("com.android.billingclient:billing:$billing_version") }
আপনি Kotlin ব্যবহার করলে, Google Play Billing Library KTX মডিউলে
Kotlin এক্সটেনশন ও কোরুটিন সাপোর্ট থাকে যা আপনাকে Google Play Billing Library ব্যবহার করার সময়
ইডিওমেটিক Kotlin লিখতে সাহায্য করে। আপনার প্রোজেক্টে এইসব এক্সটেনশন অন্তর্ভুক্ত করতে,
আপনার অ্যাপের build.gradle ফাইলে নিম্নলিখিত ডিপেন্ডেন্সি যোগ করুন,
যেমন দেখানো হয়েছে:
গ্ৰুভি
dependencies { def billing_version = "9.1.0" implementation "com.android.billingclient:billing-ktx:$billing_version" }
Kotlin
dependencies { val billing_version = "9.1.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
BillingClient শুরু করা
Google Play Billing Library-তে ডিপেন্ডেন্সি যোগ করার পরে, আপনাকে
BillingClient ইনস্ট্যান্স শুরু করতে হবে। Google Play Billing Library এবং আপনার অ্যাপের বাকি অংশের মধ্যে যোগাযোগের জন্য BillingClient হল প্রধান ইন্টারফেস। BillingClient অনেক সাধারণ বিলিং অপারেশনের জন্য সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস, উভয় সুবিধাজনক পদ্ধতি প্রদান করে। নিম্নলিখিত বিষয়গুলি
মনে রাখবেন:
- একই ইভেন্টের জন্য একাধিক
PurchasesUpdatedListenerকলব্যাক এড়াতে, একই সময়ে একটি অ্যাক্টিভBillingClientকানেকশন খুলে রাখার সাজেশন দেওয়া হয়। - আপনার অ্যাপ যাতে সময়মতো কেনাকাটা প্রসেস করতে পারে তা নিশ্চিত করতে, অ্যাপ চালু হলে বা ফোরগ্রাউন্ডে এলে BillingClient-এর জন্য কানেকশন শুরু করার সাজেশন দেওয়া হয়। এটি করতে হলে,
registerActivityLifecycleCallbacks-এর মাধ্যমে রেজিস্টার করাActivityLifecycleCallbacksব্যবহার করতে হবে এবং আপনি প্রথমবার কোনও অ্যাক্টিভিটি আবার শুরু হতে দেখলে, কানেকশন শুরু করার জন্য onActivityResumed-এর জন্য অপেক্ষা করতে হবে। এই পেশাদার পদ্ধতি কেন অনুসরণ করা উচিত সেই সম্পর্কে আরও জানতে কেনাকাটা প্রসেস করা বিভাগটি দেখুন। এছাড়াও, আপনার অ্যাপ বন্ধ হয়ে গেলে কানেকশন বন্ধ করতে ভুলবেন না।
BillingClient তৈরি করতে, newBuilder ব্যবহার করুন। আপনি যেকোনও কন্টেক্সট
newBuilder()-এ পাস করতে পারেন এবং BillingClient এটি ব্যবহার করে অ্যাপ্লিকেশন কন্টেক্সট পায়। এর অর্থ
হল, মেমরি লিক নিয়ে আপনাকে চিন্তা করতে হবে না। কেনাকাটার ব্যাপারে আপডেট পেতে, আপনাকে অবশ্যই setListener কল করতে হবে, PurchasesUpdatedListener-এ
রেফারেন্স পাস করতে হবে। এই লিসেনার আপনার অ্যাপে করা সব কেনাকাটার
আপডেট পায়।
Kotlin
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();
Google Play-তে কানেক্ট করুন
BillingClient তৈরি করার পরে, আপনাকে Google Play-এর সাথে
কানেকশন তৈরি করতে হবে।
Google Play-তে কানেক্ট করতে, startConnection নম্বরে কল করুন। কানেকশন প্রসেস
অ্যাসিঙ্ক্রোনাস এবং ক্লায়েন্টের সেট-আপ সম্পূর্ণ হলে এবং আরও অনুরোধ করার জন্য
এটি রেডি হলে কলব্যাক পাওয়ার জন্য
আপনাকে অবশ্যই BillingClientStateListener প্রয়োগ করতে হবে।
আপনি অটোমেটিক পরিষেবা রিকানেকশন চালু না করে থাকলে, Google Play-এর সাথে কানেকশন বিচ্ছিন্ন হয়ে গেলে
তা সামলানোর জন্য আপনাকে রিট্রাই লজিকও প্রয়োগ করতে হবে। আবার চেষ্টা করার লজিক প্রয়োগ করতে,
onBillingServiceDisconnected() কলব্যাক পদ্ধতি ওভাররাইড করুন এবং
নিশ্চিত করুন যে BillingClient, startConnection() পদ্ধতিকে কল করে
যাতে আরও অনুরোধ করার আগে Google Play-তে আবার কানেক্ট করা যায়। আপনি যদি
অটোমেটিক পরিষেবা রিকানেকশন চালু করে থাকেন, তাহলে আপনি এই পদ্ধতিটি নো-অপ হিসেবে প্রয়োগ করতে পারেন।
নিচের উদাহরণে দেখানো হয়েছে কীভাবে কানেকশন শুরু করতে হয় এবং এটি ব্যবহারের জন্য প্রস্তুত কিনা তা পরীক্ষা করতে হয়:
Kotlin
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() { // If automatic service reconnection is enabled, this can be left empty (no-op) // because the library handles retries. You can still use this for non-retry // tasks like logging or updating the UI to reflect a disconnected state. // Otherwise, 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. // It's a good practice to query products after the connection is established. queryProductDetails(); } } @Override public void onBillingServiceDisconnected() { // Try to restart the connection on the next request to // Google Play by calling the startConnection() method. // This is automatically handled by the library when you call a method that requires a connection. } });
অটোমেটিক কানেকশন আবার তৈরি করা
8.0.0 ভার্সনে BillingClient.Builder-এ enableAutoServiceReconnection() পদ্ধতি চালু করার মাধ্যমে,
পরিষেবা ডিসকানেক্ট হয়ে যাওয়ার পরে API কল করা হলে, Play Billing Library এখন
অটোমেটিক পরিষেবা কানেকশন আবার স্থাপন করতে পারে। এর ফলে
SERVICE_DISCONNECTED রেসপন্স কমে যেতে পারে কারণ API কল করার আগে
অভ্যন্তরীণভাবে রিকানেকশন ম্যানেজ করা হয়।
অটোমেটিক রিকানেকশন কীভাবে চালু করবেন
BillingClient ইনস্ট্যান্স তৈরি করার সময়, অটোমেটিক রিকানেকশন চালু করতে
BillingClient.Builder-এ enableAutoServiceReconnection() পদ্ধতি
ব্যবহার করুন।
Kotlin
val billingClient = BillingClient.newBuilder(context) .setListener(listener) .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()) .enableAutoServiceReconnection() // Add this line to enable reconnection .build()
জাভা
BillingClient billingClient = BillingClient.newBuilder(context)
.setListener(listener)
.enablePendingPurchases()
.enableAutoServiceReconnection() // Add this line to enable reconnection
.build();
কেনার জন্য উপলভ্য প্রোডাক্ট দেখুন
Google Play-এর সাথে কানেকশন তৈরি করার পরে, আপনি উপলভ্য প্রোডাক্টের জন্য কোয়েরি করতে এবং ব্যবহারকারীদের তা দেখাতে পারবেন।
ব্যবহারকারীদের প্রোডাক্ট দেখানোর আগে প্রোডাক্টের বিবরণ সম্পর্কে কোয়েরি করা একটি গুরুত্বপূর্ণ ধাপ, কারণ এটি প্রোডাক্টের স্থানীয় তথ্য প্রদান করে। সাবস্ক্রিপশনের জন্য, আপনার প্রোডাক্ট ডিসপ্লে সব Play নীতি মেনে চলছে কিনা তা যাচাই করুন।
এককালীন প্রোডাক্টের বিবরণ সম্পর্কে কোয়েরি করতে, queryProductDetailsAsync
মেথড কল করুন। আপনার এককালীন প্রোডাক্ট কনফিগারেশনের উপর ভিত্তি করে এই পদ্ধতি একাধিক অফার দেখাতে পারে। আরও তথ্যের জন্য, এককালীন প্রোডাক্টের জন্য একাধিক কেনাকাটার বিকল্প
ও অফার দেখুন।
অ্যাসিঙ্ক্রোনাস অপারেশনের ফলাফল ম্যানেজ করতে, আপনাকে অবশ্যই একটি লিসেনার নির্দিষ্ট করতে হবে যা ProductDetailsResponseListener ইন্টারফেস প্রয়োগ করে।
তারপর আপনি onProductDetailsResponse ওভাররাইড করতে পারবেন, যা কোয়েরি শেষ হলে
লিসেনারকে বিজ্ঞপ্তি পাঠায়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
Kotlin
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder() .setProductList( listOf( Product.newBuilder() .setProductId("product_id_example") .setProductType(ProductType.SUBS) .build() ) ) .build() billingClient.queryProductDetailsAsync(queryProductDetailsParams) { billingResult, queryProductDetailsResult -> if (billingResult.responseCode == BillingResponseCode.OK) { for (productDetails in queryProductDetailsResult.productDetailsList) { // Process successfully retrieved product details here. } for (unfetchedProduct in queryProductDetailsResult.unfetchedProductList) { // 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 successfully 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 এক্সটেনশন সহ কোয়েরি
আপনি Kotlin এক্সটেনশন ব্যবহার করলে, queryProductDetails() এক্সটেনশন ফাংশন কল করে এককালীন প্রোডাক্টের
বিবরণ কোয়েরি করতে পারবেন।
queryProductDetails() Kotlin coroutines ব্যবহার করে যাতে আপনাকে আলাদা লিসেনার
সংজ্ঞায়িত করতে না হয়। পরিবর্তে, কোয়েরি সম্পূর্ণ না হওয়া পর্যন্ত ফাংশনটি সাসপেন্ড হয়ে যায়, যার পরে আপনি ফলাফল প্রসেস করতে পারবেন:
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
পরিষেবা-এর পুরনো ভার্সন ব্যবহার করার কারণে এমন হয়। এই পরিস্থিতিতে যথাযথ সহায়তা প্রদান করতে, Play Billing Library 7 মাইগ্রেশন
গাইড থেকে ব্যাকওয়ার্ড কম্প্যাটিবিলিটি ফিচার কীভাবে ব্যবহার করতে হয় তা জানুন।
ফলাফল প্রসেস করুন
Google Play Billing Library, কোয়েরির ফলাফল
QueryProductDetailsResult অবজেক্টে স্টোর করে। QueryProductDetailsResult
এতে ProductDetails অবজেক্টের List রয়েছে। তারপর, আপনি তালিকার প্রতিটি ProductDetails অবজেক্টে বিভিন্ন ধরনের মেথড কল করতে পারেন, যাতে সফলভাবে ফেচ করা এককালীন প্রোডাক্টের প্রাসঙ্গিক তথ্য দেখতে পারেন, যেমন এর দাম বা বিবরণ। উপলভ্য প্রোডাক্টের বিস্তারিত তথ্য দেখতে,
ProductDetails ক্লাসে পদ্ধতির তালিকা দেখুন।
QueryProductDetailsResult-এ UnfetchedProduct অবজেক্টের
List-ও রয়েছে। তারপর আপনি প্রতিটি UnfetchedProduct কোয়েরি করতে পারেন
যাতে ফেচ করতে না পারার কারণের সাথে সম্পর্কিত স্ট্যাটাস কোড পাওয়া যায়।
উপলভ্য আনফেচ করা প্রোডাক্টের তথ্য দেখতে,
UnfetchedProduct ক্লাসে পদ্ধতির তালিকা দেখুন।
বিক্রির জন্য কোনও আইটেম অফার করার আগে, ব্যবহারকারীর কাছে আগে থেকেই সেই আইটেমটি আছে কিনা তা চেক করুন। ব্যবহারকারীর আইটেম লাইব্রেরিতে এখনও কোনও ব্যবহারযোগ্য আইটেম থাকলে, সেটি আবার কেনার আগে তাকে অবশ্যই আইটেমটি ব্যবহার করে ফেলতে হবে।
সাবস্ক্রিপশন অফার করার আগে, ব্যবহারকারী আগে থেকেই সাবস্ক্রাইব করেছেন কিনা তা যাচাই করুন। এছাড়াও, নিম্নলিখিত বিষয়গুলি মনে রাখবেন:
সাবস্ক্রিপশনের জন্য,
queryProductDetailsAsync()পদ্ধতি সাবস্ক্রিপশন প্রোডাক্টের বিবরণ এবং সাবস্ক্রিপশন প্রতি সর্বাধিক ৫০টি ব্যবহারকারীর জন্য উপযুক্ত অফার রিটার্ন করে। ব্যবহারকারী যদি কোনও অনুপযুক্ত অফার কেনার চেষ্টা করেন (যেমন, অ্যাপটি যদি উপযুক্ত অফারের একটি পুরনো তালিকা দেখায়), তাহলে Play ব্যবহারকারীকে জানায় যে তিনি অনুপযুক্ত এবং ব্যবহারকারী এর পরিবর্তে বেস প্ল্যান কেনার বিকল্প বেছে নিতে পারেন।এককালীন প্রোডাক্টের ক্ষেত্রে,
queryProductDetailsAsync()পদ্ধতি শুধুমাত্র ব্যবহারকারীর জন্য উপযুক্ত অফার রিটার্ন করে। ব্যবহারকারী যদি এমন কোনও অফার কেনার চেষ্টা করেন যার জন্য তিনি উপযুক্ত নন (যেমন, ব্যবহারকারী যদি কেনাকাটার পরিমাণের সীমায় পৌঁছে যান), তাহলে Play ব্যবহারকারীকে জানায় যে তিনি উপযুক্ত নন এবং ব্যবহারকারী এর পরিবর্তে তার কেনাকাটার বিকল্প অফার কেনার জন্য বেছে নিতে পারেন।
পারচেজ ফ্লো চালু করুন
আপনার অ্যাপ থেকে কেনাকাটার অনুরোধ শুরু করতে, অ্যাপের মূল থ্রেড থেকে launchBillingFlow()
মেথড কল করুন। এই পদ্ধতিটি একটি
BillingFlowParams অবজেক্টের রেফারেন্স নেয় যাতে প্রাসঙ্গিক
ProductDetails অবজেক্ট থাকে যা
queryProductDetailsAsync কল করার মাধ্যমে পাওয়া যায়। BillingFlowParams অবজেক্ট তৈরি করতে,
BillingFlowParams.Builder ক্লাস ব্যবহার করুন।
Kotlin
// 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.getSubscriptionOfferDetails() // 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<BillingFlowParams.ProductDetailsParams> productDetailsParamsList = ImmutableList.of( 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.getSubscriptionOfferDetails() // 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-এর কেনাকাটার স্ক্রিন দেখায়। ছবি ১-এ সাবস্ক্রিপশন কেনার স্ক্রিন দেখানো হয়েছে:
Google Play onPurchasesUpdated()-কে কল করে যাতে PurchasesUpdatedListener ইন্টারফেস প্রয়োগ করে এমন কোনও লিসনারকে কেনাকাটার
অপারেশনের ফলাফল ডেলিভার করা যায়। আপনি ক্লায়েন্ট শুরু করার সময় setListener() পদ্ধতি ব্যবহার করে লিসেনার নির্দিষ্ট করা হয়।
সম্ভাব্য রেসপন্স কোড ম্যানেজ করতে আপনাকে অবশ্যই onPurchasesUpdated() প্রয়োগ করতে হবে। নিম্নলিখিত
উদাহরণ থেকে onPurchasesUpdated() কীভাবে ওভাররাইড করতে হয় তা দেখানো হয়েছে:
Kotlin
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-তে কেনাকাটা সম্পূর্ণ হওয়ার স্ক্রিন দেখানো হয়, যা ছবি ২-এর মতো দেখতে হয়।
কেনাকাটা সম্পূর্ণ হলে একটি পারচেজ টোকেনও জেনারেট হয়, যা হল একটি অনন্য শনাক্তকারী। এটি ব্যবহারকারী এবং তার কেনা এককালীন প্রোডাক্টের প্রোডাক্ট আইডি প্রতিনিধিত্ব করে। আপনার অ্যাপ স্থানীয়ভাবে পারচেজ টোকেন স্টোর করতে পারে, তবে আমরা আপনার সুরক্ষিত ব্যাকএন্ড সার্ভারে টোকেন পাস করার জন্য জোরদার সাজেশন দিই, যেখানে আপনি তারপর কেনাকাটা যাচাই করতে এবং প্রতারণার বিরুদ্ধে সুরক্ষা দিতে পারবেন। এই প্রসেসটি কেনাকাটা শনাক্ত ও প্রসেস করা লিঙ্কে আরও বিশদে বর্ণনা করা হয়েছে।
এছাড়াও, ব্যবহারকারীকে ট্রানজ্যাকশনের রসিদ ইমেল করা হয়, যাতে অর্ডার আইডি বা ট্রানজ্যাকশনের অনন্য আইডি থাকে। প্রতিটি এককালীন প্রোডাক্ট কেনাকাটার জন্য, এছাড়াও প্রাথমিক সাবস্ক্রিপশন কেনাকাটা এবং পরবর্তী রেকারিং অটোমেটিক রিনিউয়ালের জন্য ব্যবহারকারীরা অনন্য অর্ডার আইডি সহ একটি ইমেল পান। Google Play Console-এ রিফান্ড ম্যানেজ করতে আপনি অর্ডার আইডি ব্যবহার করতে পারবেন।
পছন্দমতো দাম উল্লেখ করুন
আপনার অ্যাপ ইউরোপীয় ইউনিয়নের ব্যবহারকারীদের মধ্যে ডিস্ট্রিবিউট করা গেলে, launchBillingFlow কল করার সময়
setIsOfferPersonalized() পদ্ধতি ব্যবহার করুন যাতে ব্যবহারকারীদের কাছে প্রকাশ করা যায় যে
অটোমেটিক সিদ্ধান্ত গ্রহণের মাধ্যমে কোনও আইটেমের দাম পছন্দমতো সেট করা হয়েছে।
আপনাকে অবশ্যই আর্ট. দেখতে হবে। গ্রাহকের অধিকার সংক্রান্ত নির্দেশিকার 6 (1) (ea) CRD 2011/83/EU অনুযায়ী, আপনি ব্যবহারকারীদের যে দাম অফার করছেন তা পছন্দমতো কিনা তা নির্ধারণ করতে।
setIsOfferPersonalized()-এ বুলিয়ান ইনপুট দিতে হয়। true হলে, Play UI-তে
ডিসক্লোজার অন্তর্ভুক্ত থাকে। false হলে, UI ডিসক্লোজার বাদ দেয়। ডিফল্ট
ভ্যালু হল false।
আরও তথ্যের জন্য গ্রাহক সহায়তা কেন্দ্র দেখুন।
ইউজার আইডেন্টিফায়ার অ্যাটাচ করা
আপনি পারচেজ ফ্লো চালু করলে, আপনার অ্যাপ obfuscatedAccountId বা obfuscatedProfileId ব্যবহার করে কেনাকাটা করা ব্যবহারকারীর জন্য আপনার কাছে থাকা যেকোনও ইউজার আইডেন্টিফায়ার অ্যাটাচ করতে পারে। উদাহরণস্বরূপ, আপনার সিস্টেমে ব্যবহারকারীর লগ-ইনের অস্পষ্ট ভার্সন শনাক্তকারী হতে পারে। এইসব প্যারামিটার সেট করলে Google-এর পক্ষে প্রতারণা শনাক্ত করা সহজ হয়। এছাড়াও, এটি আপনাকে নিশ্চিত করতে সাহায্য করতে পারে যে কেনাকাটাগুলি সঠিক ব্যবহারকারীর সাথে অ্যাট্রিবিউট করা হয়েছে, যেমন ব্যবহারকারীদের এনটাইটেলমেন্ট প্রদান করা-তে আলোচনা করা হয়েছে।
কেনাকাটা শনাক্ত ও প্রসেস করা
এই বিভাগে বর্ণিত কেনাকাটা শনাক্তকরণ ও প্রসেস করার পদ্ধতি সব ধরনের কেনাকাটার ক্ষেত্রে প্রযোজ্য, যার মধ্যে প্রোমোশন রিডিম করার মতো অ্যাপ-বহিস্থ কেনাকাটাও অন্তর্ভুক্ত।
আপনার অ্যাপ নতুন কেনাকাটা শনাক্ত করে এবং নিম্নলিখিত উপায়ে বাকি থাকা কেনাকাটা সম্পূর্ণ করে:
- আপনার অ্যাপ
launchBillingFlowকল করার ফলে যখনonPurchasesUpdatedকল করা হয় (আগের বিভাগে যেমন আলোচনা করা হয়েছে) অথবা আপনার অ্যাপের বাইরে কোনও কেনাকাটা করা হলে বা কোনও বাকি থাকা কেনাকাটা সম্পূর্ণ হলে, আপনার অ্যাপ যদি অ্যাক্টিভ Billing Library কানেকশন সহ চালানো হয়। যেমন, পরিবারের কোনও সদস্য অন্য ডিভাইসে বাকি থাকা কেনাকাটার অনুমোদন করেন। - ব্যবহারকারীর কেনাকাটা সম্পর্কে কোয়েরি করার জন্য আপনার অ্যাপ queryPurchasesAsync কল করলে।
#১-এর জন্য, আপনার অ্যাপ যতক্ষণ চলছে এবং Google Play Billing Library-এর সাথে কানেকশন অ্যাক্টিভ আছে, ততক্ষণ নতুন বা সম্পূর্ণ হওয়া কেনাকাটার জন্য onPurchasesUpdated অটোমেটিক কল করা হবে। আপনার অ্যাপ্লিকেশন না চললে বা আপনার অ্যাপে অ্যাক্টিভ Google Play Billing Library কানেকশন না থাকলে, onPurchasesUpdated
ইনভোক করা হবে না। মনে রাখবেন, আপনার অ্যাপ যতক্ষণ ফোরগ্রাউন্ডে থাকবে ততক্ষণ একটি অ্যাক্টিভ কানেকশন
রাখার চেষ্টা করার জন্য আপনার অ্যাপের জন্য এটি সাজেস্ট করা হয় যাতে আপনার অ্যাপ সময়মতো
কেনাকাটার আপডেট পায়।
#২-এর জন্য আপনার অ্যাপ যাতে সব কেনাকাটা প্রসেস করে তা নিশ্চিত করতে আপনাকে অবশ্যই BillingClient.queryPurchasesAsync() কল করতে হবে। আপনার অ্যাপ Google Play Billing Library-এর সাথে কানেকশন স্থাপন করলে এটি করার সাজেশন দেওয়া হয় (BillingClient শুরু করুন-এ যেমন আলোচনা করা হয়েছে, আপনার অ্যাপ চালু হলে বা ফোরগ্রাউন্ডে এলে এটি করার সাজেশন দেওয়া হয়)। onServiceConnected-এ সঠিক ফলাফল পাওয়ার সময় queryPurchasesAsync কল করে এটি করা যেতে পারে। এই সাজেশন অনুসরণ করা, এই ধরনের ইভেন্ট ও পরিস্থিতি ম্যানেজ করার জন্য অত্যন্ত গুরুত্বপূর্ণ:
- কেনাকাটার সময় নেটওয়ার্ক সংক্রান্ত সমস্যা: কোনও ব্যবহারকারী সফলভাবে কেনাকাটা
করতে এবং Google-এর থেকে কনফার্মেশন পেতে পারেন, কিন্তু তার ডিভাইস এবং আপনার অ্যাপ
PurchasesUpdatedListener-এর মাধ্যমে কেনাকাটার বিজ্ঞপ্তি পাওয়ার আগেই তার ডিভাইসের নেটওয়ার্ক কানেক্টিভিটি হারিয়ে যায়। - একাধিক ডিভাইস: কোনও ব্যবহারকারী একটি ডিভাইসে আইটেম কিনে অন্য ডিভাইসে সেটি দেখতে চাইতে পারেন।
- আপনার অ্যাপের বাইরে করা কেনাকাটা ম্যানেজ করা: কিছু কেনাকাটা, যেমন প্রোমোশন রিডিম করা, আপনার অ্যাপের বাইরে করা যেতে পারে।
- কেনাকাটার স্ট্যাটাস পরিবর্তন ম্যানেজ করা: আপনার অ্যাপ্লিকেশন না চললেও, কোনও ব্যবহারকারী বাকি থাকা কেনাকাটার জন্য পেমেন্ট সম্পূর্ণ করতে পারেন এবং আপনার অ্যাপ খোলার সময় কেনাকাটা সম্পূর্ণ করার কনফার্মেশন পাওয়ার আশা করতে পারেন।
- সাসপেন্ড করা সাবস্ক্রিপশন: সাবস্ক্রিপশন লাইফসাইকেল চলাকালীন কোনও সাবস্ক্রিপশন সাসপেন্ড করা হতে পারে। BillingClient.queryPurchasesAsync()
সাসপেন্ড করা সাবস্ক্রিপশন তখনই ফিরিয়ে দেবে যদি
includeSuspendedSubscriptionsপ্যারামিটারQueryPurchasesParams.Builder-এ সেট করা থাকে। সাসপেন্ড করা সাবস্ক্রিপশনPurchasesUpdatedListener-এ ফেরত দেওয়া হয় না।
আপনার অ্যাপ নতুন বা সম্পূর্ণ হওয়া কেনাকাটা শনাক্ত করলে, আপনার অ্যাপকে এগুলি করতে হবে:
- কেনাকাটা যাচাই করুন।
- কেনাকাটা সম্পূর্ণ করার জন্য ব্যবহারকারীকে কন্টেন্ট প্রদান করুন।
- ব্যবহারকারীকে বিজ্ঞপ্তি পাঠান।
- আপনার অ্যাপ যে সম্পূর্ণ কেনাকাটা প্রসেস করেছে তা Google-কে জানান।
এই ধাপগুলি নিম্নলিখিত বিভাগে বিস্তারিতভাবে আলোচনা করা হয়েছে এবং তারপরে সমস্ত ধাপের রিক্যাপ করার জন্য একটি বিভাগ রয়েছে।
কেনাকাটা যাচাই করুন
ব্যবহারকারীকে সুবিধা দেওয়ার আগে আপনার অ্যাপকে সবসময় কেনাকাটার বৈধতা যাচাই করতে হবে। এনটাইটেলমেন্ট দেওয়ার আগে কেনাকাটা যাচাই করুন লিঙ্কে দেওয়া নির্দেশিকা অনুসরণ করে এটি করা যেতে পারে। কেনাকাটা যাচাই করার পরেই আপনার অ্যাপকে কেনাকাটা প্রসেস করা এবং ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করা চালিয়ে যেতে হবে, যা পরবর্তী বিভাগে আলোচনা করা হয়েছে। কোনও কেনাকাটা আপনার যাচাইকরণ, উপযুক্ততা বা অপব্যবহার সংক্রান্ত চেক সম্পূর্ণ করতে না পারলে, বাতিল করা বা অসম্পূর্ণ কেনাকাটা ম্যানেজ করা নিবন্ধটি দেখুন।
ব্যবহারকারীকে এনটাইটেলমেন্টের অনুমতি দিন
আপনার অ্যাপ কেনাকাটা যাচাই করার পরে, এটি ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করা চালিয়ে যেতে
এবং ব্যবহারকারীকে বিজ্ঞপ্তি দিতে পারে। এনটাইটেলমেন্ট দেওয়ার আগে, আপনার অ্যাপ কেনাকাটার স্ট্যাটাস PURCHASED কিনা তা চেক করছে কিনা তা যাচাই করুন। কেনাকাটা
'বাকি আছে' স্ট্যাটাসে থাকলে, আপনার অ্যাপের উচিত ব্যবহারকারীকে জানানো যে এনটাইটেলমেন্ট পাওয়ার আগে
কেনাকাটা সম্পূর্ণ করার জন্য তাকে এখনও অ্যাকশন সম্পূর্ণ করতে হবে।
কেনাকাটার স্ট্যাটাস 'বাকি আছে' থেকে 'কেনা হয়েছে' স্ট্যাটাসে পরিবর্তিত হলে তবেই এনটাইটেলমেন্ট মঞ্জুর করুন।
বাকি থাকা ট্রানজ্যাকশন ম্যানেজ করা থেকে অতিরিক্ত তথ্য পাওয়া যাবে।
ইউজার আইডেন্টিফায়ার অ্যাটাচ করা বিভাগে যেমন আলোচনা করা হয়েছে, আপনি যদি কেনাকাটার সাথে ইউজার আইডেন্টিফায়ার অ্যাটাচ করে থাকেন, তাহলে আপনার সিস্টেমে সঠিক ব্যবহারকারীকে অ্যাট্রিবিউট করার জন্য সেগুলি উদ্ধার ও ব্যবহার করতে পারবেন। কেনাকাটা রিকনসাইল করার সময় এই টেকনিক কাজে লাগে যেখানে আপনার অ্যাপ হয়ত ভুলে গেছে যে কোন ব্যবহারকারী কেনাকাটা করেছেন। অপব্যবহারের বিরুদ্ধে সুরক্ষা দিতে, Google Play আপনাকে এনটাইটেলমেন্ট দেওয়ার আগে আপনার সুরক্ষিত ব্যাকএন্ডে এইসব শনাক্তকারী যাচাই করার সাজেশন দেয়। আরও তথ্যের জন্য, এনটাইটেলমেন্ট দেওয়ার আগে কেনাকাটা যাচাই করুন নিবন্ধটি দেখুন। মনে রাখবেন, আপনার অ্যাপের বাইরে করা কেনাকাটায় এইসব আইডেন্টিফায়ার সেট করা থাকবে না। এই ক্ষেত্রে আপনার অ্যাপ লগ-ইন করা ব্যবহারকারীকে এনটাইটেলমেন্ট দিতে পারে অথবা ব্যবহারকারীকে পছন্দের অ্যাকাউন্ট বেছে নেওয়ার জন্য প্রম্পট করতে পারে।
প্রি-অর্ডারের ক্ষেত্রে, রিলিজের সময় না হওয়া পর্যন্ত কেনাকাটা 'বাকি আছে' স্ট্যাটাসে থাকে। রিলিজের সময় প্রি-অর্ডার কেনাকাটা সম্পূর্ণ হবে এবং অতিরিক্ত অ্যাকশন ছাড়াই স্ট্যাটাস পরিবর্তন হয়ে 'কেনা হয়েছে' হিসেবে দেখাবে।
ব্যবহারকারীকে বিজ্ঞপ্তি পাঠান
ব্যবহারকারীকে এনটাইটেলমেন্ট দেওয়ার পরে, আপনার অ্যাপের উচিত কেনাকাটা সম্পূর্ণ হওয়ার স্বীকৃতি হিসেবে একটি বিজ্ঞপ্তি দেখানো। বিজ্ঞপ্তি পাওয়ার ফলে, ব্যবহারকারী কেনাকাটা সম্পূর্ণ হয়েছে কিনা তা নিয়ে বিভ্রান্ত হন না, যার ফলে ব্যবহারকারী আপনার অ্যাপ ব্যবহার করা বন্ধ করে দিতে পারেন, ব্যবহারকারী সহায়তা টিমের সাথে যোগাযোগ করতে পারেন অথবা সোশ্যাল মিডিয়ায় এই বিষয়ে অভিযোগ করতে পারেন। মনে রাখবেন, আপনার অ্যাপ্লিকেশনের লাইফসাইকেল চলাকালীন যেকোনও সময় আপনার অ্যাপ কেনাকাটা সংক্রান্ত আপডেট শনাক্ত করতে পারে। যেমন, অভিভাবক অন্য ডিভাইসে বাকি থাকা কেনাকাটার অনুমোদন করেন, এই ক্ষেত্রে আপনার অ্যাপ ব্যবহারকারীকে উপযুক্ত সময়ে বিজ্ঞপ্তি পাঠাতে দেরি করতে পারে। কিছু উদাহরণ যেখানে দেরি করা উপযুক্ত হবে:
- গেমের অ্যাকশন পার্ট বা কাটসিন চলাকালীন মেসেজ দেখালে ব্যবহারকারীর মনোযোগ বিঘ্নিত হতে পারে। এই ক্ষেত্রে, অ্যাকশন পার্ট শেষ হওয়ার পরে আপনাকে অবশ্যই ব্যবহারকারীকে জানাতে হবে।
- গেমের প্রাথমিক টিউটোরিয়াল ও ব্যবহারকারী সেট-আপের সময়। যেমন, কোনও ব্যবহারকারী আপনার অ্যাপ ইনস্টল করার আগে অ্যাপের বাইরে থেকে কেনাকাটা করে থাকতে পারেন। আমরা সাজেস্ট করি যে নতুন ব্যবহারকারী গেম খোলার সাথে সাথেই অথবা প্রাথমিক ব্যবহারকারী সেট-আপের সময় তাদের পুরস্কার সম্পর্কে জানান। আপনার অ্যাপে ব্যবহারকারীকে এনটাইটেলমেন্ট দেওয়ার আগে অ্যাকাউন্ট তৈরি করতে বা লগ-ইন করতে হলে, ব্যবহারকারীকে তার কেনাকাটা দাবি করার জন্য কোন কোন ধাপ সম্পূর্ণ করতে হবে তা জানানো উচিত। এটি খুবই গুরুত্বপূর্ণ কারণ আপনার অ্যাপ কেনাকাটা প্রসেস না করলে ৩ দিন পরে কেনাকাটার টাকা রিফান্ড করে দেওয়া হয়।
কেনাকাটার ব্যাপারে ব্যবহারকারীকে বিজ্ঞপ্তি পাঠানোর সময়, Google Play নিম্নলিখিত পদ্ধতি সাজেস্ট করে:
- ইন-অ্যাপ ডায়ালগ দেখান।
- ইন-অ্যাপ মেসেজ বক্সে মেসেজটি ডেলিভার করুন এবং ইন-অ্যাপ মেসেজ বক্সে যে নতুন মেসেজ এসেছে তা স্পষ্টভাবে উল্লেখ করুন।
- OS বিজ্ঞপ্তি মেসেজ ব্যবহার করুন।
বিজ্ঞপ্তির মাধ্যমে ব্যবহারকারীকে তার পাওয়া সুবিধা সম্পর্কে জানাতে হবে। যেমন, "আপনি ১০০টি গোল্ড কয়েন কিনেছেন!"। এছাড়াও, Play Pass-এর মতো কোনও প্রোগ্রামের সুবিধা হিসেবে কেনাকাটা করা হলে, আপনার অ্যাপ ব্যবহারকারীকে এই বিষয়ে জানায়। যেমন, "আইটেম পাওয়া গেছে! আপনি Play Pass-এর মাধ্যমে ১০০টি জেম পেয়েছেন। চালিয়ে যান।"। প্রতিটি প্রোগ্রামে ব্যবহারকারীদের সুবিধা সম্পর্কে জানাতে, তাদের দেখানোর জন্য সাজেস্ট করা টেক্সট সম্পর্কে নির্দেশিকা থাকতে পারে।
কেনাকাটা প্রসেস করা হয়েছে বলে Google-কে জানান
আপনার অ্যাপ ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করার পরে এবং সফল ট্রানজ্যাকশন সম্পর্কে তাকে জানানোর পরে, আপনার অ্যাপকে Google-কে জানাতে হবে যে কেনাকাটা সফলভাবে প্রসেস করা হয়েছে। কেনাকাটা স্বীকার করার মাধ্যমে এটি করা হয় এবং তিন দিনের মধ্যে এটি করতে হবে যাতে কেনাকাটা অটোমেটিক রিফান্ড না হয়ে যায় এবং এনটাইটেলমেন্ট তুলে নেওয়া হয়। বিভিন্ন ধরনের কেনাকাটা স্বীকার করার প্রসেস নিচের বিভাগে বর্ণনা করা হয়েছে।
ব্যবহারযোগ্য প্রোডাক্ট
ব্যবহার্য আইটেমের ক্ষেত্রে, আপনার অ্যাপে সুরক্ষিত ব্যাকএন্ড থাকলে, আমরা আপনাকে
Purchases.products:consume ব্যবহার করার সাজেশন দিই যাতে নির্ভরযোগ্যভাবে কেনাকাটা ব্যবহার করা যায়। Purchases.products:get কল করার ফলাফল থেকে
consumptionState চেক করে দেখে নিন যে কেনাকাটাটি
আগে থেকেই ব্যবহার করা হয়নি। আপনার অ্যাপ যদি ব্যাকএন্ড ছাড়া
শুধু ক্লায়েন্ট-ভিত্তিক হয়, তাহলে Google Play Billing Library থেকে
consumeAsync() ব্যবহার করুন। দুটি পদ্ধতিই স্বীকৃতি সংক্রান্ত প্রয়োজনীয়তা পূরণ করে এবং ইঙ্গিত দেয় যে আপনার অ্যাপ ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করেছে।
এছাড়াও, এই পদ্ধতিগুলি আপনার অ্যাপকে ইনপুট পারচেজ টোকেনের সাথে সম্পর্কিত এককালীন প্রোডাক্টকে
আবার কেনার জন্য উপলভ্য করতে দেয়। consumeAsync()-এর সাথে আপনাকে
অবশ্যই এমন একটি অবজেক্ট পাস করতে হবে যা ConsumeResponseListener
ইন্টারফেস প্রয়োগ করে। এই অবজেক্টটি কনজাম্পশন অপারেশনের ফলাফল ম্যানেজ করে। আপনি
onConsumeResponse() পদ্ধতি ওভাররাইড করতে পারেন, যা
অপারেশন সম্পূর্ণ হলে Google Play Billing Library কল করে।
নিম্নলিখিত উদাহরণে দেখানো হয়েছে যে কীভাবে সংশ্লিষ্ট কেনাকাটার টোকেন ব্যবহার করে Google Play Billing Library-এর মাধ্যমে কোনও প্রোডাক্ট ব্যবহার করা যায়:
Kotlin
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 = (billingResult, 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 Billing Library ব্যবহার করে কীভাবে কেনাকাটা স্বীকার করতে হয় তা নিম্নলিখিত উদাহরণ থেকে দেখুন:
Kotlin
val client: BillingClient = billingClient val acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.purchaseToken) val ackPurchaseResult = withContext(Dispatchers.IO) { client.acknowledgePurchase(acknowledgePurchaseParams.build()) }
জাভা
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) { if (!purchase.isAcknowledged()) { AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() .setPurchaseToken(purchase.getPurchaseToken()) .build(); billingClient.acknowledgePurchase(acknowledgePurchaseParams, (billingResult) -> { // Acknowledgment handled. }); } }
সাবস্ক্রিপশন
সাবস্ক্রিপশন নন-কনজিউমেবল আইটেমের মতোই ম্যানেজ করা হয়। সম্ভব হলে, আপনার সুরক্ষিত ব্যাকএন্ড থেকে কেনাকাটা নির্ভরযোগ্যভাবে স্বীকার করতে,
Google Play Developer API থেকে
Purchases.subscriptions.acknowledge ব্যবহার করুন। Purchases.subscriptions:get থেকে কেনাকাটার রিসোর্সে acknowledgementState চেক করে দেখে নিন যে কেনাকাটা আগে স্বীকার করা হয়েছে কিনা। অন্যথায়, আপনি isAcknowledged() চেক করার পরে
Google Play Billing Library থেকে BillingClient.acknowledgePurchase() ব্যবহার করে
সাবস্ক্রিপশন অ্যাকনলেজ করতে পারবেন। প্রাথমিক
সাবস্ক্রিপশন কেনাকাটা স্বীকার করতে হবে। সাবস্ক্রিপশন রিনিউ করার জন্য
স্বীকৃতি জানানোর প্রয়োজন নেই। সাবস্ক্রিপশন কখন স্বীকার করতে হবে সেই সম্পর্কে আরও তথ্যের জন্য, সাবস্ক্রিপশন বিক্রি করুন শীর্ষক নিবন্ধটি দেখুন।
বাতিল বা অসম্পূর্ণ কেনাকাটা ম্যানেজ করা
কোনও কেনাকাটা আপনার ব্যাকএন্ড যাচাইকরণ, ব্যবহারকারীর উপযুক্ততা চেক, জালিয়াতি এবং অপব্যবহার চেক করতে ব্যর্থ হলে অথবা আপনার সিস্টেম এনটাইটেলমেন্ট পূরণ করতে না পারলে, এনটাইটেলমেন্ট মঞ্জুর করবেন না এবং কেনাকাটা স্বীকার বা ব্যবহার করবেন না।
গ্রাহকের সুরক্ষার জন্য, স্বীকৃতি না দেওয়া কেনাকাটা অটোমেটিক রিফান্ড করা হয় এবং স্বীকৃতির উইন্ডোর মেয়াদ শেষ হওয়ার পরে বাতিল করা হয়। তবে, কেনাকাটা বাতিল করার জন্য এই মেয়াদ শেষ হওয়ার উইন্ডোর উপর নির্ভর করবেন না। স্বীকৃতি উইন্ডোর মেয়াদ শেষ হয়ে গেলে অর্ডারটি অস্বীকৃত অবস্থায় থেকে যায় এবং Google Play-এর কাছে তা অস্পষ্ট হয়ে যায়, যা ব্যাকএন্ড প্রসেসিং টাইমআউট থেকে ইচ্ছাকৃতভাবে ডেভেলপারের প্রত্যাখ্যানকে আলাদা করতে পারে না।
পরিবর্তে, Google Play Developer API ব্যবহার করে আপনার ব্যাকএন্ড থেকে বাতিল করা কেনাকাটা অবিলম্বে প্রত্যাহার করুন এবং রিফান্ড করুন:
- সাবস্ক্রিপশন:
revocationContext-এ"fullRefund": {}-এর সাথেpurchases.subscriptionsv2.revoke-কে কল করুন। এটি অবিলম্বে সাবস্ক্রিপশন বন্ধ করে দেয়, অ্যাক্সেস তুলে নেয় এবং সম্পূর্ণ রিফান্ড করার প্রসেস শুরু করে। - এককালীন প্রোডাক্ট: কোনও অর্ডার অবিলম্বে রিফান্ড করতে এবং তার এনটাইটেলমেন্ট তুলে নিতে,
revokeপ্যারামিটারtrue-এ সেট করেorders.refundকল করুন। এই পদ্ধতি কল করার সময়, আপনাকে কেনাকাটার অর্ডার আইডি পাস করতে হবে, যা আপনিPurchase.getOrderId()বাpurchases.productsv2.getproductpurchasev2ব্যবহার করে ফিরিয়ে আনতে পারবেন। বাতিল করা কেনাকাটার জন্য কখনওconsumeAsync(),acknowledgePurchase(),Purchases.products:consumeঅথবাPurchases.products:acknowledge-এ কল করবেন না। - RTDN এবং বাতিল করা কেনাকাটার আচরণ: ডেভেলপার-চালিত প্রত্যাহার এবং
রিফান্ড (
purchases.subscriptionsv2.revokeএবংorders.refund-এর সাথেrevoke-কেtrue-এ সেট করা) রিয়েল-টাইম ডেভেলপার বিজ্ঞপ্তি ট্রিগার করে এবং বাতিল করা কেনাকাটার API-তে রেকর্ড করা হয় (purchases.voidedpurchases.listডেভেলপারের জন্যvoidedSourceরেসপন্স ফিল্ড1-এ সেট করা):- সাবস্ক্রিপশন:
SUBSCRIPTION_REVOKEDবিজ্ঞপ্তি এবংVoidedPurchaseNotification, দুটিই পাঠায়। - এককালীন প্রোডাক্ট:
VoidedPurchaseNotification(এবংONE_TIME_PRODUCT_CANCELEDবিজ্ঞপ্তি পাঠায়, যদি আপনার অ্যাপ Play Console-এ সব এককালীন প্রোডাক্টের বিজ্ঞপ্তি পাওয়ার জন্য কনফিগার করা থাকে)। revoke-এর মানtrue-এ সেট না করেorders.refundকল করলে, এনটাইটেলমেন্ট তুলে না নিয়েই অর্ডার রিফান্ড করা হয় এবং এনটাইটেলমেন্ট তুলে নেওয়া বা বাতিল করা কেনাকাটার বিজ্ঞপ্তি ট্রিগার করা হয় না। আরও তথ্যের জন্য, সাবস্ক্রিপশন ও এক-বার ক্রয় ম্যানেজ করুন।
- সাবস্ক্রিপশন:
রিক্যাপ
এইসব ধাপের একটি রিক্যাপ নিচে দেওয়া হল।
এনটাইটেলমেন্ট দেওয়ার আগে কেনাকাটা যাচাই করতে আপনার সুরক্ষিত ব্যাকএন্ডে কেনাকাটার তথ্য পাঠান।
কেনাকাটার মাধ্যমে আপনার এনটাইটেলমেন্ট স্টোরেজ আপডেট করুন। কেনাকাটা 'বাকি আছে' স্ট্যাটাসে থাকলে, এনটাইটেলমেন্ট 'বাকি আছে' হিসেবে চিহ্নিত করা হয়েছে কিনা এবং ব্যবহারকারী এখনও সুবিধা পাননি কিনা তা নিশ্চিত করুন। এই ধাপটি আপনার সুরক্ষিত ব্যাকএন্ডে করা হলে ভালো হয় এবং ধাপ ১-এ আপনার ব্যাকএন্ডে API কলের সাথে একত্রিত করা যেতে পারে।
উপযুক্ত মেসেজ ব্যবহার করে ব্যবহারকারীকে বিজ্ঞপ্তি পাঠান (আগে আলোচনা করা হয়েছে এমন কোনও কারণে বিজ্ঞপ্তি পাঠাতে দেরি হলে)।
কেনাকাটা প্রসেস করা বিভাগে আলোচনা করা ধাপগুলি ব্যবহার করে কেনাকাটা প্রসেস করা হয়েছে কিনা তা Google-কে জানান।
আপনার অ্যাপ এইসব ধাপ সঠিকভাবে প্রয়োগ করেছে কিনা তা যাচাই করতে, আপনি টেস্টিং গাইড অনুসরণ করতে পারেন।
পেন্ডিং ট্রানজ্যাকশন ম্যানেজ করা
Google Play-তে পেন্ডিং ট্রানজ্যাকশন বা এমন ট্রানজ্যাকশন করা যায় যেখানে ব্যবহারকারী কেনাকাটা শুরু করার পর থেকে পেমেন্ট পদ্ধতি প্রসেস হওয়া পর্যন্ত এক বা একাধিক অতিরিক্ত ধাপ প্রয়োজন হয়। Google যতক্ষণ না আপনাকে জানাচ্ছে যে ব্যবহারকারীর পেমেন্ট পদ্ধতি থেকে সফলভাবে চার্জ করা হয়েছে, ততক্ষণ আপনার অ্যাপের এই ধরনের কেনাকাটার জন্য এনটাইটেলমেন্ট দেওয়া উচিত নয়।
যেমন, কোনও ব্যবহারকারী কোনও ফিজিক্যাল স্টোর বেছে নিয়ে ট্রানজ্যাকশন শুরু করতে পারেন যেখানে তিনি পরে নগদে পেমেন্ট করবেন। ব্যবহারকারী বিজ্ঞপ্তি ও ইমেল, দুটির মাধ্যমেই একটি কোড পাবেন। ব্যবহারকারী দোকানে পৌঁছালে, তিনি ক্যাশিয়ারের কাছে কোডটি রিডিম করতে এবং ক্যাশে পেমেন্ট করতে পারবেন। তারপর Google আপনাকে এবং ব্যবহারকারীকে পেমেন্ট পাওয়ার বিজ্ঞপ্তি পাঠায়। আপনার অ্যাপ তখন ব্যবহারকারীকে এনটাইটেলমেন্ট দিতে পারবে।
আপনার অ্যাপের জন্য পেন্ডিং ট্রানজ্যাকশন চালু করতে
BillingClient শুরু করার অংশ হিসেবে enablePendingPurchases() কল করুন। আপনার অ্যাপকে অবশ্যই
এককালীন প্রোডাক্টের জন্য পেন্ডিং ট্রানজ্যাকশন চালু করতে ও সাপোর্ট করতে হবে। সহায়তা যোগ করার আগে, পেন্ডিং ট্রানজ্যাকশনের জন্য কেনাকাটার লাইফসাইকেল সম্পর্কে আপনি বুঝেছেন কিনা তা নিশ্চিত করুন।
আপনার অ্যাপ যখন নতুন কেনাকাটার তথ্য পায়, হয় আপনার
PurchasesUpdatedListener-এর মাধ্যমে অথবা
queryPurchasesAsync কল করার ফলে, তখন getPurchaseState() পদ্ধতি ব্যবহার করে
নির্ধারণ করুন যে কেনাকাটার স্ট্যাটাস PURCHASED নাকি PENDING। স্ট্যাটাস PURCHASED হলে
শুধুমাত্র তখনই আপনাকে এনটাইটেলমেন্ট মঞ্জুর করতে হবে।
আপনার অ্যাপ চালু থাকলে এবং ব্যবহারকারী কেনাকাটা সম্পূর্ণ করার সময়
আপনার Play Billing Library কানেকশন অ্যাক্টিভ থাকলে, আপনার PurchasesUpdatedListener আবার
কল করা হয় এবং PurchaseState এখন PURCHASED হয়। এই পর্যায়ে, আপনার
অ্যাপ কেনাকাটা শনাক্ত ও
প্রসেস করার জন্য স্ট্যান্ডার্ড পদ্ধতি ব্যবহার করে কেনাকাটা প্রসেস করতে পারবে। আপনার অ্যাপ না চলার সময় 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 Developer API ব্যবহার করে কেনাকাটার বর্তমান স্ট্যাটাস
চেক করতে পারবেন।
একাধিক পরিমাণ কেনাকাটা ম্যানেজ করা
Google Play Billing Library-এর ৪.০ ও তার পরবর্তী ভার্সনে কাজ করে, Google Play গ্রাহকদের একই এককালীন প্রোডাক্ট একাধিকবার কেনার অনুমতি দেয়, এর জন্য গ্রাহকদের কেনাকাটার কার্ট থেকে পরিমাণ উল্লেখ করে একটি ট্রানজ্যাকশন করতে হয়। আপনার অ্যাপ একাধিক পরিমাণ কেনাকাটা ম্যানেজ করবে এবং নির্দিষ্ট কেনাকাটার পরিমাণের উপর ভিত্তি করে এনটাইটেলমেন্ট প্রদান করবে বলে আশা করা হচ্ছে।
একাধিক পরিমাণ কেনাকাটার সুবিধা দিতে, আপনার অ্যাপের প্রভিশনিং লজিককে আইটেমের পরিমাণ
চেক করতে হবে। আপনি নিম্নলিখিত API-এর মধ্যে থেকে একটির quantity ফিল্ড অ্যাক্সেস করতে পারবেন:
- Google Play Billing Library থেকে
getQuantity()। - Google Play Developer API থেকে
Purchases.products.quantity
একাধিক পরিমাণ কেনাকাটা ম্যানেজ করার জন্য লজিক যোগ করার পরে, আপনাকে Google Play Developer Console-এ এককালীন প্রোডাক্ট ম্যানেজমেন্ট পৃষ্ঠায় সংশ্লিষ্ট প্রোডাক্টের জন্য একাধিক পরিমাণ ফিচার চালু করতে হবে।
ব্যবহারকারীর বিলিং কনফিগারেশন কোয়েরি করুন
getBillingConfigAsync() ব্যবহারকারী Google Play-এর জন্য যে দেশ ব্যবহার করেন সেটি প্রদান করে।
BillingClient তৈরি করার পরে আপনি ব্যবহারকারীর বিলিং কনফিগারেশন কোয়েরি করতে পারবেন। নিম্নলিখিত কোড স্নিপেট থেকে জানতে পারবেন যে কীভাবে getBillingConfigAsync()-এ কল করতে হয়। BillingConfigResponseListener প্রয়োগ করে
রেসপন্স ম্যানেজ করুন। এই লিসেনার আপনার অ্যাপ থেকে শুরু করা সব বিলিং
কনফিগারেশন কোয়েরির জন্য আপডেট পায়।
ফেরত আসা BillingResult-এ কোনও সমস্যা না থাকলে, আপনি BillingConfig অবজেক্টের countryCode ফিল্ড চেক করে ব্যবহারকারীর Play Country জানতে পারবেন।
Kotlin
// 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 { // Handle errors } } } )
জাভা
GetBillingConfigParams getBillingConfigParams = GetBillingConfigParams.newBuilder().build(); billingClient.getBillingConfigAsync( getBillingConfigParams, (billingResult, billingConfig) -> { if (billingResult.getResponseCode() == BillingResponseCode.OK && billingConfig != null) { String countryCode = billingConfig.getCountryCode(); } else { // TODO: Handle errors } });