Skip to main content
Solved

Custom purchase logic triggers unexpected “Confirm Plan” prompt and failed subscription


Forum|alt.badge.img

When I was originally developing using the PurchasesAreCompletedBy.REVENUECAT mode, everything worked fine.

However, since I needed to change the GoogleReplacementMode to DEFERRED, I had to switch to the PurchasesAreCompletedBy.MY_APP mode.

To support this, I passed a custom purchaseLogic to PaywallOptions via PaywallOptions.Builder.


But after switching to this approach, my subscription purchases started showing a “Confirm Plan” prompt, and the subscription would end up being automatically canceled.


Even after I manually called Purchases.sharedInstance.syncPurchases(), the issue still persisted.

Is there something wrong with my setup?

 


 

// Implementation of PurchaseLogic

override suspend fun performPurchase(
    activity: Activity,
    rcPackage: Package,
): PurchaseLogicResult {
    onPurchaseStarted(rcPackage)
    val purchaseParams = PurchaseParams.Builder(activity, rcPackage)
        .googleReplacementMode(GoogleReplacementMode.WITHOUT_PRORATION)
        .build()

    return try {
        val result = Purchases.sharedInstance.awaitPurchase(purchaseParams)
        onPurchaseCompleted(result.customerInfo, result.storeTransaction)        
        PurchaseLogicResult.Success
    } catch (e: PurchasesException) {
        when (e.code) {
            PurchasesErrorCode.PurchaseCancelledError -> {
                onPurchaseCancelled()
                PurchaseLogicResult.Cancellation
            }
            else -> {
                onPurchaseError(e.error)
                PurchaseLogicResult.Error(e.error)
            }
        }
    }
}

Paywall(
    options = PaywallOptions.Builder {
        viewModel.requestToDismissPage()
    }
        .setOffering(null)
        .setPurchaseLogic(purchaseLogic)
        .build()
)

 

Best answer by Jens

Ahh, now I get where the problem lies. Sorry for the confusion, I didn’t realize that this issue was related to the paywalls code. The problem with PurchasesAreCompletedBy.MY_APP is that it assumes you have your own purchasing logic which acknowledges the purchase with Google (step 7 of this list: https://developer.android.com/google/play/billing/security#verify). Because you set the flag like you did, RevenueCat is no longer acknowledging the purchase, that’s why it automatically gets cancelled.

I am checking with the team if there is another way to achieve what you want to achieve, because setting PurchasesAreCompletedBy.MY_APP is definitely not the right solution.

One thing that does come to mind, though: In Google Play Console, you can set the default replacement mode on a per-base plan basis (field “Customer base plan and offer changes”). So it might be sufficient to just set it to the right replacement mode in Google Play Console so that you don’t have to pass in a PurchaseParam when making the purchase with the RevenueCat SDK.

 

View original
Did this post help you find an answer to your question?
This post has been closed for comments

4 replies

Jens
RevenueCat Staff
Forum|alt.badge.img+7
  • RevenueCat Staff
  • 187 replies
  • April 18, 2025

Why do you think that using the DEFERRED replacement mode requires you to switch to PurchasesAreCompletedBy.MY_APP? That should not be required, and the fact that you switched probably is causing these issues right now.


Forum|alt.badge.img
  • Author
  • New Member
  • 3 replies
  • April 18, 2025
Jens wrote:

Why do you think that using the DEFERRED replacement mode requires you to switch to PurchasesAreCompletedBy.MY_APP? That should not be required, and the fact that you switched probably is causing these issues right now.



Based on the information I found, in order to switch to DEFERRED mode, I need to pass a PurchaseParams instance when calling the purchase function.
From what I’ve seen in the PaywallViewModel implementation, it seems that the only way to provide a custom PurchaseParams when calling the purchase function is by switching to PurchasesAreCompletedBy.MY_APP.


Jens
RevenueCat Staff
Forum|alt.badge.img+7
  • RevenueCat Staff
  • 187 replies
  • Answer
  • April 18, 2025

Ahh, now I get where the problem lies. Sorry for the confusion, I didn’t realize that this issue was related to the paywalls code. The problem with PurchasesAreCompletedBy.MY_APP is that it assumes you have your own purchasing logic which acknowledges the purchase with Google (step 7 of this list: https://developer.android.com/google/play/billing/security#verify). Because you set the flag like you did, RevenueCat is no longer acknowledging the purchase, that’s why it automatically gets cancelled.

I am checking with the team if there is another way to achieve what you want to achieve, because setting PurchasesAreCompletedBy.MY_APP is definitely not the right solution.

One thing that does come to mind, though: In Google Play Console, you can set the default replacement mode on a per-base plan basis (field “Customer base plan and offer changes”). So it might be sufficient to just set it to the right replacement mode in Google Play Console so that you don’t have to pass in a PurchaseParam when making the purchase with the RevenueCat SDK.

 


Forum|alt.badge.img
  • Author
  • New Member
  • 3 replies
  • April 19, 2025

@Jens  Got it, I understand now. Sorry that my earlier explanation wasn’t clear and caused confusion. I really appreciate your suggestion! Thx!


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings