প্রোডাক্ট বিক্রি শুরু করার জন্য কীভাবে আপনার অ্যাপে 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" }
কোটলিন
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" }
কোটলিন
dependencies { val billing_version = "9.1.0" implementation("com.android.billingclient:billing-ktx:$billing_version") }
BillingClient ইনিশিয়ালাইজ করা
Google Play Billing Library-তে কোনও ডিপেন্ডেন্সি যোগ করার পরে, আপনাকে একটি BillingClient ইনস্ট্যান্স
ইনিশিয়ালাইজ করতে হবে। BillingClient হল Google Play বিলিং লাইব্রেরি এবং আপনার অ্যাপের
বাকি অংশের মধ্যে যোগাযোগের প্রধান
ইন্টারফেস। 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, আরও অনুরোধ করার আগে Google Play-এর সাথে আবার কানেক্ট করার জন্য startConnection() পদ্ধতিকে
কল করে। আপনি যদি
অটোমেটিক পরিষেবা আবার কানেক্ট করা চালু করে থাকেন, তাহলে আপনি এই পদ্ধতিটি নো-অপ হিসেবে প্রয়োগ করতে পারবেন।
নিচের উদাহরণে দেখানো হয়েছে কীভাবে কানেকশন শুরু করতে হয় এবং এটি ব্যবহারের জন্য প্রস্তুত কিনা তা পরীক্ষা করতে হয়:
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 অবজেক্টের রেফারেন্স নেয়, যার মধ্যে
queryProductDetailsAsync কল করার মাধ্যমে পাওয়া প্রাসঙ্গিক
ProductDetails অবজেক্ট থাকে। 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-এ তালিকাভুক্ত একাধিক রেসপন্স কোডের মধ্যে একটি ফেরত দেয়। পারচেজ ফ্লো চালু করার সময় কোনও সমস্যা হয়েছে কিনা তা যাচাই করতে
এই ফলাফল চেক করতে ভুলবেন না। BillingResponseCode
of OK সফল লঞ্চের ইঙ্গিত দেয়।
launchBillingFlow()-এ কল করা হলে, সিস্টেম Google Play-এর কেনাকাটার স্ক্রিন দেখায়। ছবি ১-এ সাবস্ক্রিপশন কেনার স্ক্রিন দেখানো হয়েছে:
Google Play, PurchasesUpdatedListener ইন্টারফেস প্রয়োগ করে এমন কোনও লিসনারকে কেনাকাটা
প্রক্রিয়ার ফলাফল প্রদান করতে onPurchasesUpdated() কল করে। আপনি যখন
আপনার ক্লায়েন্ট ইনিশিয়ালাইজ করেন, তখন 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() পদ্ধতি ব্যবহার করুন যাতে ব্যবহারকারীদের
জানানো যায় যে অটোমেটিক সিদ্ধান্ত গ্রহণের মাধ্যমে কোনও আইটেমের দাম পছন্দমতো সেট করা হয়েছে।
আপনাকে অবশ্যই Art-এর সাথে পরামর্শ করতে হবে। ৬ (১) (ea) CRD of the Consumer Rights Directive 2011/83/EU থেকে নির্ধারণ করা হয় যে ব্যবহারকারীদের অফার করা দাম ব্যক্তিগতকৃত কিনা।
setIsOfferPersonalized()-এ বুলিয়ান ইনপুট দিতে হয়। true হলে, Play UI-তে
ডিসক্লোজার অন্তর্ভুক্ত থাকে। false হলে, UI ডিসক্লোজার বাদ দেয়। ডিফল্ট
ভ্যালু হল false।
আরও তথ্যের জন্য গ্রাহক সহায়তা কেন্দ্র দেখুন।
ব্যবহারকারীর শনাক্তকারী তথ্য অ্যাটাচ করা
আপনি পারচেজ ফ্লো চালু করলে, আপনার অ্যাপ obfuscatedAccountId বা obfuscatedProfileId ব্যবহার করে কেনাকাটা করা ব্যবহারকারীর জন্য আপনার কাছে থাকা যেকোনও ইউজার আইডেন্টিফায়ার অ্যাটাচ করতে পারে। উদাহরণস্বরূপ, আপনার সিস্টেমে ব্যবহারকারীর লগ-ইনের অস্পষ্ট ভার্সন শনাক্তকারী হিসেবে ব্যবহার করা যেতে পারে। এইসব প্যারামিটার সেট করলে Google-এর পক্ষে প্রতারণা শনাক্ত করা সহজ হয়। এছাড়াও, এটি আপনাকে নিশ্চিত করতে সাহায্য করতে পারে যে কেনাকাটাগুলি সঠিক ব্যবহারকারীর সাথে অ্যাট্রিবিউট করা হয়েছে, যেমনটি ব্যবহারকারীদের এনটাইটেলমেন্ট প্রদান করা-তে আলোচনা করা হয়েছে।
কেনাকাটা শনাক্ত ও প্রসেস করা
এই বিভাগে বর্ণিত কেনাকাটা শনাক্তকরণ এবং প্রসেসিং সব ধরনের কেনাকাটার ক্ষেত্রে প্রযোজ্য, যার মধ্যে অ্যাপের বাইরে করা কেনাকাটা যেমন প্রোমোশন রিডিম করাও অন্তর্ভুক্ত।
আপনার অ্যাপ নতুন কেনাকাটা এবং সম্পূর্ণ হওয়া বাকি কেনাকাটা নিম্নলিখিত উপায়ে শনাক্ত করে:
- আপনার অ্যাপ
launchBillingFlowকল করার ফলেonPurchasesUpdatedকল করা হলে (আগের বিভাগে আলোচনা করা হয়েছে) অথবা আপনার অ্যাপ চালু থাকাকালীন Billing Library কানেকশন অ্যাক্টিভ থাকলে, আপনার অ্যাপের বাইরে কোনও কেনাকাটা করা হলে বা কোনও বাকি থাকা কেনাকাটা সম্পূর্ণ হলে। যেমন, পরিবারের কোনও সদস্য অন্য ডিভাইসে বাকি থাকা কেনাকাটার অনুমোদন করেন। - ব্যবহারকারীর কেনাকাটা সংক্রান্ত কোয়েরি করার জন্য আপনার অ্যাপ queryPurchasesAsync কল করলে।
#১-এর জন্য, আপনার অ্যাপ চালু থাকা এবং অ্যাক্টিভ Google Play Billing
লাইব্রেরি কানেকশন থাকা পর্যন্ত নতুন বা সম্পূর্ণ হওয়া
কেনাকাটার জন্য 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-এর মাধ্যমে ১০০টি Gem পেয়েছেন। চালিয়ে যান।" প্রতিটি প্রোগ্রামে ব্যবহারকারীদের সুবিধা সম্পর্কে জানাতে, তাদের দেখানোর জন্য সাজেস্ট করা টেক্সট সম্পর্কে নির্দেশিকা থাকতে পারে।
কেনাকাটা প্রসেস করা হয়েছে বলে Google-কে জানানো
আপনার অ্যাপ ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করার পরে এবং সফল ট্রানজ্যাকশন সম্পর্কে তাদের জানানোর পরে, আপনার অ্যাপকে Google-কে জানাতে হবে যে কেনাকাটা সফলভাবে প্রসেস করা হয়েছে। কেনাকাটা স্বীকার করার মাধ্যমে এটি করা হয় এবং এটি তিন দিনের মধ্যে করতে হবে যাতে কেনাকাটার জন্য অটোমেটিক রিফান্ড না হয়ে যায় এবং এনটাইটেলমেন্ট প্রত্যাহার না করা হয়। বিভিন্ন ধরনের কেনাকাটা স্বীকার করার প্রসেস নিচের বিভাগে বর্ণনা করা হয়েছে।
ব্যবহারযোগ্য প্রোডাক্ট
ব্যবহারযোগ্য আইটেমের ক্ষেত্রে, আপনার অ্যাপের সুরক্ষিত ব্যাকএন্ড থাকলে, কেনাকাটা নির্ভরযোগ্যভাবে ব্যবহার করার জন্য আমরা আপনাকে
Purchases.products:consume ব্যবহার করার সাজেশন দিই। Purchases.products:get কল করার ফলাফল থেকে
consumptionState চেক করে দেখে নিন যে কেনাকাটাটি
আগে থেকেই ব্যবহার করা হয়নি। আপনার অ্যাপ যদি ব্যাকএন্ড ছাড়া
শুধুমাত্র ক্লায়েন্ট-ভিত্তিক হয়, তাহলে Google Play Billing Library থেকে
consumeAsync() ব্যবহার করুন। দুটি পদ্ধতিই স্বীকৃতি সংক্রান্ত প্রয়োজনীয়তা পূরণ করে এবং ইঙ্গিত দেয় যে আপনার অ্যাপ ব্যবহারকারীকে এনটাইটেলমেন্ট প্রদান করেছে।
এছাড়াও, এই পদ্ধতিগুলি আপনার অ্যাপকে ইনপুট পারচেজ টোকেনের সাথে সম্পর্কিত এককালীন প্রোডাক্টকে
আবার কেনার জন্য উপলভ্য করতে দেয়। consumeAsync()-এর সাথে আপনাকে অবশ্যই এমন একটি অবজেক্ট পাস করতে হবে যা ConsumeResponseListener
ইন্টারফেস
ইমপ্লিমেন্ট করে। এই অবজেক্টটি কনজাম্পশন অপারেশনের ফলাফল ম্যানেজ করে। আপনি onConsumeResponse() মেথডকে ওভাররাইড করতে পারেন, যা
অপারেশন সম্পূর্ণ হলে Google Play বিলিং লাইব্রেরি কল করে।
নিচের উদাহরণে সংশ্লিষ্ট পার্চেজ টোকেন ব্যবহার করে 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-এর সাথেrevoketrueহিসেবে সেট করা) রিয়েল-টাইম ডেভেলপার বিজ্ঞপ্তি ট্রিগার করে এবং এগুলি বাতিল করা কেনাকাটা API-তে রেকর্ড করা হয় (purchases.voidedpurchases.listডেভেলপারের জন্যvoidedSourceরেসপন্স ফিল্ড1হিসেবে সেট করা):- সাবস্ক্রিপশন:
SUBSCRIPTION_REVOKEDবিজ্ঞপ্তি ওVoidedPurchaseNotification, দুটিই পাঠায়। - এককালীন প্রোডাক্ট:
VoidedPurchaseNotification(এবং আপনার অ্যাপ যদি Play Console-এ সব এককালীন প্রোডাক্টের বিজ্ঞপ্তি পাওয়ার জন্য কনফিগার করা থাকে, তাহলে একটিONE_TIME_PRODUCT_CANCELEDবিজ্ঞপ্তি) পাঠায়। 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-এ ট্রানজিশন করলে, আপনার
রিয়েল-টাইম ডেভেলপার বিজ্ঞপ্তি ক্লায়েন্ট একটি
ONE_TIME_PRODUCT_PURCHASED বা SUBSCRIPTION_PURCHASED বিজ্ঞপ্তি পায়। কেনাকাটা বাতিল করা হলে, আপনি ONE_TIME_PRODUCT_CANCELED বা
SUBSCRIPTION_PENDING_PURCHASE_CANCELED বিজ্ঞপ্তি পাবেন। আপনার গ্রাহক প্রয়োজনীয় টাইমফ্রেমের মধ্যে পেমেন্ট সম্পূর্ণ না করলে এটি হতে পারে। মনে রাখবেন যে আপনি
সবসময় Google Play Developer API ব্যবহার করে কোনও
কেনাকাটার বর্তমান স্ট্যাটাস চেক করতে পারবেন।
একাধিক পরিমাণ কেনাকাটা ম্যানেজ করা
Google Play বিলিং লাইব্রেরির 4.0 ও এর পরের যেকোনও ভার্সনে কাজ করে, 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
দেশ জানতে পারবেন।
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 } });