Flutter未找到任何应​​用内购买产品

时间:2019-06-13 13:23:49

标签: android flutter

我正在尝试在我的应用中设置付费产品。

我已经遵循了Flutter_Inapp_Purchase插件的所有指南,并且都说:

List<IAPItem> items = await FlutterInappPurchase.getProducts([iapId]);

其中iapId是“我的应用的ID”。与该实现有关的所有其他代码均能正常工作,因为当我将“ android.test.purchased”用作iapId字符串时,可以找到测试产品并将其完美加载到应用程序中。因此,问题可能是我正在使用的字符串,因为在任何地方都没有给出其他解释或示例。

我的商店中有一个名为remove_ads的产品。

那么我在这里使用错误的iapId吗?我无法想象它还会要求什么。

编辑:

购买物品。

我已经更新了以下代码,因为它已经有错误。现在,它在以下几行失败:_verifyPurchase和_deliverPurchase,因为这些不是问题。官方文档似乎说“您可以继续并从这里开始处理所有这些工作”,甚至没有任何指示。

  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);
      }
    }
  }

3 个答案:

答案 0 :(得分:6)

这个答案有点建议,但是,它应该带您实现目标。

Flutter小组最近完成了一个官方插件,用于应用内购买。它是in_app_purchase plugin

  1. 我认为您已经通读了the Android Developers guide来配置您的#Sample Data x <- data.frame(row = 1:5, string = LETTERS[1:5]) # row string #1 1 A #2 2 B #3 3 C #4 4 D #5 5 E matchingRow <- match("C", x$string) x[-c(matchingRow-1, matchingRow+1),] #romove row befor and after matichingRow # row string #1 1 A #3 3 C #5 5 E 购买。

  2. 您需要在remove_ads文件中添加in_app_purchase作为依赖项:

pubspec.yaml
  1. 现在,在Flutter应用中,您需要导入dependencies: in_app_purchase: ^0.2.0 # For newer versions, check the Pub page.
'package:in_app_purchase/in_app_purchase.dart'
  1. 加载产品,您可以使用以下代码:
import 'package:in_app_purchase/in_app_purchase.dart';

有关更多信息和说明,请阅读plugin's README并签出example app

  1. 您需要按照example's README中说明的步骤进行操作。您将需要创建一个// 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) { println('${product.tile}: ${product.description} (cost is ${product.price})'); } // Example: purchasing the first available item. final PurchaseParam purchaseParam = PurchaseParam(productDetails: products[0]); InAppPurchaseConnection.instance.buyNonConsumable(purchaseParam: purchaseParam); } SKU ID(而不是他们提到的内容),因为它们的SKU ID仅适用于示例。

答案 1 :(得分:5)

您需要使用保留的SKU进行测试:android.test.purchased

使用in_app_purchase时:

const List<String> _kProductIds = <String>[
  'android.test.purchased'
];
ProductDetailsResponse productDetailResponse =
  await _connection.queryProductDetails(_kProductIds.toSet());

答案 2 :(得分:2)

我在使用 flutter 插件 in_app_purchase 时遇到了同样的问题 (notFoundIds)。所以要确保两件事:

  1. 确保 productId 按照插件自述文件的规定在 PlayStore/AppStore 中注册;

  2. 在调用 queryProductDetails 之前,调用 isAppPurchaseAvailable,它会初始化并稍等片刻,直到它准备好,然后 queryProductDetails 将起作用。下面的示例代码:

       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;
     }
     }