Skip to content

Upgrade/Downgrade not working for replacement mode chargeProratedPrice, withTimeProration, deferred #170658

@niilx

Description

@niilx

What package does this bug report belong to?

in_app_purchase

What target platforms are you seeing this bug on?

Android

Have you already upgraded your packages?

Yes

Dependency versions

pubspec.lock
name: example
description: A new Flutter application.
version: 1.0.0+1

environment:
  sdk: '>=3.4.1 <4.0.0'
  flutter: 3.32.4

dependencies:

  flutter:
    sdk: flutter

  app_settings: ^6.1.1
  facebook_app_events: ^0.20.1
  firebase_analytics: ^11.5.0
  firebase_auth: ^5.6.0
  firebase_core: ^3.14.0
  firebase_crashlytics: ^4.3.7
  firebase_messaging: ^15.2.7
  firebase_remote_config: ^5.4.5
  fl_chart: ^1.0.0
  flutter_cache_manager: ^3.4.1
  flutter_dotenv: ^5.2.1
  flutter_svg: ^2.1.0
  fluttertoast: ^8.2.12
  font_awesome_flutter: ^10.8.0
  fpdart: ^1.1.1
  get: ^4.7.2
  go_router: ^15.2.0
  google_sign_in: ^6.3.0
  highlight_text: ^1.8.0
  http: ^1.4.0
  intl: ^0.20.2
  in_app_purchase: ^3.2.3
  in_app_purchase_storekit: ^0.4.2
  in_app_purchase_android: ^0.4.0+2
  json_annotation: ^4.9.0
  just_audio: ^0.10.4
  package_info_plus: ^8.3.0
  path_provider: ^2.1.5
  flutter_volume_controller: ^1.3.3
  permission_handler: ^12.0.0+1

dev_dependencies:
  integration_test:
    sdk: flutter
  flutter_test:
    sdk: flutter
  flutter_lints: ^5.0.0
  build_runner: ^2.4.12
  json_serializable: ^6.8.0
  built_value_generator: ^8.9.2
  freezed: ^3.0.4
  path_provider_platform_interface: ^2.1.2

dependency_overrides:
  freezed_annotation: ^2.4.1

# The following section is specific to Flutter.
  path: any
flutter:
  fonts:
    - family: SarabunBold
      fonts:
        - asset: assets/fonts/Sarabun-Bold.ttf
    - family: SarabunRegular
      fonts:
        - asset: assets/fonts/Sarabun-Regular.ttf
    - family: SarabunSemiBold
      fonts:
        - asset: assets/fonts/Sarabun-SemiBold.ttf
    - family: SarabunLight
      fonts:
        - asset: assets/fonts/Sarabun-Light.ttf
    - family: SarabunThin
      fonts:
        - asset: assets/fonts/Sarabun-Thin.ttf
    - family: SarabunMedium
      fonts:
        - asset: assets/fonts/Sarabun-Medium.ttf
    - family: CustomIcons
      fonts:
        - asset: assets/fonts/CustomIcons.ttf


  assets:
    - assets/env/
    - assets/config/
    - assets/images/
    - assets/icon/



  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #   - images/a_dot_burr.jpeg
  #   - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:



  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

Steps to reproduce

  1. Create a subscription and create 4 base plan
  2. write code to subscription
  3. try to upgrade/change plan using ReplacementMode: chargeProratedPrice
    Code:
` final PurchaseDetails oldPurchaseDetails = purchasesOnline.firstWhere(
    (element) =>
        element.status == PurchaseStatus.purchased ||
        element.status == PurchaseStatus.restored,
  );
  //recordAnalyticsChangeSub(oldPurchaseDetails, product);
  if (oldPurchaseDetails is GooglePlayPurchaseDetails) {
    // For android we need to manually upgade/downgrade subscription
    PurchaseParam purchaseParam = GooglePlayPurchaseParam(
      productDetails: product,
      changeSubscriptionParam: ChangeSubscriptionParam(
        oldPurchaseDetails: oldPurchaseDetails,
        replacementMode: ReplacementMode.chargeProratedPrice, //only chargeFullPrice works
      ),
    );

    await InAppPurchase.instance
        .buyNonConsumable(purchaseParam: purchaseParam);

    changingPlan = false;
`

Expected results

Should show the dialog with prorated price and others info

Actual results

Getting this error:
Image

Code sample

