প্রোডাক্ট বিক্রি শুরু করার জন্য কীভাবে আপনার অ্যাপে Google Play Billing Library ইন্টিগ্রেট করবেন তা এই ডকুমেন্টে বর্ণনা করা হয়েছে।
কেনাকাটার মেয়াদ
এককালীন কেনাকাটা বা সাবস্ক্রিপশনের জন্য এখানে একটি সাধারণ কেনাকাটার ফ্লো দেওয়া হল।
- ব্যবহারকারী কী কিনতে পারবেন তা তাকে দেখান।
- ব্যবহারকারীকে কেনাকাটা সম্পূর্ণ করার জন্য কেনাকাটা সংক্রান্ত ফ্লো লঞ্চ করুন।
- আপনার সার্ভারে কেনাকাটা যাচাই করুন।
- ব্যবহারকারীকে কন্টেন্ট দাও।
- কন্টেন্ট ডেলিভারি করা হয়েছে বলে স্বীকার করুন। ব্যবহারযোগ্য প্রোডাক্টের ক্ষেত্রে, কেনাকাটা সম্পূর্ণ করুন যাতে ব্যবহারকারী আইটেমটি আবার কিনতে পারেন।
সাবস্ক্রিপশন বাতিল না করা পর্যন্ত অটোমেটিক রিনিউ হয়। সাবস্ক্রিপশন নিম্নলিখিত স্ট্যাটাস পেতে পারে:
- অ্যাক্টিভ: ব্যবহারকারী নিয়ম মেনে চলছেন এবং তার সাবস্ক্রিপশনে অ্যাক্সেস আছে।
- বাতিল করা হয়েছে: ব্যবহারকারী বাতিল করেছেন, তবে মেয়াদ শেষ না হওয়া পর্যন্ত অ্যাক্সেস থাকবে।
- গ্রেস পিরিয়ডে আছে: ব্যবহারকারী পেমেন্ট সংক্রান্ত সমস্যার সম্মুখীন হয়েছেন, কিন্তু এখনও অ্যাক্সেস আছে এবং Google পেমেন্ট পদ্ধতি আবার চেষ্টা করছে।
- হোল্ডে আছে: ব্যবহারকারী পেমেন্ট সংক্রান্ত সমস্যার সম্মুখীন হয়েছেন এবং Google পেমেন্ট পদ্ধতি আবার চেষ্টা করার সময় তার আর অ্যাক্সেস নেই।
- পজ করা হয়েছে: ব্যবহারকারী তার অ্যাক্সেস পজ করেছেন এবং সেটি আবার চালু না করা পর্যন্ত তার অ্যাক্সেস থাকবে না।
- মেয়াদ শেষ হয়ে গেছে: ব্যবহারকারী বাতিল করেছেন এবং সাবস্ক্রিপশনে অ্যাক্সেস হারিয়েছেন। মেয়াদ শেষ হয়ে গেলে ব্যবহারকারীকে চর্ন হয়ে গেছেন বলে ধরে নেওয়া হয়।
Google Play-তে কানেকশন ইনিশিয়ালাইজ করা
Google Play-এর বিলিং সিস্টেমের সাথে ইন্টিগ্রেট করার প্রথম ধাপ হল আপনার অ্যাপে Google Play বিলিং লাইব্রেরি যোগ করা এবং কানেকশন চালু করা।
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 এখন
অটোমেটিক পরিষেবা কানেকশন আবার স্থাপন করতে
পারবে। এর ফলে, API কল করার আগে ইন্টার্নালি রিকানেকশন ম্যানেজ করা হয় বলে
SERVICE_DISCONNECTED উত্তর কমে যেতে পারে।
কীভাবে অটোমেটিক আবার কানেক্ট করার সুবিধা চালু করতে হয়
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-এর একটি ইনস্ট্যান্স পাস করুন যা ProductType-এর সাথে Google Play Console-এ তৈরি করা প্রোডাক্ট আইডি স্ট্রিংয়ের
একটি তালিকা নির্দিষ্ট করে। ProductType-এর
মূল্য ProductType.INAPP এককালীন প্রোডাক্টের জন্য অথবা
ProductType.SUBS সাবস্ক্রিপশনের জন্য হতে পারে।
Kotlin এক্সটেনশন সহ কোয়েরি
আপনি Kotlin এক্সটেনশন ব্যবহার করলে, queryProductDetails() এক্সটেনশন ফাংশন কল করে এককালীন প্রোডাক্টের
বিস্তারিত তথ্য কোয়েরি করতে পারবেন।
queryProductDetails() Kotlin কোরাউটিন ব্যবহার করে, যাতে আপনাকে আলাদা
লিসনার ডিফাইন করতে না হয়। এর পরিবর্তে, কোয়েরি করা
সম্পূর্ণ না হওয়া পর্যন্ত ফাংশনটি সাসপেন্ড করা হয়, তারপরে আপনি ফলাফল প্রসেস করতে পারবেন:
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-এ List-এর
UnfetchedProduct অবজেক্টও রয়েছে। তারপরে, আপনি প্রতিটি 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-এ তালিকাভুক্ত একাধিক রেসপন্স কোডের মধ্যে একটি ফেরত দেয়। কেনাকাটার ফ্লো লঞ্চ করার সময় কোনও সমস্যা হয়নি কিনা তা
যাচাই করতে এই ফলাফল চেক করে দেখতে ভুলবেন না। BillingResponseCode
of OK সফল লঞ্চের ইঙ্গিত দেয়।
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() পদ্ধতি ব্যবহার করে ব্যবহারকারীদের কাছে এই তথ্য প্রকাশ করুন যে
অটোমেটিক সিদ্ধান্ত নেওয়ার প্রসেস ব্যবহার করে কোনও আইটেমের দাম পছন্দমতো সেট করা হয়েছে।
আপনাকে অবশ্যই 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 বিলিং লাইব্রেরি কানেকশন না থাকলে, 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 লাইব্রেরি থেকে 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() ব্যবহার করে
সাবস্ক্রিপশন অ্যাকনলেজ করতে পারবেন। প্রাথমিক সাবস্ক্রিপশন কেনার
জন্য সব অ্যাকনলেজমেন্ট প্রয়োজন। সাবস্ক্রিপশন রিনিউ করার জন্য
কোনও স্বীকৃতি দেওয়ার প্রয়োজন নেই। সাবস্ক্রিপশন কখন
অ্যাকনলেজ করতে হবে সেই সম্পর্কে আরও তথ্য পেতে, সাবস্ক্রিপশন বিক্রি করুন বিষয় দেখুন।
রিক্যাপ
এইসব ধাপের একটি সংক্ষিপ্তসার নিচে দেওয়া হল।
এনটাইটেলমেন্ট দেওয়ার আগে কেনাকাটা যাচাই করতে আপনার সুরক্ষিত ব্যাকএন্ডে কেনাকাটা পাঠান।
কেনাকাটা করে আপনার এনটাইটেলমেন্ট স্টোরেজ আপডেট করুন। কেনাকাটা পেন্ডিং অবস্থায় থাকলে, এনটাইটেলমেন্ট পেন্ডিং হিসেবে চিহ্নিত করা হয়েছে কিনা এবং ব্যবহারকারী এখনও সুবিধা পাননি কিনা তা নিশ্চিত করুন। সাজেস্ট করা হয় যে এই ধাপটি আপনার সুরক্ষিত ব্যাকএন্ডে সম্পূর্ণ করা হয় এবং এটি ধাপ ১-এ আপনার ব্যাকএন্ডে করা 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 বিলিং লাইব্রেরির 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 } });