I am trying to set up paid products in my app.
I have followed all the guides for the Flutter_Inapp_Purchase plugin and they all say:
List<IAPItem> items = await FlutterInappPurchase.getProducts([iapId]);
Where iapId is the "id of my app". All of my other code surrounding this implementation works fine, because when I use 'android.test.purchased' as my iapId string, the test product is found and loaded into the app perfectly. So the issue is the string that I am using maybe, because no other explanation or examples are given about this anywhere.
I have a product in my store called remove_ads
.
So am I using the wrong iapId
here? I can't imagine what else it could be asking for.
Edit:
Purchasing the items.
I have updated the code below, as it had errors already. It now fails at the lines: _verifyPurchase and _deliverPurchase below, as these are not things. The official documentation for this seems to say "you go ahead and work all this stuff out from here", with no indication how to even begin.
Future<Null> _queryPastPurchases() async {
final QueryPurchaseDetailsResponse response = await InAppPurchaseConnection.instance.queryPastPurchases();
if (response.error != null) {
// Handle the error.
}
for (PurchaseDetails purchase in response.pastPurchases) {
_verifyPurchase(purchase); // Verify the purchase following the best practices for each storefront.
_deliverPurchase(purchase); // Deliver the purchase to the user in your app.
if (Platform.isIOS) {
// Mark that you've delivered the purchase. Only the App Store requires
// this final confirmation.
InAppPurchaseConnection.instance.completePurchase(purchase);
}
}
}
If you haven't received an in-app item you bought, try closing and restarting the app or game you're using. Tap Apps or Manage applications (depending on your device, this may be different). Tap the app you used to make your in-app purchase.
With some apps, you can buy additional content or services within the app. We call these "in-app purchases." Here are some examples of in-app purchases: A sword that gives you more power in a game. A key that unlocks more features of an app.
This answer is somewhat of a recommendation, however, it should take you to your goal.
The Flutter team has recently finished an official plugin for in-app purchases. It is the in_app_purchase
plugin.
I assume that you have already read through the Android Developers guide for configuring your remove_ads
purchase.
You need to add in_app_purchase
as a dependency in your pubspec.yaml
file:
dependencies:
in_app_purchase: ^0.3.1 # For newer versions, check the Pub page.
'package:in_app_purchase/in_app_purchase.dart'
:import 'package:in_app_purchase/in_app_purchase.dart';
// Set literals require Dart 2.2. Alternatively, remove `const` and use `<String>['remove_ads'].toSet()`.
const Set<String> _kIds = {'remove_ads'};
final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds);
if (!response.notFoundIds.isEmpty()) {
// Handle the error.
} else {
List<ProductDetails> products = response.productDetails;
for (ProductDetails product in products) {
print('${product.title}: ${product.description} (cost is ${product.price})');
}
// Example: purchasing the first available item.
final PurchaseParam purchaseParam = PurchaseParam(productDetails: products[0]);
InAppPurchaseConnection.instance.buyNonConsumable(purchaseParam: purchaseParam);
}
For more information and instructions, read the plugin's README and checkout the example app.
remove_ads
SKU ID instead of what they mention because their SKU IDs only apply to the example.You need to use a reserved SKU for the test: android.test.purchased
When using in_app_purchase:
const List<String> _kProductIds = <String>[
'android.test.purchased'
];
ProductDetailsResponse productDetailResponse =
await _connection.queryProductDetails(_kProductIds.toSet());
I just had this same problem (notFoundIds) while using flutter plugin in_app_purchase. So two things to be ensured:
Ensure productId is registered in PlayStore/AppStore as specified by plugin readme;
Before calling queryProductDetails, call isAppPurchaseAvailable which will initialise and wait a bit until it is ready, then queryProductDetails will work. Sample code below:
Future<List<ProductDetails>> loadProductsForSale() async {
if(await isAppPurchaseAvailable()) {
const Set<String> _kIds = {APP_PRODUCTID01};
final ProductDetailsResponse response =
await InAppPurchaseConnection.instance.queryProductDetails(_kIds);
if (response.notFoundIDs.isNotEmpty) {
debugPrint(
'#PurchaseService.loadProductsForSale() notFoundIDs: ${response
.notFoundIDs}');
}
if (response.error != null) {
debugPrint(
'#PurchaseService.loadProductsForSale() error: ${response.error
.code + ' - ' + response.error.message}');
}
List<ProductDetails> products = response.productDetails;
return products;
} else{
debugPrint('#PurchaseService.loadProductsForSale() store not available');
return null;
}
}
Future<bool> isAppPurchaseAvailable() async {
final bool available = await InAppPurchaseConnection.instance.isAvailable();
debugPrint('#PurchaseService.isAppPurchaseAvailable() => $available');
return available;
if (!available) {
// The store cannot be reached or accessed. Update the UI accordingly.
return false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With