[in_app_purchase] Fix upgrading subscription by deferred proration mode on android. (#4560)

This PR is for updating the bug of upgrading subscription by deferred mode on android, the purchaseStream of PurchaseStatus will return error.

Fixes [flutter/flutter#94439]
diff --git a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md
index 9bce54c..5c34de2 100644
--- a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md
+++ b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.2
+
+* Fixes the `purchaseStream` incorrectly reporting `PurchaseStatus.error` when user upgrades subscription by deferred proration mode.
+
 ## 0.2.1
 
 * Deprecated the `InAppPurchaseAndroidPlatformAddition.enablePendingPurchases()` method and `InAppPurchaseAndroidPlatformAddition.enablePendingPurchase` property. Since Google Play no longer accepts App submissions that don't support pending purchases it is no longer necessary to acknowledge this through code.
diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart
index 7deec6e..7c8ca52 100644
--- a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart
+++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart
@@ -270,13 +270,17 @@
     if (purchases.isNotEmpty) {
       return Future.wait(purchases);
     } else {
+      PurchaseStatus status = PurchaseStatus.error;
+      if (resultWrapper.responseCode == BillingResponse.userCanceled) {
+        status = PurchaseStatus.canceled;
+      } else if (resultWrapper.responseCode == BillingResponse.ok) {
+        status = PurchaseStatus.purchased;
+      }
       return [
         PurchaseDetails(
             purchaseID: '',
             productID: '',
-            status: resultWrapper.responseCode == BillingResponse.userCanceled
-                ? PurchaseStatus.canceled
-                : PurchaseStatus.error,
+            status: status,
             transactionDate: null,
             verificationData: PurchaseVerificationData(
                 localVerificationData: '',
diff --git a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml
index 63bfa13..4d88643 100644
--- a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml
+++ b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: An implementation for the Android platform of the Flutter `in_app_purchase` plugin. This uses the Android BillingClient APIs.
 repository: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase/in_app_purchase_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
-version: 0.2.1
+version: 0.2.2
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
diff --git a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart
index 9f00bc7..9c167e5 100644
--- a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart
+++ b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart
@@ -682,6 +682,51 @@
       GooglePlayPurchaseDetails result = await completer.future;
       expect(result.status, PurchaseStatus.canceled);
     });
+
+    test(
+        'should get purchased purchase status when upgrading subscription by deferred proration mode',
+        () async {
+      final SkuDetailsWrapper skuDetails = dummySkuDetails;
+      final String accountId = "hashedAccountId";
+      const String debugMessage = 'dummy message';
+      final BillingResponse sentCode = BillingResponse.ok;
+      final BillingResultWrapper expectedBillingResult = BillingResultWrapper(
+          responseCode: sentCode, debugMessage: debugMessage);
+      stubPlatform.addResponse(
+          name: launchMethodName,
+          value: buildBillingResultMap(expectedBillingResult),
+          additionalStepBeforeReturn: (_) {
+            // Mock java update purchase callback.
+            MethodCall call = MethodCall(kOnPurchasesUpdated, {
+              'billingResult': buildBillingResultMap(expectedBillingResult),
+              'responseCode': BillingResponseConverter().toJson(sentCode),
+              'purchasesList': []
+            });
+            iapAndroidPlatform.billingClient.callHandler(call);
+          });
+
+      Completer completer = Completer();
+      PurchaseDetails purchaseDetails;
+      Stream purchaseStream = iapAndroidPlatform.purchaseStream;
+      late StreamSubscription subscription;
+      subscription = purchaseStream.listen((_) {
+        purchaseDetails = _.first;
+        completer.complete(purchaseDetails);
+        subscription.cancel();
+      }, onDone: () {});
+      final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
+          productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
+          applicationUserName: accountId,
+          changeSubscriptionParam: ChangeSubscriptionParam(
+            oldPurchaseDetails: GooglePlayPurchaseDetails.fromPurchase(
+                dummyUnacknowledgedPurchase),
+            prorationMode: ProrationMode.deferred,
+          ));
+      await iapAndroidPlatform.buyNonConsumable(purchaseParam: purchaseParam);
+
+      PurchaseDetails result = await completer.future;
+      expect(result.status, PurchaseStatus.purchased);
+    });
   });
 
   group('complete purchase', () {