Skip to main content
Solved

Paywall getting dismissed automatically after the purchase

  • May 13, 2025
  • 1 reply
  • 18 views

Forum|alt.badge.img

I am using Jetpack Compose in my Android app. I have created a composable screen in which based on the user (Free or Premium), I show the paywall. Now, when the user makes a successful purchase, my composable screen is getting dismissed automatically. I am using the below code if the user is not premium.
 

PaywallDialog(
        PaywallDialogOptions.Builder()
            .setOffering(currentOffering)
            .setFontProvider(CustomFontProvider(RobotoFontFamily))
            .setDismissRequest { onNavigateUp() }
            .setListener(
                object : PaywallListener {
                    override fun onPurchaseCompleted(
                        customerInfo: CustomerInfo,
                        storeTransaction: StoreTransaction
                    ) {
                        onPurchaseOrRestoreCompleted()
                    }

                    override fun onRestoreCompleted(customerInfo: CustomerInfo) {
                        onPurchaseOrRestoreCompleted()
                    }
                }
            )
            .build()
    )

Now, the problem is once the purchase is done, I am updating the user status from free to premium and based on that I want to show the plan information and other details on the same screen. But, as soon as the purchase is done, the user is redirected back to the previous screen. I don’t want that behavior.

Is this possible or am I missing something?

Best answer by guilherme

Hey ​@mehul4795 ,

from your code snippet I believe the culprit is: 

.setDismissRequest { onNavigateUp() }

mixed with the internal behavior of the PaywallDialog.

The PaywallDialog logic calls closePaywall() when a purchase or restore is completed (source), which in turn triggers the dialog (sourcedismissRequest. My assumption here is that since you're navigating away there, the screen pops.

Instead of navigating in dismissRequest, you can control the dialog’s visibility using a local state flag, like showDialog.

Here’s a pattern that keeps your screen in place and just hides the dialog after purchase:

var showDialog by remember { mutableStateOf(!isPremiumUser) } //or similar

if (showDialog) {
    PaywallDialog(
        PaywallDialogOptions.Builder()
            .setOffering(currentOffering)
            .setDismissRequest { showDialog = false } // Only dismiss the dialog
            .setListener(object : PaywallListener {
                override fun onPurchaseCompleted(
                    customerInfo: CustomerInfo,
                    storeTransaction: StoreTransaction
                ) {
                    onPurchaseOrRestoreCompleted()
                    showDialog = false // Hide dialog, stay on screen
                }

                override fun onRestoreCompleted(customerInfo: CustomerInfo) {
                    onPurchaseOrRestoreCompleted()
                    showDialog = false
                }
            })
            .build()
    )
}

This way, you should see:

  • the dialog still auto-dismisses after purchase (as expected);

  • instead of navigating away, you just hide the dialog with showDialog = false;

  • your screen stays active, so you can show plan info, premium features, etc.

Alternatively, if you want more flexibility, you can use the Paywall composable (docs here under the Manually tab) instead of the dialog. Something like this should do the trick:

if (showPaywall) { //a flag to control this visibility
    Paywall(
        PaywallOptions.Builder()
            .setOffering(currentOffering)
            .setListener(object : PaywallListener {
                override fun onPurchaseCompleted(customerInfo: CustomerInfo, storeTransaction: StoreTransaction) {
                    onPurchaseOrRestoreCompleted()
                    showPaywall = false
                }

                override fun onRestoreCompleted(customerInfo: CustomerInfo) {
                    onPurchaseOrRestoreCompleted()
                    showPaywall = false
                }
            })
            .build()
    )
}

This gives you full control over how the paywall appears and what happens afterward,  no dialogs, no auto-dismiss, just Compose state.

 

Best,

Gui

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

1 reply

guilherme
RevenueCat Staff
Forum|alt.badge.img+3
  • RevenueCat Staff
  • 48 replies
  • Answer
  • May 15, 2025

Hey ​@mehul4795 ,

from your code snippet I believe the culprit is: 

.setDismissRequest { onNavigateUp() }

mixed with the internal behavior of the PaywallDialog.

The PaywallDialog logic calls closePaywall() when a purchase or restore is completed (source), which in turn triggers the dialog (sourcedismissRequest. My assumption here is that since you're navigating away there, the screen pops.

Instead of navigating in dismissRequest, you can control the dialog’s visibility using a local state flag, like showDialog.

Here’s a pattern that keeps your screen in place and just hides the dialog after purchase:

var showDialog by remember { mutableStateOf(!isPremiumUser) } //or similar

if (showDialog) {
    PaywallDialog(
        PaywallDialogOptions.Builder()
            .setOffering(currentOffering)
            .setDismissRequest { showDialog = false } // Only dismiss the dialog
            .setListener(object : PaywallListener {
                override fun onPurchaseCompleted(
                    customerInfo: CustomerInfo,
                    storeTransaction: StoreTransaction
                ) {
                    onPurchaseOrRestoreCompleted()
                    showDialog = false // Hide dialog, stay on screen
                }

                override fun onRestoreCompleted(customerInfo: CustomerInfo) {
                    onPurchaseOrRestoreCompleted()
                    showDialog = false
                }
            })
            .build()
    )
}

This way, you should see:

  • the dialog still auto-dismisses after purchase (as expected);

  • instead of navigating away, you just hide the dialog with showDialog = false;

  • your screen stays active, so you can show plan info, premium features, etc.

Alternatively, if you want more flexibility, you can use the Paywall composable (docs here under the Manually tab) instead of the dialog. Something like this should do the trick:

if (showPaywall) { //a flag to control this visibility
    Paywall(
        PaywallOptions.Builder()
            .setOffering(currentOffering)
            .setListener(object : PaywallListener {
                override fun onPurchaseCompleted(customerInfo: CustomerInfo, storeTransaction: StoreTransaction) {
                    onPurchaseOrRestoreCompleted()
                    showPaywall = false
                }

                override fun onRestoreCompleted(customerInfo: CustomerInfo) {
                    onPurchaseOrRestoreCompleted()
                    showPaywall = false
                }
            })
            .build()
    )
}

This gives you full control over how the paywall appears and what happens afterward,  no dialogs, no auto-dismiss, just Compose state.

 

Best,

Gui


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