2
votes

I have integrated the google play billing library inside my application to make a subscription purchase. It works well. The user receives purchase confirmation mail from google. confirmation mail from google

The active subscription is also visible in the play store subscriptions screen. Active subscription showing in play store

In the play console, the order detail said the user was successfully charged for a subscription. However, It gets canceled instantly. play console order history

I also check purchase acknowledgment, it returns true on every purchase. Initially, I thought there would be a mistake in my code. So, I tried various billing libraries from Github. The problem persists. In the end, I replaced the entire google billing library with Revenue cat. Followed every step described on Revenue cat documents. Still, getting the same issue.

Is there anything that I am missing to implement or done incorrectly? please help me out. Thank you

code for fetching available products:

 private fun fetchOffering(){
    Purchases.sharedInstance.getOfferingsWith({ error ->
        // An error occurred
        handleBillingError(requireActivity(), error)

    }) { offerings ->
        offerings.current?.availablePackages?.takeUnless { it.isNullOrEmpty() }?.let {
            // All packages from current offering

            if (it.isNotEmpty()){
                it.forEach { p: Package ->
                    offeringPackages.add(p)
                }
                isProductsAvailable = true
            }

            Log.d("RevenueCat", "fetchOffering: success: ${it.size}")

        }
    }
}

code for making purchase:

 private fun makePurchase(pack:Package){
    Purchases.sharedInstance.purchasePackageWith(
        requireActivity(),
        packageToPurchase = pack /* package from the fetched Offering*/,
        onError = {error, userCancelled ->
            Log.d("RevenueCat", "makePurchase: userCancelled: $userCancelled")
            handleBillingError(requireActivity(), error)
        },
        onSuccess = { product, purchaserInfo ->
            if (purchaserInfo.entitlements[REVENUE_ENTITLEMENT_ID_PRO]?.isActive == true) {
                Log.d("RevenueCat", "makePurchase: success: ${product.originalJson} ")
                afterPurchaseSuccessSetup()
            }
        })
}
1
can you share some Coding Files where you have work on subscription code?Yahya M
@YahyaM I have edited question. You can check it outVaibhav Patel

1 Answers

1
votes

I don't know where you are lagging, you should follow these steps to make subscribe purchase.

private lateinit var billingClient: BillingClient
private val skuListsubscribe = listOf("subscription_1", "subscription_2")

initialize billing client.

 private fun setupBillingClient() {
    billingClient = BillingClient.newBuilder(BaseActivity.mContext!!)
        .enablePendingPurchases()
        .setListener(this)
        .build()
    billingClient.startConnection(object : BillingClientStateListener {
        override fun onBillingSetupFinished(billingResult: BillingResult) {
            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
                // The BillingClient is ready. You can query purchases here.


                loadAllSKUsSubscription()

            }
        }

        override fun onBillingServiceDisconnected() {
            // Try to restart the connection on the next request to
            // Google Play by calling the startConnection() method.
            Log.e("TAG", "onBillingServiceDisconnected: ")
        }
    })
}

private fun loadAllSKUsSubscription() = if (billingClient.isReady) {
    val params = SkuDetailsParams
        .newBuilder()
        .setSkusList(skuListsubscribe)
        .setType(BillingClient.SkuType.SUBS)
        .build()

    billingClient.querySkuDetailsAsync(params) { billingResult, skuDetailsList ->
        // Process the result.
        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK && skuDetailsList!!.isNotEmpty()) {
            for (skuDetails in skuDetailsList) {
                if (skuDetails.sku == subscribtionId) {

                    tv_full_category_price.text = skuDetails.price
                    realAmountSubscription = skuDetails.price

                    rl_bestvalue_plan.setOnClickListener {
                        isInAppPurchase = false
                        isSubscribtion = true
                        val billingFlowParams = BillingFlowParams
                            .newBuilder()
                            .setSkuDetails(skuDetails)
                            .build()
                        billingClient.launchBillingFlow(requireActivity(), billingFlowParams)
                    }
                }
            }
        }
    }


} else {
    println("Billing Client not ready")
}

override purchase update method

override fun onPurchasesUpdated(
    billingResult: BillingResult,
    purchases: MutableList<Purchase>?,
) {

   

    if (billingResult?.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
        for (purchase in purchases) {

            acknowledgePurchase(purchase)

        }
    } else if (billingResult?.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {


        //logger("User Cancelled")
        //logger(billingResult?.debugMessage.toString())

  
    } else {
        //logger(billingResult?.debugMessage.toString())

    }
}

 private fun acknowledgePurchase(purchase: Purchase) {

    if (isSubscribtion) {

        handleNonConsumableProduct(purchase = purchase)
    } 
}

fun handleConsumableProduct(purchase: Purchase) {

    val consumeParams =
        ConsumeParams.newBuilder()
            .setPurchaseToken(purchase.purchaseToken)
            .build()

    billingClient.consumeAsync(consumeParams) { billingResult, purchaseToken ->

        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {

            if (isVisible && isAdded)
                Snackbar.MakeInternetSnackbar(BaseActivity.mContext!!,
                    subscription_fragment_indicator_layout,
                    "Purchased Successfully")

            InAppPaymentApi(realAmount.toString(), audio_id!!, purchase.purchaseToken)

        }
    }
}