Flutter [in_app_purchase] 获取订阅内的所有计划

问题描述 投票:0回答:2

我正在使用 in_app_purchase 软件包,但我只能在订阅中获得一项计划

我有 3 个订阅:

Basic subscription
Premium subscription
Enterprise subscription

在每个订阅中,我想要有 2 个计划:

Month plan
Year plan

我总是得到启用“向后兼容性”的计划(“这将是已弃用的 Google Play 计费库方法 querySkuDetailsAsync() 返回的基线”)。

有什么方法可以获取所有计划,还是我必须订阅 6 个计划,每个计划中只有 1 个计划?

编辑:

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

import 'package:flutter/material.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
import 'package:motorline_home/widgets/materials/appbar/appbar_title_widget.dart';
import 'package:motorline_home/widgets/materials/pop_button_widget.dart';
import 'package:rxdart/subjects.dart';

class SubscriptionPage extends StatefulWidget {

  const SubscriptionPage({
    Key? key,
  }) : super(key: key);

  @override
  State<SubscriptionPage> createState() => _SubscriptionPageState();
}

class _SubscriptionPageState extends State<SubscriptionPage> {
  // In app subscriptions
  InAppPurchase _inAppPurchase = InAppPurchase.instance;
  late StreamSubscription<List<PurchaseDetails>> _inAppPurchaseSubscription;
  StreamController<List<ProductDetails>> _streamGooglePlaySubscriptions =
      BehaviorSubject();
  final List<String> _subscriptionsIDs = [
    "basic",
    "premium",
    "enterprise",
  ];

  @override
  void initState() {
    super.initState();

    // In app purchase subscription
    _inAppPurchaseSubscription =
        _inAppPurchase.purchaseStream.listen((purchaseDetailsList) {
      _listenToPurchaseUpdated(purchaseDetailsList);
    }, onDone: () {
      print("In app purchase onDone");
      _inAppPurchaseSubscription.cancel();
    }, onError: (error) {
      print("In app purchase error: ${error.toString()}");
      // handle error here.
      _inAppPurchaseSubscription.cancel();
    });
    // Initialize in app purchase
    _initializeInAppPurchase();
  }

  @override
  void dispose() {
    if (Platform.isIOS) {
      final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
      _inAppPurchase
          .getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
      iosPlatformAddition.setDelegate(null);
    }

    // Cancel in app purchase listener
    _inAppPurchaseSubscription.cancel();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: AppBarTitleWidget(
          title: FlutterI18n.translate(context, "subscriptions"),
        ),
        leading: PopButtonWidget(),
      ),
      // Body
      body: Container(),
    );
  }

  void _initializeInAppPurchase() async {
    print("Initializing in app purchase");
    bool available = await _inAppPurchase.isAvailable();
    print("In app purchase initialized: $available");

    if (available) {
      if (Platform.isIOS) {
        final InAppPurchaseStoreKitPlatformAddition iosPlatformAddition =
        _inAppPurchase
            .getPlatformAddition<InAppPurchaseStoreKitPlatformAddition>();
        await iosPlatformAddition.setDelegate(ExamplePaymentQueueDelegate());
      }

      // Get subscriptions
      List<ProductDetails> subscriptions = await _getSubscriptions(
        productIds:
          _subscriptionsIDs.toSet(),
      );
      // Sort by price
      subscriptions.sort((a, b) => a.rawPrice.compareTo(b.rawPrice));

      // Add subscriptions to stream
      _streamGooglePlaySubscriptions.add(subscriptions);

      // DEBUG: Print subscriptions
      print("In app purchase subscription subscriptions: ${subscriptions}");
      for (var subscription in subscriptions) {
        print("In app purchase plan: ${subscription.id}: ${subscription.rawPrice}");
        print("In app purchase description: ${subscription.description}");
        // HOW GET ALL PLANS IN EACH SUBSCRIPTION ID?
      }

      await InAppPurchase.instance.restorePurchases();
    }
  }

  // In app purchase updates
  void _listenToPurchaseUpdated(List<PurchaseDetails> purchaseDetailsList) {
    purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async {
      // If purchase is pending
      if (purchaseDetails.status == PurchaseStatus.pending) {
        print("In app purchase pending...");
        // Show pending ui
      } else {
        if (purchaseDetails.status == PurchaseStatus.canceled) {
          print("In app purchase cancelled");
        }
        // If purchase failed
        if (purchaseDetails.status == PurchaseStatus.error) {
          print("In app purchase error");
          // Show error
        } else if (purchaseDetails.status == PurchaseStatus.purchased ||
            purchaseDetails.status == PurchaseStatus.restored) {
          print("In app purchase restored or purchased");
        }

        if (purchaseDetails.pendingCompletePurchase) {
          debugPrint("In app purchase complete purchased");
          debugPrint(
              "In app purchase purchase id : ${purchaseDetails.purchaseID}");
          debugPrint(
              "In app purchase server data : ${purchaseDetails.verificationData.serverVerificationData}");
          debugPrint(
              "In app purchase local data  : ${purchaseDetails.verificationData.localVerificationData}");
          // Verify purchase on backend

          try {
            // VALIDADE PURCHASE IN BACKEND
          } catch (error) {
            debugPrint("In app purchase error: ${error.toString()}");
          }
        }
      }
    });
  }

  // Get subscription
  Future<List<ProductDetails>> _getSubscriptions(
      {required Set<String> productIds}) async {
    ProductDetailsResponse response =
        await _inAppPurchase.queryProductDetails(productIds);

    return response.productDetails;
  }
}

/// Example implementation of the
/// [`SKPaymentQueueDelegate`](https://developer.apple.com/documentation/storekit/skpaymentqueuedelegate?language=objc).
///
/// The payment queue delegate can be implementated to provide information
/// needed to complete transactions.
class ExamplePaymentQueueDelegate implements SKPaymentQueueDelegateWrapper {
  @override
  bool shouldContinueTransaction(
      SKPaymentTransactionWrapper transaction, SKStorefrontWrapper storefront) {
    return true;
  }

  @override
  bool shouldShowPriceConsent() {
    return false;
  }
}
flutter in-app-purchase
2个回答
0
投票

你喜欢做的事情是不可能的。您需要为每个订阅创建一个新计划,您不能说高级订阅确实有包年和包月计划。


0
投票

目前这是不可能的,因为官方插件不支持它(而且我们不知道什么时候会支持):

https://github.com/flutter/flutter/issues/110909

正如他们提到的,解决方案是每个订阅一个计划,并在应用程序中添加必要的额外逻辑(例如,检测 ID 为

PLUS-year
的订阅是否是
PLUS-month
的升级)

© www.soinside.com 2019 - 2024. All rights reserved.