首页 > 解决方案 > 如何在 Android 上使用 Flutter 成功完成应用内购买?

问题描述

我想要的是

我想将 Google Play 在应用购买中集成到我的 Flutter 应用中,我要销售的产品是消耗品。现在我正在使用这个in_app_purchase: (0.3.4+16)包。

我做了什么

预期和实际结果

我希望付款能够正常工作,并且所有 api 调用都能正常返回。

当我在手机上开始购买时,购买流程开始,我可以选择所需的付款方式。在我接受付款后_listenToPurchaseUpdated(...),按预期调用该方法。但是,调用InAppPurchaseConnection.instance.completePurchase(p)返回 aBillingResponse.developerError并且我收到以下调试消息:

W/BillingHelper: Couldn't find purchase lists, trying to find single data.
I/flutter: result: BillingResponse.developerError (Purchase is in an invalid state.)

此错误伴随着“测试卡,始终批准”以及当我使用 PayPal 开始实际交易时。对于 PayPal 购买,我收到了一封确认电子邮件,表明交易成功。在文档中它说:

警告!未能在购买后 3 天内调用此方法并获得成功响应将导致 Android 退款。

总结问题

如何获得InAppPurchaseConnection.instance.completePurchase(p)返回成功结果的调用?

采购实施

在应用程序购买中设置的代码如文档所示实现:

InAppPurchaseConnection.enablePendingPurchases();

Stream<List<PurchaseDetails>> purchaseUpdated = InAppPurchaseConnection.instance.purchaseUpdatedStream;

_subscription = purchaseUpdated.listen(_listenToPurchaseUpdated, onDone: () {
    _subscription.cancel();
}, onError: (error) {
  // handle error here.
});

...

Future<void> _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
  for (var p in purchaseDetailsList) {
   
    // Code to validate the payment

    if (!p.pendingCompletePurchase) continue;

    var result = await InAppPurchaseConnection.instance.completePurchase(p);

    if (result.responseCode != BillingResponse.ok) {
      print("result: ${result.responseCode} (${result.debugMessage})");
    }
  }
}

要购买消耗品,我有这种查询产品详细信息和电话的方法buyConsumable(...)

Future<bool> _buyConsumableById(String id) async {
  final ProductDetailsResponse response = await InAppPurchaseConnection
      .instance
      .queryProductDetails([id].toSet());

  if (response.notFoundIDs.isNotEmpty || response.productDetails.isEmpty) {
    return false;
  }

  List<ProductDetails> productDetails = response.productDetails;

  final PurchaseParam purchaseParam = PurchaseParam(
    productDetails: productDetails[0],
  );

  return await InAppPurchaseConnection.instance.buyConsumable(
    purchaseParam: purchaseParam,
  );
}

标签: androidfluttergoogle-playin-app-purchasein-app-billing

解决方案


解决方法是不调用completePurchase(...)消耗品购买的方法。默认情况下,库会为您使用购买,这隐含地充当对completePurchase(...).

背景

调用InAppPurchaseConnection.instance.buyConsumable(...)有一个可选的布尔参数autoConsume,它总是true. 这意味着,在 android 上,购买是在回调到purchaseUpdatedStream. 该completePurchase方法的文档说明如下:

[consumePurchase] 在 Android 上充当隐式 [completePurchase]

解决问题的代码

Future<void> _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
  for (var p in purchaseDetailsList) {

    // Code to validate the payment

    if (!p.pendingCompletePurchase) continue;
    if (_isConsumable(p.productID)) continue; // Determine if the item is consumable. If so do not consume it

    var result = await InAppPurchaseConnection.instance.completePurchase(p);

    if (result.responseCode != BillingResponse.ok) {
      print("result: ${result.responseCode} (${result.debugMessage})");
    }
  }
}

推荐阅读