Skip to main content
Question

Need Solution for Managing Google Play Subscription Upgrades/Downgrades in Flutter with Paywall

  • September 9, 2025
  • 3 replies
  • 120 views

Forum|alt.badge.img

Hi, I’ve been using Paywall with Flutter, and it’s been great so far, but it doesn’t handle subscription upgrades/downgrades for Google Play, which is a major issue.

Without this essential feature, Paywall becomes almost unusable for managing multiple subscriptions on the Play Store.

Are there any solutions to make RevenueCat Paywall work for upgrades/downgrades with Google subscriptions in Flutter?

This post has been closed for comments

3 replies

guilherme
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • September 11, 2025

Hey ​@winterofcoming-203f8a ,

As you may have already seen, Google Play does not have an equivalent subscription group structure as Apple does to automatically handle this. You will need to handle the checking for a current subscription and the upgrading/downgrading to the new subscription within your app itself.

So in Flutter you’ll need to be passing a GoogleProductChangeInfo to purchasePackage or purchaseStoreProduct.

The GoogleProductChangeInfo is constructed by the old product ID and proration mode, similar to the native Android flow. Something like this (untested, but as an example):

// 1. Use PaywallView with listeners to capture paywall interactions:

PaywallView(
offering: yourOffering,
onPurchaseStarted: (Package rcPackage) {
// User selected a package - capture the selection here
print('User selected package: ${rcPackage.identifier}');
},
onPurchaseCompleted: (CustomerInfo customerInfo, StoreTransaction storeTransaction) {
// Purchase successful - handle upgrade logic here
_handlePurchaseCompleted(customerInfo, storeTransaction);
},
onPurchaseError: (PurchasesError error) {
// Handle purchase errors
print('Purchase error: ${error.message}');
},
)

// 2. Handle Google Play Upgrades with Proration. When you detect an upgrade scenario in onPurchaseStarted, use purchaseStoreProduct with GoogleProductChangeInfo:

void _handleUpgrade(Package selectedPackage, String oldProductId) async {
try {
final upgradeInfo = GoogleProductChangeInfo(
oldProductId,
prorationMode: GoogleProrationMode.immediateWithTimeProration, // or other modes
);

final purchaseResult = await Purchases.purchaseStoreProduct(
selectedPackage.storeProduct,
googleProductChangeInfo: upgradeInfo,
);

// Handle successful upgrade
print('Upgrade completed: ${purchaseResult.customerInfo}');
} catch (e) {
print('Upgrade failed: $e');
}
}

The Flutter | Displaying Paywalls section has more context on these listeners, and you can find an actual example in Flutter codebase example app here!
 

NOTE

When changing a subscription you must pass the old product ID (and optionally replacement/proration mode)

 

I hope this helps, but let me know if you have any further questions.


Forum|alt.badge.img

Thanks for the reply, I don't quite understand that when using paywall, all purchases are done inside the sdk, so how can I pass the old product ID into paywall?


guilherme
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • September 18, 2025

Hey ​@winterofcoming-203f8a, you cannot pass the old product ID into the paywall because the PaywallView doesn't expose that functionality.

The 2 best approaches as of now are:

  • handle upgrades/downgrades outside the paywall with a separate screen using purchaseStoreProduct with GoogleProductChangeInfo 
  • or structure your products as base plans within a single Google Play subscription (this allows automatic upgrades like iOS)

Having Google Play upgrade support for Paywalls is on our roadmap though, but no ETA as of yet. We're looking into solutions to make this work seamlessly.