From a53e1fde8ac8be8fee764f1828fa3ba073df6f6e Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Fri, 13 May 2022 11:21:25 +0300 Subject: [PATCH 1/9] Added ability to to purchase multiple quantity of one product --- .../in_app_purchase_storekit_platform.dart | 8 +-- .../test/fakes/fake_storekit_platform.dart | 39 ++++++++----- ...n_app_purchase_storekit_platform_test.dart | 58 +++++++++++++++++++ 3 files changed, 85 insertions(+), 20 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart index 629355d12d4c..86c4591e34fb 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart @@ -68,10 +68,10 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { Future isAvailable() => SKPaymentQueueWrapper.canMakePayments(); @override - Future buyNonConsumable({required PurchaseParam purchaseParam}) async { + Future buyNonConsumable({required PurchaseParam purchaseParam, int quantity = 1}) async { await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, - quantity: 1, + quantity: quantity, applicationUsername: purchaseParam.applicationUserName, simulatesAskToBuyInSandbox: purchaseParam is AppStorePurchaseParam && purchaseParam.simulatesAskToBuyInSandbox, @@ -82,9 +82,9 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @override Future buyConsumable( - {required PurchaseParam purchaseParam, bool autoConsume = true}) { + {required PurchaseParam purchaseParam, bool autoConsume = true, int quantity = 1}) { assert(autoConsume == true, 'On iOS, we should always auto consume'); - return buyNonConsumable(purchaseParam: purchaseParam); + return buyNonConsumable(purchaseParam: purchaseParam, quantity: quantity); } @override diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart index 7c543750c25e..09048b3694b9 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart @@ -56,20 +56,21 @@ class FakeStoreKitPlatform { queueIsActive = false; } - SKPaymentTransactionWrapper createPendingTransaction(String id) { + SKPaymentTransactionWrapper createPendingTransaction(String id, {int quantity = 1}) { return SKPaymentTransactionWrapper( transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: id), + payment: SKPaymentWrapper(productIdentifier: id, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.purchasing, transactionTimeStamp: 123123.121, error: null, - originalTransaction: null); + originalTransaction: null, + ); } SKPaymentTransactionWrapper createPurchasedTransaction( - String productId, String transactionId) { + String productId, String transactionId, {int quantity = 1}) { return SKPaymentTransactionWrapper( - payment: SKPaymentWrapper(productIdentifier: productId), + payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.purchased, transactionTimeStamp: 123123.121, transactionIdentifier: transactionId, @@ -77,10 +78,10 @@ class FakeStoreKitPlatform { originalTransaction: null); } - SKPaymentTransactionWrapper createFailedTransaction(String productId) { + SKPaymentTransactionWrapper createFailedTransaction(String productId, {int quantity = 1}) { return SKPaymentTransactionWrapper( transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: productId), + payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.failed, transactionTimeStamp: 123123.121, error: const SKError( @@ -91,10 +92,10 @@ class FakeStoreKitPlatform { } SKPaymentTransactionWrapper createCanceledTransaction( - String productId, int errorCode) { + String productId, int errorCode, {int quantity = 1}) { return SKPaymentTransactionWrapper( transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: productId), + payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.failed, transactionTimeStamp: 123123.121, error: SKError( @@ -105,9 +106,9 @@ class FakeStoreKitPlatform { } SKPaymentTransactionWrapper createRestoredTransaction( - String productId, String transactionId) { + String productId, String transactionId, {int quantity = 1}) { return SKPaymentTransactionWrapper( - payment: SKPaymentWrapper(productIdentifier: productId), + payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.restored, transactionTimeStamp: 123123.121, transactionIdentifier: transactionId, @@ -166,25 +167,29 @@ class FakeStoreKitPlatform { return Future.sync(() {}); case '-[InAppPurchasePlugin addPayment:result:]': final String id = call.arguments['productIdentifier'] as String; + int quantity = call.arguments['quantity'] as int; final SKPaymentTransactionWrapper transaction = - createPendingTransaction(id); + createPendingTransaction(id, quantity: quantity); + transactions.add(transaction); InAppPurchaseStoreKitPlatform.observer.updatedTransactions( transactions: [transaction]); sleep(const Duration(milliseconds: 30)); if (testTransactionFail) { final SKPaymentTransactionWrapper transactionFailed = - createFailedTransaction(id); + createFailedTransaction(id, quantity: quantity); InAppPurchaseStoreKitPlatform.observer.updatedTransactions( transactions: [transactionFailed]); } else if (testTransactionCancel > 0) { final SKPaymentTransactionWrapper transactionCanceled = - createCanceledTransaction(id, testTransactionCancel); + createCanceledTransaction(id, testTransactionCancel, + quantity: quantity); InAppPurchaseStoreKitPlatform.observer.updatedTransactions( transactions: [transactionCanceled]); } else { final SKPaymentTransactionWrapper transactionFinished = createPurchasedTransaction( - id, transaction.transactionIdentifier ?? ''); + id, transaction.transactionIdentifier ?? '', + quantity: quantity); InAppPurchaseStoreKitPlatform.observer.updatedTransactions( transactions: [transactionFinished]); } @@ -192,7 +197,9 @@ class FakeStoreKitPlatform { case '-[InAppPurchasePlugin finishTransaction:result:]': finishedTransactions.add(createPurchasedTransaction( call.arguments['productIdentifier'] as String, - call.arguments['transactionIdentifier'] as String)); + call.arguments['transactionIdentifier'] as String, + quantity: transactions.first.payment.quantity + )); break; case '-[SKPaymentQueue startObservingTransactionQueue]': queueIsActive = true; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart index e92d8487ed93..206624435fd3 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart @@ -427,6 +427,64 @@ void main() { final PurchaseStatus purchaseStatus = await completer.future; expect(purchaseStatus, PurchaseStatus.canceled); }); + + test('buying non consumable, should be able to purchase multiple quantity of one product', () async { + final List details = []; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; + late StreamSubscription> subscription; + subscription = stream.listen((List purchaseDetailsList) { + details.addAll(purchaseDetailsList); + for (final PurchaseDetails purchaseDetails in purchaseDetailsList) { + if (purchaseDetails.pendingCompletePurchase) { + iapStoreKitPlatform.completePurchase(purchaseDetails); + completer.complete(details); + subscription.cancel(); + } + } + }); + final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( + productDetails: + AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyNonConsumable( + purchaseParam: purchaseParam, + quantity: 5 + ); + await completer.future; + expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); + }); + + test('buying consumable, should be able to purchase multiple quantity of one product', () async { + final List details = []; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; + late StreamSubscription> subscription; + subscription = stream.listen((List purchaseDetailsList) { + details.addAll(purchaseDetailsList); + for (final PurchaseDetails purchaseDetails in purchaseDetailsList) { + if (purchaseDetails.pendingCompletePurchase) { + iapStoreKitPlatform.completePurchase(purchaseDetails); + completer.complete(details); + subscription.cancel(); + } + } + }); + final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( + productDetails: + AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyConsumable( + purchaseParam: purchaseParam, + quantity: 5 + ); + await completer.future; + expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); + }); }); group('complete purchase', () { From 03b6758bef827fd9903fa27b088b05c4b76cfc96 Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Mon, 16 May 2022 14:10:29 +0300 Subject: [PATCH 2/9] Moved the quantity param the AppStorePurchaseParam --- .../lib/src/in_app_purchase_storekit_platform.dart | 8 ++++---- .../lib/src/types/app_store_purchase_param.dart | 4 ++++ .../test/fakes/fake_storekit_platform.dart | 2 +- .../test/in_app_purchase_storekit_platform_test.dart | 8 ++++---- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart index 86c4591e34fb..6ecb378484e4 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart @@ -68,10 +68,10 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { Future isAvailable() => SKPaymentQueueWrapper.canMakePayments(); @override - Future buyNonConsumable({required PurchaseParam purchaseParam, int quantity = 1}) async { + Future buyNonConsumable({required PurchaseParam purchaseParam}) async { await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, - quantity: quantity, + quantity: purchaseParam is AppStorePurchaseParam ? purchaseParam.quantity : 1, applicationUsername: purchaseParam.applicationUserName, simulatesAskToBuyInSandbox: purchaseParam is AppStorePurchaseParam && purchaseParam.simulatesAskToBuyInSandbox, @@ -82,9 +82,9 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { @override Future buyConsumable( - {required PurchaseParam purchaseParam, bool autoConsume = true, int quantity = 1}) { + {required PurchaseParam purchaseParam, bool autoConsume = true}) { assert(autoConsume == true, 'On iOS, we should always auto consume'); - return buyNonConsumable(purchaseParam: purchaseParam, quantity: quantity); + return buyNonConsumable(purchaseParam: purchaseParam); } @override diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart index b2d8eea9d791..a789854fb2ad 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart @@ -12,6 +12,7 @@ class AppStorePurchaseParam extends PurchaseParam { AppStorePurchaseParam({ required ProductDetails productDetails, String? applicationUserName, + this.quantity = 1, this.simulatesAskToBuyInSandbox = false, }) : super( productDetails: productDetails, @@ -28,4 +29,7 @@ class AppStorePurchaseParam extends PurchaseParam { /// /// See also [SKPaymentWrapper.simulatesAskToBuyInSandbox]. final bool simulatesAskToBuyInSandbox; + + /// Quantity of the product user requested to buy + int quantity; } diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart index 09048b3694b9..da81e88847be 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart @@ -167,7 +167,7 @@ class FakeStoreKitPlatform { return Future.sync(() {}); case '-[InAppPurchasePlugin addPayment:result:]': final String id = call.arguments['productIdentifier'] as String; - int quantity = call.arguments['quantity'] as int; + final int quantity = call.arguments['quantity'] as int; final SKPaymentTransactionWrapper transaction = createPendingTransaction(id, quantity: quantity); transactions.add(transaction); diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart index 206624435fd3..2a1774e60a58 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart @@ -448,10 +448,10 @@ void main() { final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( productDetails: AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + quantity: 5, applicationUserName: 'appName'); await iapStoreKitPlatform.buyNonConsumable( - purchaseParam: purchaseParam, - quantity: 5 + purchaseParam: purchaseParam ); await completer.future; expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); @@ -477,10 +477,10 @@ void main() { final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( productDetails: AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + quantity: 5, applicationUserName: 'appName'); await iapStoreKitPlatform.buyConsumable( - purchaseParam: purchaseParam, - quantity: 5 + purchaseParam: purchaseParam ); await completer.future; expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); From 43cae149cac9a9a629c7930f6a6a6b851afa11c2 Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Thu, 19 May 2022 13:51:40 +0300 Subject: [PATCH 3/9] Added a version update in pubspec.yaml and a CHANGELOG entry. Corrected formatting in the tests. --- .../in_app_purchase_storekit/CHANGELOG.md | 4 +++ .../in_app_purchase_storekit/pubspec.yaml | 2 +- ...n_app_purchase_storekit_platform_test.dart | 26 +++++++++---------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md index aba1d6ed3555..734cc039a078 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0+8 + +* Added ability to purchase mutliple quanitity of one product + ## 0.3.0+7 * Minor fixes for new analysis options. diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml index 235d491fbff0..ebd5e55acdad 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml @@ -2,7 +2,7 @@ name: in_app_purchase_storekit description: An implementation for the iOS platform of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework. repository: https://github.com/flutter/plugins/tree/main/packages/in_app_purchase/in_app_purchase_storekit issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 0.3.0+7 +version: 0.3.0+8 environment: sdk: ">=2.14.0 <3.0.0" diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart index 2a1774e60a58..841023eddad5 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart @@ -430,10 +430,8 @@ void main() { test('buying non consumable, should be able to purchase multiple quantity of one product', () async { final List details = []; - final Completer> completer = - Completer>(); - final Stream> stream = - iapStoreKitPlatform.purchaseStream; + final Completer> completer = Completer>(); + final Stream> stream = iapStoreKitPlatform.purchaseStream; late StreamSubscription> subscription; subscription = stream.listen((List purchaseDetailsList) { details.addAll(purchaseDetailsList); @@ -445,11 +443,12 @@ void main() { } } }); + final AppStoreProductDetails productDetails = AppStoreProductDetails.fromSKProduct(dummyProductWrapper); final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( - productDetails: - AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + productDetails: productDetails, quantity: 5, - applicationUserName: 'appName'); + applicationUserName: 'appName' + ); await iapStoreKitPlatform.buyNonConsumable( purchaseParam: purchaseParam ); @@ -459,10 +458,8 @@ void main() { test('buying consumable, should be able to purchase multiple quantity of one product', () async { final List details = []; - final Completer> completer = - Completer>(); - final Stream> stream = - iapStoreKitPlatform.purchaseStream; + final Completer> completer = Completer>(); + final Stream> stream = iapStoreKitPlatform.purchaseStream; late StreamSubscription> subscription; subscription = stream.listen((List purchaseDetailsList) { details.addAll(purchaseDetailsList); @@ -474,11 +471,12 @@ void main() { } } }); + final AppStoreProductDetails productDetails = AppStoreProductDetails.fromSKProduct(dummyProductWrapper); final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( - productDetails: - AppStoreProductDetails.fromSKProduct(dummyProductWrapper), + productDetails: productDetails, quantity: 5, - applicationUserName: 'appName'); + applicationUserName: 'appName' + ); await iapStoreKitPlatform.buyConsumable( purchaseParam: purchaseParam ); From d4b97de52b491af576b6166c46aa95a45d0ac584 Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Wed, 1 Jun 2022 21:00:44 +0300 Subject: [PATCH 4/9] Applied the patch to make the formatter happy. --- .../lib/src/in_app_purchase_storekit_platform.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart index 6ecb378484e4..f81b36699834 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/in_app_purchase_storekit_platform.dart @@ -71,7 +71,8 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform { Future buyNonConsumable({required PurchaseParam purchaseParam}) async { await _skPaymentQueueWrapper.addPayment(SKPaymentWrapper( productIdentifier: purchaseParam.productDetails.id, - quantity: purchaseParam is AppStorePurchaseParam ? purchaseParam.quantity : 1, + quantity: + purchaseParam is AppStorePurchaseParam ? purchaseParam.quantity : 1, applicationUsername: purchaseParam.applicationUserName, simulatesAskToBuyInSandbox: purchaseParam is AppStorePurchaseParam && purchaseParam.simulatesAskToBuyInSandbox, From 8164f9c996ff6179067fe4ff7d8b0ff316f9157a Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Wed, 1 Jun 2022 21:33:53 +0300 Subject: [PATCH 5/9] Applied changes suggested by the formatter. --- .../test/fakes/fake_storekit_platform.dart | 42 ++++++++++------- ...n_app_purchase_storekit_platform_test.dart | 46 +++++++++++-------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart index da81e88847be..e987a5ceac8c 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/fakes/fake_storekit_platform.dart @@ -56,21 +56,24 @@ class FakeStoreKitPlatform { queueIsActive = false; } - SKPaymentTransactionWrapper createPendingTransaction(String id, {int quantity = 1}) { + SKPaymentTransactionWrapper createPendingTransaction(String id, + {int quantity = 1}) { return SKPaymentTransactionWrapper( - transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: id, quantity: quantity), - transactionState: SKPaymentTransactionStateWrapper.purchasing, - transactionTimeStamp: 123123.121, - error: null, - originalTransaction: null, + transactionIdentifier: '', + payment: SKPaymentWrapper(productIdentifier: id, quantity: quantity), + transactionState: SKPaymentTransactionStateWrapper.purchasing, + transactionTimeStamp: 123123.121, + error: null, + originalTransaction: null, ); } SKPaymentTransactionWrapper createPurchasedTransaction( - String productId, String transactionId, {int quantity = 1}) { + String productId, String transactionId, + {int quantity = 1}) { return SKPaymentTransactionWrapper( - payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), + payment: + SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.purchased, transactionTimeStamp: 123123.121, transactionIdentifier: transactionId, @@ -78,10 +81,12 @@ class FakeStoreKitPlatform { originalTransaction: null); } - SKPaymentTransactionWrapper createFailedTransaction(String productId, {int quantity = 1}) { + SKPaymentTransactionWrapper createFailedTransaction(String productId, + {int quantity = 1}) { return SKPaymentTransactionWrapper( transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), + payment: + SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.failed, transactionTimeStamp: 123123.121, error: const SKError( @@ -92,10 +97,12 @@ class FakeStoreKitPlatform { } SKPaymentTransactionWrapper createCanceledTransaction( - String productId, int errorCode, {int quantity = 1}) { + String productId, int errorCode, + {int quantity = 1}) { return SKPaymentTransactionWrapper( transactionIdentifier: '', - payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), + payment: + SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.failed, transactionTimeStamp: 123123.121, error: SKError( @@ -106,9 +113,11 @@ class FakeStoreKitPlatform { } SKPaymentTransactionWrapper createRestoredTransaction( - String productId, String transactionId, {int quantity = 1}) { + String productId, String transactionId, + {int quantity = 1}) { return SKPaymentTransactionWrapper( - payment: SKPaymentWrapper(productIdentifier: productId, quantity: quantity), + payment: + SKPaymentWrapper(productIdentifier: productId, quantity: quantity), transactionState: SKPaymentTransactionStateWrapper.restored, transactionTimeStamp: 123123.121, transactionIdentifier: transactionId, @@ -198,8 +207,7 @@ class FakeStoreKitPlatform { finishedTransactions.add(createPurchasedTransaction( call.arguments['productIdentifier'] as String, call.arguments['transactionIdentifier'] as String, - quantity: transactions.first.payment.quantity - )); + quantity: transactions.first.payment.quantity)); break; case '-[SKPaymentQueue startObservingTransactionQueue]': queueIsActive = true; diff --git a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart index 841023eddad5..852599ac3670 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/test/in_app_purchase_storekit_platform_test.dart @@ -428,10 +428,14 @@ void main() { expect(purchaseStatus, PurchaseStatus.canceled); }); - test('buying non consumable, should be able to purchase multiple quantity of one product', () async { + test( + 'buying non consumable, should be able to purchase multiple quantity of one product', + () async { final List details = []; - final Completer> completer = Completer>(); - final Stream> stream = iapStoreKitPlatform.purchaseStream; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; late StreamSubscription> subscription; subscription = stream.listen((List purchaseDetailsList) { details.addAll(purchaseDetailsList); @@ -443,23 +447,26 @@ void main() { } } }); - final AppStoreProductDetails productDetails = AppStoreProductDetails.fromSKProduct(dummyProductWrapper); + final AppStoreProductDetails productDetails = + AppStoreProductDetails.fromSKProduct(dummyProductWrapper); final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( productDetails: productDetails, quantity: 5, - applicationUserName: 'appName' - ); - await iapStoreKitPlatform.buyNonConsumable( - purchaseParam: purchaseParam - ); + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyNonConsumable(purchaseParam: purchaseParam); await completer.future; - expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); + expect( + fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); }); - test('buying consumable, should be able to purchase multiple quantity of one product', () async { + test( + 'buying consumable, should be able to purchase multiple quantity of one product', + () async { final List details = []; - final Completer> completer = Completer>(); - final Stream> stream = iapStoreKitPlatform.purchaseStream; + final Completer> completer = + Completer>(); + final Stream> stream = + iapStoreKitPlatform.purchaseStream; late StreamSubscription> subscription; subscription = stream.listen((List purchaseDetailsList) { details.addAll(purchaseDetailsList); @@ -471,17 +478,16 @@ void main() { } } }); - final AppStoreProductDetails productDetails = AppStoreProductDetails.fromSKProduct(dummyProductWrapper); + final AppStoreProductDetails productDetails = + AppStoreProductDetails.fromSKProduct(dummyProductWrapper); final AppStorePurchaseParam purchaseParam = AppStorePurchaseParam( productDetails: productDetails, quantity: 5, - applicationUserName: 'appName' - ); - await iapStoreKitPlatform.buyConsumable( - purchaseParam: purchaseParam - ); + applicationUserName: 'appName'); + await iapStoreKitPlatform.buyConsumable(purchaseParam: purchaseParam); await completer.future; - expect(fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); + expect( + fakeStoreKitPlatform.finishedTransactions.first.payment.quantity, 5); }); }); From d1d3816d5c65a8247b49b6654ac52cf3d7c2d752 Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Thu, 9 Jun 2022 09:14:39 +0300 Subject: [PATCH 6/9] Updated the version number to 0.3.1 --- packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md | 2 +- packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md index 734cc039a078..cfbd17d67787 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.3.0+8 +## 0.3.1 * Added ability to purchase mutliple quanitity of one product diff --git a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml index ebd5e55acdad..73d816517299 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_storekit/pubspec.yaml @@ -2,7 +2,7 @@ name: in_app_purchase_storekit description: An implementation for the iOS platform of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework. repository: https://github.com/flutter/plugins/tree/main/packages/in_app_purchase/in_app_purchase_storekit issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22 -version: 0.3.0+8 +version: 0.3.1 environment: sdk: ">=2.14.0 <3.0.0" From 4dba2408a5b5ee729589afb34778e81b030eeb5e Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 22 Jun 2022 11:35:26 -0400 Subject: [PATCH 7/9] Fix CHANGELOG to match style guide --- packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md index 26eb7d7aba32..445fdb6aa491 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_storekit/CHANGELOG.md @@ -1,6 +1,6 @@ ## 0.3.1 -* Added ability to purchase mutliple quanitity of one product +* Adds ability to purchase more than one of a product. ## 0.3.0+10 From 402eceea17cb25162c73f68a8c33c279fc5229f7 Mon Sep 17 00:00:00 2001 From: stuartmorgan Date: Wed, 22 Jun 2022 11:36:21 -0400 Subject: [PATCH 8/9] Update packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart Co-authored-by: Chris Yang --- .../lib/src/types/app_store_purchase_param.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart index a789854fb2ad..0cc8ef7b21bb 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart @@ -30,6 +30,6 @@ class AppStorePurchaseParam extends PurchaseParam { /// See also [SKPaymentWrapper.simulatesAskToBuyInSandbox]. final bool simulatesAskToBuyInSandbox; - /// Quantity of the product user requested to buy + /// Quantity of the product user requested to buy. int quantity; } From e30795a635009560f3a7b24fcae75a181671ed06 Mon Sep 17 00:00:00 2001 From: Vladislav Khomenko Date: Thu, 23 Jun 2022 09:40:41 +0300 Subject: [PATCH 9/9] Made the quantity param final --- .../lib/src/types/app_store_purchase_param.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart index 0cc8ef7b21bb..168ef5cea5f4 100644 --- a/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart +++ b/packages/in_app_purchase/in_app_purchase_storekit/lib/src/types/app_store_purchase_param.dart @@ -31,5 +31,5 @@ class AppStorePurchaseParam extends PurchaseParam { final bool simulatesAskToBuyInSandbox; /// Quantity of the product user requested to buy. - int quantity; + final int quantity; }