Code sample
final PurchaseDetails oldPurchaseDetails = purchasesOnline.firstWhere(
    (element) =>
        element.status == PurchaseStatus.purchased ||
        element.status == PurchaseStatus.restored,
  );
  //recordAnalyticsChangeSub(oldPurchaseDetails, product);
  if (oldPurchaseDetails is GooglePlayPurchaseDetails) {
    // For android we need to manually upgade/downgrade subscription
    PurchaseParam purchaseParam = GooglePlayPurchaseParam(
      productDetails: product,
      changeSubscriptionParam: ChangeSubscriptionParam(
        oldPurchaseDetails: oldPurchaseDetails,
        replacementMode: ReplacementMode.chargeProratedPrice, //only chargeFullPrice works
      ),
    );

    await InAppPurchase.instance
        .buyNonConsumable(purchaseParam: purchaseParam);

    changingPlan = false;

Screenshots or Videos

Screenshot

Image

Logs

Logs
//flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
W/WindowOnBackDispatcher(19670): sendCancelIfRunning: isInProgress=false callback=io.flutter.embedding.android.FlutterActivity$1@56aad94
I/LogRocket(19670): [MemoryTracker] memory used: 7763520, max: 201326592, available percent: 0.9614381790161133
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): │ #0   PurchaseController.storeAvailable (package:example_call/controllers/purchase_controller.dart:191:12)
purchase_controller.dart:191
I/flutter (19670): │ #1   <asynchronous suspension>
I/flutter (19670): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 💡 Store available
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
W/WindowOnBackDispatcher(19670): sendCancelIfRunning: isInProgress=false callback=io.flutter.embedding.android.FlutterActivity$1@56aad94
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): │ #0   PurchaseController._checkPendingPurchase (package:example_call/controllers/purchase_controller.dart:215:14)
purchase_controller.dart:215
I/flutter (19670): │ #1   PurchaseController._purchaseEvent (package:example_call/controllers/purchase_controller.dart:207:11)
purchase_controller.dart:207
I/flutter (19670): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 🐛 PurchaseStatus.restored
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
D/SessionLifecycleClient(19670): Sending lifecycle 2 to service
D/SessionLifecycleService(19670): Activity backgrounding at 8001027
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): │ #0   PurchasedPackage.getPlanDetailsList (package:example_call/screen/subscription/purchased_package.dart:307:12)
purchased_package.dart:307
I/flutter (19670): │ #1   PurchasedPackage.build.<anonymous closure> (package:example_call/screen/subscription/purchased_package.dart:27:34)
purchased_package.dart:27
I/flutter (19670): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 🐛 • All from basic plan 
I/flutter (19670): │ 🐛 • Plus access to Chat AI
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
D/SessionLifecycleClient(19670): Sending lifecycle 1 to service
D/SessionLifecycleService(19670): Activity foregrounding at 8001081.
I/flutter (19670): ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 🐛 Not recording test & analytics api calls for path: /a2/pg
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
D/SessionLifecycleClient(19670): Sending lifecycle 2 to service
D/SessionLifecycleService(19670): Activity backgrounding at 8001202
I/flutter (19670): ┌────────────────────────────────────────────────────────────────├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): │ #0   PurchaseController.getVerifyPurchase.<anonymous closure> (package:example_call/controllers/purchase_controller.dart:601:18)
purchase_controller.dart:601
I/flutter (19670): │ #1   Right.match (package:fpdart/src/either.dart:530:14)
either.dart:530
I/flutter (19670): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 💡 Purchase List:::::
I/flutter (19670): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (19670): │ #0   PurchaseController.getVerifyPurchase.<anonymous closure> (package:example_call/controllers/purchase_controller.dart:602:18)
purchase_controller.dart:602
I/flutter (19670): │ #1   Right.match (package:fpdart/src/either.dart:530:14)
either.dart:530
I/flutter (19670): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (19670): │ 💡 [
I/flutter (19670): │ 💡   {
I/flutter (19670): │ 💡     "created_on": "2025-06-16T06:31:46.276221+00:00",

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.32.4, on macOS 14.6.1 23G93 darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[!] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS and macOS development.
      Download at: https://developer.apple.com/xcode/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.3)
[✓] VS Code (version 1.100.2)
[✓] Connected device (3 available)
[✓] Network resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    r: invalidIssue is closed as not valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions