扑。如何检查自动续订订阅是否仍然有效

Flutter. How to check that autorenewal subscription is still valid

我的应用有 1 个月的自动续订订阅。当用户单击 "Buy a subscription" 按钮时,我将购买日期保存到共享首选项中。 然后,1 个月后,我需要检查此订阅是否仍然有效。 那么我该如何实现呢?

有几种方法可以做到这一点,但我不会在移动设备上这样做。

在您要求的设备上

安装 Flutter Cache Manager,在开始时将缓存键值 'Subscription' 设置为 true 以及 maxAgeCacheObject:持续时间(天数:30)。每次启动时检查该键是否仍然存在于缓存中。如果是,则它仍然有效,否则它已过期。

使用 FirebaseFunction 的建议解决方案

我建议设置一个后端来管理所有这些。这不是移动设备的任务。您可以从 firebase 获得一个 Cloud Function,您可以在其中传递一个唯一的设备 ID,它会 return 订阅是否仍然有效。无服务器功能应该适用于此。伪步骤:

  1. (在设备上)当应用程序启动时生成一个 guid 并使用您的 guid 发出 http post 请求。
  2. (Server) 在您的无服务器函数中,保存向您的数据库发出请求的日期以及您发送的 uniqueId。如果您的 ID 已经在数据库中,则检查它是否已过期(添加日期 - 当前日期)< 30 天。 Return true 或 false 来自函数。如果仍然有效则为真,如果无效则为假。
  3. (在设备上)当您从函数中收到 true 时,将生成的 id 保存在本地磁盘上,然后继续您想要执行的操作。如果为假,则将用户锁定或显示您要处理的订阅。

==== 2020 年 3 月 11 日更新

你好,我可以看到这个 post 仍在寻找如何在 Flutter 中使用订阅的人阅读。 在 2019 年期间,我制作了两款安装量达数千次的应用程序,用户可以在这两个平台上购买可续订的订阅。 直到 2020 年 2 月,我使用了 Flutter 团队 https://pub.dev/packages/in_app_purchase 的这个包,但是 - 无法获取有关用户在 iOS 中取消订阅的信息。这不是插件问题,而是该过程的 iOS 方法。出于安全原因,我们应该实现自己的后端(顺便说一句 Google 也建议这样做,但仍然留下了直接从应用程序检查状态的方式)。

所以,经过一些研究,我找到了制作后端和插件的人,并且它是免费的,直到你当月的收入低于 10 000 美元。 https://www.revenuecat.com/ https://pub.dev/packages/purchases_flutter

我已经在我的应用程序中实现了这个插件,它非常有用。有一些好的方法可以让您在应用程序中的任何位置获得订阅状态。我打算做一个例子和文章,但不确定时间。

====

2019 年 7 月 15 日更新。只是为了节省时间。下面的答案是针对一个过时的支付插件。之后Flutter团队做了插件 https://pub.dev/packages/in_app_purchase 我推荐使用它。

=====

最好的方法是使用安全的后端服务器接收 Real-time Developer Notifications。 但是,可以直接在应用程序中检查状态。 因此,当用户尝试访问某些付费功能时,您可以检查他的订阅是否有效。下面是示例:

在某处使用 class

创建文件
import 'dart:io' show Platform;
import 'package:flutter/services.dart';
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
import 'dart:async';

class SubcsriptionStatus {
static Future<bool> subscriptionStatus(
  String sku,
  [Duration duration = const Duration(days: 30),
  Duration grace = const Duration(days: 0)]) async {
    if (Platform.isIOS) {
      var history = await FlutterInappPurchase.getPurchaseHistory();

      for (var purchase in history) {
        Duration difference =
        DateTime.now().difference(purchase.transactionDate);
        if (difference.inMinutes <= (duration + grace).inMinutes &&
            purchase.productId == sku) return true;
      }
      return false;
    } else if (Platform.isAndroid) {
      var purchases = await FlutterInappPurchase.getAvailablePurchases();

      for (var purchase in purchases) {
        if (purchase.productId == sku) return true;
      }
      return false;
    }
    throw PlatformException(
        code: Platform.operatingSystem, message: "platform not supported");
  }
}

在需要查看订阅状态的地方导入,在Constructor中使用。例如:

class _SubscriptionState extends State<Subscription> {
  bool userSubscribed;
  _SubscriptionState() {
  SubcsriptionStatus.subscriptionStatus(iapId, const Duration(days: 30), const 
  Duration(days: 0)).then((val) => setState(() {
  userSubscribed = val;
   }));
   }
}

在变量 userSubscribed 中将是状态 - true 或 false。 (请注意,您必须将 flutter_inapp_purchase 添加到您的项目中)。

是的,关于漏洞,有一种方法可以解决用户手动更改时间只是为了欺骗应用程序的问题,我想到的解决方案是让DateTime这样从服务器传来,用户是否是否更改日期和时间,您最终会得到正确的时间范围。希望对您有所帮助。

至于检查订阅是否已过期,只需按照@awaik 给出的步骤,此外,您可以向您的 api 请求存储购买订阅和期望订阅的日期时间直到到期为止。我建议您将购买日期和预计日期保存在服务器中而不是用户设备中,因为清除应用程序的缓存或数据目录会导致保存的数据丢失。祝你好运。