[in_app_purchase] Fix incorrect json key in `queryPurchasesAsync` response (#6174)

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 6f47643..c369b8f 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.3+2
+
+* Fixes incorrect json key in `queryPurchasesAsync` that fixes restore purchases functionality.
+
 ## 0.2.3+1
 
 * Updates `json_serializable` to fix warnings in generated code.
diff --git a/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java b/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java
index ab12b2d..bdf52dc 100644
--- a/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java
+++ b/packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java
@@ -320,7 +320,7 @@
             // as success is implied by calling this callback.
             serialized.put("responseCode", BillingClient.BillingResponseCode.OK);
             serialized.put("billingResult", Translator.fromBillingResult(billingResult));
-            serialized.put("purchaseList", fromPurchasesList(purchasesList));
+            serialized.put("purchasesList", fromPurchasesList(purchasesList));
             result.success(serialized);
           }
         });
diff --git a/packages/in_app_purchase/in_app_purchase_android/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java b/packages/in_app_purchase/in_app_purchase_android/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java
index e99ff46..ffebb25 100644
--- a/packages/in_app_purchase/in_app_purchase_android/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java
+++ b/packages/in_app_purchase/in_app_purchase_android/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java
@@ -31,6 +31,7 @@
 import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.refEq;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -56,7 +57,9 @@
 import com.android.billingclient.api.Purchase;
 import com.android.billingclient.api.PurchaseHistoryRecord;
 import com.android.billingclient.api.PurchaseHistoryResponseListener;
+import com.android.billingclient.api.PurchasesResponseListener;
 import com.android.billingclient.api.QueryPurchaseHistoryParams;
+import com.android.billingclient.api.QueryPurchasesParams;
 import com.android.billingclient.api.SkuDetails;
 import com.android.billingclient.api.SkuDetailsParams;
 import com.android.billingclient.api.SkuDetailsResponseListener;
@@ -64,9 +67,12 @@
 import io.flutter.plugin.common.MethodCall;
 import io.flutter.plugin.common.MethodChannel;
 import io.flutter.plugin.common.MethodChannel.Result;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import org.json.JSONException;
 import org.junit.Before;
 import org.junit.Test;
@@ -74,6 +80,8 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
 public class MethodCallHandlerTest {
   private MethodCallHandlerImpl methodChannelHandler;
@@ -593,6 +601,58 @@
   }
 
   @Test
+  public void queryPurchases_returns_success() throws Exception {
+    establishConnectedBillingClient(null, null);
+
+    CountDownLatch lock = new CountDownLatch(1);
+    doAnswer(
+            new Answer() {
+              public Object answer(InvocationOnMock invocation) {
+                lock.countDown();
+                return null;
+              }
+            })
+        .when(result)
+        .success(any(HashMap.class));
+
+    ArgumentCaptor<PurchasesResponseListener> purchasesResponseListenerArgumentCaptor =
+        ArgumentCaptor.forClass(PurchasesResponseListener.class);
+    doAnswer(
+            new Answer() {
+              public Object answer(InvocationOnMock invocation) {
+                BillingResult.Builder resultBuilder =
+                    BillingResult.newBuilder()
+                        .setResponseCode(BillingClient.BillingResponseCode.OK)
+                        .setDebugMessage("hello message");
+                purchasesResponseListenerArgumentCaptor
+                    .getValue()
+                    .onQueryPurchasesResponse(resultBuilder.build(), new ArrayList<Purchase>());
+                return null;
+              }
+            })
+        .when(mockBillingClient)
+        .queryPurchasesAsync(
+            any(QueryPurchasesParams.class), purchasesResponseListenerArgumentCaptor.capture());
+
+    HashMap<String, Object> arguments = new HashMap<>();
+    arguments.put("skuType", SkuType.INAPP);
+    methodChannelHandler.onMethodCall(new MethodCall(QUERY_PURCHASES_ASYNC, arguments), result);
+
+    lock.await(5000, TimeUnit.MILLISECONDS);
+
+    verify(result, never()).error(any(), any(), any());
+
+    ArgumentCaptor<HashMap> hashMapCaptor = ArgumentCaptor.forClass(HashMap.class);
+    verify(result, times(1)).success(hashMapCaptor.capture());
+
+    HashMap<String, Object> map = hashMapCaptor.getValue();
+    assert (map.containsKey("responseCode"));
+    assert (map.containsKey("billingResult"));
+    assert (map.containsKey("purchasesList"));
+    assert ((int) map.get("responseCode") == 0);
+  }
+
+  @Test
   public void queryPurchaseHistoryAsync() {
     // Set up an established billing client and all our mocked responses
     establishConnectedBillingClient(null, null);
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 84bd36a..3b334a6 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/main/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.3+1
+version: 0.2.3+2
 
 environment:
   sdk: ">=2.14.0 <3.0.0"