首页 > 解决方案 > 有人可以帮助我使用 in_app_purchase 插件吗?

问题描述

再会!我正在尝试配置非消耗性产品。我应该何时以及为什么应该完成Purchase以及何时以及为什么应该消费Purchase?另外,我不能让它在两个平台上都能正常工作。

我正在使用带有以下环境的in_app_purchase: ^0.5.1+3插件:

[✓] Flutter (Channel stable, 2.0.4, on macOS 11.2.2 20D80 darwin-x64, locale en-BY)

[✓] Android 工具链 - 为 Android 设备开发(Android SDK 版本 30.0.2)

[✓] Xcode - 为 iOS 和 macOS 开发

[✓] Chrome - 为网络开发

[✓] Android Studio(4.1版)

[✓] VS 代码(版本 1.55.0)

[✓] 连接的设备(1 个可用)

如果有人可以帮助我编写代码,那就太好了。

import 'dart:async';
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase/store_kit_wrappers.dart';

const myProductId = 'remove_ads';

class PaymentProvider with ChangeNotifier {
  final _iap = InAppPurchaseConnection.instance;

  StreamSubscription<List<PurchaseDetails>> subscription;
  bool isAvailable = false;
  bool initialized = false;

  bool _isPurchased = false;
  bool get isPurchased => _isPurchased;
  set isPurchased(bool value) {
    _isPurchased = value;
    notifyListeners();
  }

  bool _isPurchasePending = false;
  bool get isPurchasePending => _isPurchasePending;
  set isPurchasePending(bool value) {
    _isPurchasePending = value;
    notifyListeners();
  }

  List<ProductDetails> _products = [];
  List<ProductDetails> get products => _products;
  set products(List value) {
    _products = value;
    notifyListeners();
  }

  List<PurchaseDetails> _purchases = [];
  List<PurchaseDetails> get purchases => _purchases;
  set purchases(List value) {
    _purchases = value;
    notifyListeners();
  }

  Future<void> initialize() async {
    isAvailable = await _iap.isAvailable();

    if (isAvailable) {
      await Future.wait([
        _getProducts(),
        _getPastPurchases(),
      ]);

      await restorePurchase();

      subscription = _iap.purchaseUpdatedStream.listen(
        _listenToPurchaseUpdated,
        onDone: () {
          subscription?.cancel();
        },
      );

      initialized = true;
      notifyListeners();
    }
  }

  void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
    purchaseDetailsList.forEach((purchaseDetails) async {
      switch (purchaseDetails.status) {
        case PurchaseStatus.pending:
          isPurchasePending = true;
          break;
        case PurchaseStatus.error:
          if (Platform.isIOS) await _iap.completePurchase(purchaseDetails);
          isPurchasePending = false;
          break;
        case PurchaseStatus.purchased:
          var valid = await _verifyPurchase(purchaseDetails);

          if (valid) {
            _deliverProduct(purchaseDetails);
          } else {
            _handleInvalidPurchase(purchaseDetails);
          }
          break;
        default:
          break;
      }
    });
  }

  Future<bool> _verifyPurchase(PurchaseDetails purchaseDetails) async {
    /// ???
    return Future<bool>.value(true);
  }

  void _deliverProduct(PurchaseDetails purchaseDetails) async {
    if (purchaseDetails.productID != myProductId) {
      purchases.add(purchaseDetails);
    }

    if (purchaseDetails.pendingCompletePurchase) {
      await _iap.completePurchase(purchaseDetails);
    }

    if (Platform.isAndroid) {
      if (purchaseDetails.productID == myProductId) {
        await _iap.consumePurchase(purchaseDetails);
      }
    }

    isPurchased = true;
    isPurchasePending = false;
  }

  void _handleInvalidPurchase(PurchaseDetails purchaseDetails) {
    /// ???
  }

  Future<void> restorePurchase() async {
    // if (Platform.isIOS) {
    //   await SKPaymentQueueWrapper().restoreTransactions();
    // }

    var purchase = hasPurchased(myProductId);

    if (purchase != null && purchase.status == PurchaseStatus.purchased) {
      await _iap.completePurchase(purchase);
      isPurchased = true;
    }
  }

  PurchaseDetails hasPurchased(String productId) {
    return purchases.firstWhereOrNull((_) => _.productID == productId);
  }

  Future<void> purchaseRemoveAds(ProductDetails product) async {
    if (Platform.isIOS) {
      var transactions = await SKPaymentQueueWrapper().transactions();

      await Future.forEach(transactions, (transaction) async {
        await SKPaymentQueueWrapper().finishTransaction(transaction);
      });
    }

    var purchaseParam = PurchaseParam(
      productDetails: product,
    );

    await _iap.buyNonConsumable(purchaseParam: purchaseParam);
  }

  Future<void> _getProducts() async {
    var response = await _iap.queryProductDetails({myProductId});
    products = response.productDetails;
  }

  Future<void> _getPastPurchases() async {
    var purchaseResponse = await _iap.queryPastPurchases();

    if (purchaseResponse.error != null) {
      // handle query past purchase error..
    }

    for (var purchase in purchaseResponse.pastPurchases) {
      if (purchase.pendingCompletePurchase) {
        await _iap.completePurchase(purchase);
      }

      if (Platform.isAndroid && purchase.status == PurchaseStatus.purchased) {
        await _iap.consumePurchase(purchase);
      }
    }

    purchases = purchaseResponse.pastPurchases;
  }
}

标签: flutterin-app-purchase

解决方案


推荐阅读