payment_sdk.dart 2.96 KB
import 'dart:async';

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

class PaymentSdk {
  PaymentSdk._privateConstructor();

  static final PaymentSdk _instance = PaymentSdk._privateConstructor();

  static PaymentSdk get instance {
    return _instance;
  }

  static const Set<String> _kIds = <String>{'yearly_yiyan_vip', 'monthly_yiyan_vip', 'yearly-default'};

  StreamSubscription<List<PurchaseDetails>>? _subscription;
  List<ProductDetails> products = [];

  initState() {
    final Stream<List<PurchaseDetails>> purchaseUpdated = InAppPurchase.instance.purchaseStream;
    _subscription = purchaseUpdated.listen((purchaseDetailsList) {
      _listenToPurchaseUpdated(purchaseDetailsList);
    }, onDone: () {
      _subscription?.cancel();
    }, onError: (error) {
      // handle error here.
    });
  }

  Future<List<ProductDetails>> queryProducts() async {
    final bool available = await InAppPurchase.instance.isAvailable();
    if (!available) {
      print("####### isAvailable false");
      return [];
    }
    final ProductDetailsResponse response = await InAppPurchase.instance.queryProductDetails({
      'yearly_yiyan_vip',
      'monthly_yiyan_vip',
      'yearly-default',
      'test.yiyan.vip.1.month',
    });
    if (response.notFoundIDs.isNotEmpty) {
      // Handle the error.
      print("####### notFoundIDs");
    } else {
    }
    print(response.productDetails.length);
    return products = response.productDetails;
  }

  buy(ProductDetails details) {
    final PurchaseParam purchaseParam = PurchaseParam(productDetails: details);
    if (_isConsumable(details)) {
      InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);
    } else {
      InAppPurchase.instance.buyNonConsumable(purchaseParam: purchaseParam);
    }
  }

  void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) async {
    for (var purchaseDetails in purchaseDetailsList) {
      if (purchaseDetails.status == PurchaseStatus.pending) {
        // _showPendingUI();
      } else {
        if (purchaseDetails.status == PurchaseStatus.error) {
          // _handleError(purchaseDetails.error!);
        } else if (purchaseDetails.status == PurchaseStatus.purchased || purchaseDetails.status == PurchaseStatus.restored) {
          bool valid = await _verifyPurchase(purchaseDetails);
          if (valid) {
            _deliverProduct(purchaseDetails);
          } else {
            _handleInvalidPurchase(purchaseDetails);
          }
        }
        if (purchaseDetails.pendingCompletePurchase) {
          await InAppPurchase.instance.completePurchase(purchaseDetails);
        }
      }
    }
  }

  _verifyPurchase(PurchaseDetails purchaseDetails) async {
    return true;
  }

  void _deliverProduct(PurchaseDetails purchaseDetails) {}

  void _handleInvalidPurchase(PurchaseDetails purchaseDetails) {}

  bool _isConsumable(ProductDetails details) {
    return true;
  }

  void dispose() {
    _subscription?.cancel();
  }
}