[in_app_purchase_storekit] Make Storekit 2 the default (#9178)

Make Storekit 2 the default. Fixes https://github.com/flutter/flutter/issues/159871

## Pre-Review Checklist
This commit is contained in:
LouiseHsu
2025-05-12 14:34:19 -07:00
committed by GitHub
parent 6affa420fa
commit 2e166de093
11 changed files with 49 additions and 13 deletions

View File

@ -1,5 +1,7 @@
## NEXT
## 3.2.2
* Updates `in_app_purchase_storekit` to 0.4.0
* Updates README with Storekit 2 examples.
* Updates README to indicate that Andoid SDK <21 is no longer supported.
## 3.2.1

View File

@ -356,6 +356,14 @@ if (productDetails is AppStoreProductDetails) {
SKProductWrapper skProduct = (productDetails as AppStoreProductDetails).skProduct;
print(skProduct.subscriptionGroupIdentifier);
}
// With StoreKit 2
import 'package:in_app_purchase_storekit/store_kit_2_wrappers.dart';
if (productDetails is AppStoreProduct2Details) {
SK2Product product = (productDetails as AppStoreProduct2Details).sk2Product;
print(product.subscription?.subscriptionGroupID);
}
```
The `purchaseStream` provides objects of type `PurchaseDetails`. PurchaseDetails' provides all
@ -377,7 +385,7 @@ if (purchaseDetails is GooglePlayPurchaseDetails) {
}
```
How to get the `transactionState` of a purchase in iOS:
How to get the `transactionState` of a purchase in iOS, using the original StoreKit API:
```dart
//import for AppStorePurchaseDetails
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
@ -390,6 +398,15 @@ if (purchaseDetails is AppStorePurchaseDetails) {
}
```
How to get the `jsonRepresentation` of a transaction in iOS, using StoreKit 2:
```dart
//import for SK2TransactionWrapper
import 'package:in_app_purchase_storekit/store_kit_2_wrappers.dart';
List<SK2Transaction> transactions = await SK2Transaction.transactions();
print(transactions[0].jsonRepresentation);
```
Please note that it is required to import `in_app_purchase_android` and/or `in_app_purchase_storekit`.
### Presenting a code redemption sheet (iOS 14)

View File

@ -2,7 +2,7 @@ name: in_app_purchase
description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play.
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
version: 3.2.1
version: 3.2.2
environment:
sdk: ^3.5.0

View File

@ -1,3 +1,8 @@
## 0.4.0
* **BREAKING CHANGE:** StoreKit 2 is now the default for all devices that support it.
* To revert to StoreKit1 for devices below iOS 15, call `enableStoreKit1`
## 0.3.22+1
* Fix a channel thread-safety issue when StoreKit2 is enabled.

View File

@ -12,7 +12,6 @@ import 'consumable_store.dart';
import 'example_payment_queue_delegate.dart';
void main() {
InAppPurchaseStoreKitPlatform.enableStoreKit2();
WidgetsFlutterBinding.ensureInitialized();
// When using the Android plugin directly it is mandatory to register
// the plugin as default instance as part of initializing the app.

View File

@ -31,7 +31,7 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {
InAppPurchaseStoreKitPlatform();
/// Experimental flag for StoreKit2.
static bool _useStoreKit2 = false;
static bool _useStoreKit2 = true;
/// StoreKit1
static late SKPaymentQueueWrapper _skPaymentQueueWrapper;
@ -251,10 +251,17 @@ class InAppPurchaseStoreKitPlatform extends InAppPurchasePlatform {
@Deprecated('Use countryCode')
Future<String?> getCountryCode() => countryCode();
/// Turns on StoreKit2. You cannot disable this after it is enabled.
/// This can only be enabled if your device supports StoreKit 2.
/// StoreKit 2 is now the default.
@Deprecated('StoreKit 2 is now the default')
static Future<bool> enableStoreKit2() async {
_useStoreKit2 = await SKRequestMaker.supportsStoreKit2();
_useStoreKit2 = true;
return true;
}
/// Call this before `registerPlatform` to re-enable StoreKit1
@Deprecated('Please note that StoreKit 1 will be removed in the future.')
static Future<bool> enableStoreKit1() async {
_useStoreKit2 = !(await SKRequestMaker.supportsStoreKit2());
return _useStoreKit2;
}
}

View File

@ -27,7 +27,8 @@ class SK2Transaction {
required this.appAccountToken,
this.subscriptionGroupID,
this.price,
this.error});
this.error,
this.jsonRepresentation});
/// The unique identifier for the transaction.
final String id;
@ -62,6 +63,9 @@ class SK2Transaction {
/// Any error returned from StoreKit
final SKError? error;
/// The json representation of a transaction
final String? jsonRepresentation;
/// Wrapper around [Transaction.finish]
/// https://developer.apple.com/documentation/storekit/transaction/3749694-finish
/// Indicates to the App Store that the app delivered the purchased content
@ -105,7 +109,8 @@ extension on SK2TransactionMessage {
productId: productId,
purchaseDate: purchaseDate,
expirationDate: expirationDate,
appAccountToken: appAccountToken);
appAccountToken: appAccountToken,
jsonRepresentation: jsonRepresentation);
}
PurchaseDetails convertToDetails() {

View File

@ -2,7 +2,7 @@ name: in_app_purchase_storekit
description: An implementation for the iOS and macOS platforms of the Flutter `in_app_purchase` plugin. This uses the StoreKit Framework.
repository: https://github.com/flutter/packages/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.22+1
version: 0.4.0
environment:
sdk: ^3.4.0

View File

@ -33,6 +33,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
bool isPaymentQueueDelegateRegistered = false;
String _countryCode = 'USA';
String _countryIdentifier = 'LL';
bool shouldStoreKit2BeEnabled = true;
void reset() {
transactionList = <SKPaymentTransactionWrapper>[];
@ -283,7 +284,7 @@ class FakeStoreKitPlatform implements TestInAppPurchaseApi {
@override
bool supportsStoreKit2() {
return true;
return shouldStoreKit2BeEnabled;
}
}

View File

@ -40,7 +40,6 @@ void main() {
InAppPurchaseStoreKitPlatform.registerPlatform();
iapStoreKitPlatform =
InAppPurchasePlatform.instance as InAppPurchaseStoreKitPlatform;
InAppPurchaseStoreKitPlatform.enableStoreKit2();
fakeStoreKit2Platform.reset();
});

View File

@ -26,6 +26,7 @@ void main() {
});
setUp(() {
InAppPurchaseStoreKitPlatform.enableStoreKit1();
InAppPurchaseStoreKitPlatform.registerPlatform();
iapStoreKitPlatform =
InAppPurchasePlatform.instance as InAppPurchaseStoreKitPlatform;