Skip to main content
Solved

Three consumable products in my own layout ...

  • 16 July 2024
  • 5 replies
  • 74 views

Good afternoon,
Guys, please help me, I need an example code in Kotlin.
I have the simplest option: no authorization, no subscriptions, no Compose.
Only three products (Consumables), my own layout with three buttons (for each product).

How can I get the price of a product and setOnClickListener so that the process of purchasing this product begins?

 val tv_Crystals_100: TextView = findViewById(R.id.tv_Crystals_100)
 val tv_Crystals_200: TextView = findViewById(R.id.tv_Crystals_200)
 val tv_Crystals_500: TextView = findViewById(R.id.tv_Crystals_500)

 tv_Crystals_100.text = "__price_"
 tv_Crystals_100.setOnClickListener { ... }

 tv_Crystals_200.text = "__price_"
 tv_Crystals_200.setOnClickListener { ... }

 tv_Crystals_500.text = "__price_"
 tv_Crystals_500.setOnClickListener { ... }

Thanks a lot in advance
Denis

This post has been closed for comments

5 replies

Userlevel 5
Badge +9

Hi @Denis-44aa44,

We have an ongoing support ticket about this but I will also answer your question here.

To get the price of a product:

private fun fetchProductDetails() {
Purchases.sharedInstance.getProducts(productIds, object : ReceiveProductsCallback {
override fun onReceived(products: List<StoreProduct>) {
products.forEach { product ->
when (product.identifier) {
"your tvCrystals100 product" -> tvCrystals100.text = product.price
"your tvCrystals200 product" -> tvCrystals200.text = product.price
"your tvCrystals500 product" -> tvCrystals500.text = product.price
}
}
}

override fun onError(error: PurchasesError) {
// Handle error
Log.e("RevenueCat", "Error fetching products: ${error.message}")
}
})
}

To purchase products using setOnClickListener:

val tv_Crystals_100: TextView = findViewById(R.id.tv_btn_Buy_01)
val tv_Crystals_200: TextView = findViewById(R.id.tv_btn_Buy_02)
val tv_Crystals_500: TextView = findViewById(R.id.tv_btn_Buy_03)

tv_Crystals_100.text = "___"
tv_Crystals_100.setOnClickListener { purchaseProduct(<put your product ID here>) }

tv_Crystals_200.text = "___"
tv_Crystals_200.setOnClickListener { purchaseProduct(<put your product ID here>) }

tv_Crystals_500.text = "___"
tv_Crystals_500.setOnClickListener { purchaseProduct(<put your product ID here>) }


private fun purchaseProduct(productId: String) {
Purchases.sharedInstance.purchaseProduct(this, productId, object : PurchaseCompletedCallback {
override fun onCompleted(purchase: Purchase, customerInfo: CustomerInfo) {
// Handle successful purchase
}

override fun onError(error: PurchasesError, userCancelled: Boolean) {
// Handle purchase error
if (userCancelled) {
// The user cancelled the purchase
} else {
// The purchase experienced an error, handle it
}
}
})
}

 

Badge

Thank you very much for your help. But I still can't do it.

Android Studio states that purchaseProduct is already deprecated.

productId an error occurs that (Type mismatch, Required:
StoreProduct, Found: String)

Please help me

Badge

Thank you very much for your help.
It seems like I figured it out, but I had to replace something in your code.

Denis

Userlevel 5
Badge +9

Hi @Denis-44aa44,

Thanks for confirming you got it working! If you are able, please share what changes you had to make so that I can fix my original answer. If you are not able then no problem, I’m glad it’s working now.

Badge

Yes, of course, here is an example of code that works for me.
Let me remind you that I have the simplest option.
Three buttons, three products (Consumables), and my own layout.

1  Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.xxxxxxxxxxxxx)

Purchases.logLevel = LogLevel.DEBUG
Purchases.configure(PurchasesConfiguration.Builder(this, "goog_xxxxxxxxxxxxxxxxxxxxx").appUserID(null).build())

fetchProductDetails()
}

2  Kotlin

    private fun fetchProductDetails() {

val tv_btn_Buy_01: TextView = findViewById(R.id.tv_btn_Buy_01)
val tv_btn_Buy_02: TextView = findViewById(R.id.tv_btn_Buy_02)
val tv_btn_Buy_03: TextView = findViewById(R.id.tv_btn_Buy_03)


Purchases.sharedInstance.getProducts( productIds, object : GetStoreProductsCallback {

override fun onReceived(products: List<StoreProduct>) {
products.forEach { product ->
when (product.id) {

"crystals_100" -> { tv_btn_Buy_01.text = product.price.formatted; tv_btn_Buy_01.setOnClickListener { purchaseProduct( product.copyWithOfferingId(product.id) ) } }
"crystals_200" -> { tv_btn_Buy_02.text = product.price.formatted; tv_btn_Buy_02.setOnClickListener { purchaseProduct( product.copyWithOfferingId(product.id) ) } }
"crystals_500" -> { tv_btn_Buy_03.text = product.price.formatted; tv_btn_Buy_03.setOnClickListener { purchaseProduct( product.copyWithOfferingId(product.id) ) } }

}
}
}

override fun onError(error: PurchasesError) {

buildError(error.message)

with(error) {
when (code) {
PurchasesErrorCode.PurchaseNotAllowedError -> { .... }
.... -> { .... }
else -> { .... }
}

}
}


})
}

3  Kotlin

        private fun purchaseProduct(productId: StoreProduct) {   

Purchases.sharedInstance.purchaseWith(
PurchaseParams.Builder(this, productId).build(),
onError = { error, userCancelled ->
buildError(error.message)
},
onSuccess = { storeTransaction, customerInfo ->

when (productId.id) {
"crystals_100" -> {addPurchasedCrystals(100)}
"crystals_200" -> {addPurchasedCrystals(200)}
"crystals_500" -> {addPurchasedCrystals(500)}
}

}
)
}

 

If I have a mistake or something that can be improved, please write.

Now I'm sorting out errors when making a purchase.
And I don’t quite understand what and how errors need to be handled.
For example this: PurchasesErrorCode.OperationAlreadyInProgressError.

This parameter Purchases.logLevel = LogLevel.DEBUG is needed for debugging. What should this parameter be for shopping to work as usual?


Sincerely,
Denis