【问题标题】:Flutter. How to check that autorenewal subscription is still valid扑。如何检查自动续订订阅是否仍然有效
【发布时间】:2019-07-21 13:23:54
【问题描述】:

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

【问题讨论】:

标签: flutter in-app-purchase subscription


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    您好,我可以看到这篇文章仍然被那些正在寻找如何在 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

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

    ====

    从 15.07.2019 开始更新。只是为了节省时间。下面的答案是针对过时的付款插件给出的。之后 Flutter 团队制作了插件 https://pub.dev/packages/in_app_purchase 我建议使用它。

    =====

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

    使用类在某处创建文件

    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");
      }
    }
    

    在需要检查订阅状态的地方导入并在构造函数中使用。例如:

    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 添加到您的项目中)。

    【讨论】:

    • 嘿,小问题,我实现了你的课程,它似乎工作得很好。我只是想知道,订阅的上限是 30 天还是“每月”有时是 31 天,有时是 30 天,有时是 28 天?因为您的示例仅在订阅在 30 天后到期时才有效,对吗?
    • 嗨!酷 :) 正如您从 Android 代码中看到的那样,您实际上并不需要这个“持续时间(天:30)” - 他们会进行计费并给出订阅是否付费的答案。但是对于IOS,您必须自己处理它。所以,我想,你应该检查当前月份并使用 28(29)、30 或 31 天。只需为此添加方法。抱歉,我现在很忙,下周可以。
    • 好吧,我明白了。我只是不确定 IOS 是如何处理它的,如果你在 2 月购买它,如果产品将在 28/29 天内购买,例如..
    • 嘿awaik,我现在检查了一下,iOS 系统确实处理它的方式不同,不是 30 天而是一个月,比如 4/30 到 5/29
    • 啊,谢谢你的信息,我也会在几天内在我的应用中实现 iOS。
    【解决方案3】:

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

    在您要求的设备上

    安装Flutter Cache Manager,在开始时将缓存键值“订阅”设置为 true,并使用 maxAgeCacheObject:持续时间(天数:30)。每次启动时检查该键是否仍然存在于缓存中。如果是,那么它仍然有效,否则它已经过期。

    使用 FirebaseFunction 的建议解决方案

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

    1. (在设备上)当应用启动时生成一个 guid 并使用您的 guid 发出 http post 请求。
    2. (服务器)在您的无服务器函数中,保存向您的数据库发出请求的日期以及您发送的唯一 ID。如果您的 id 已经在数据库中,请检查它是否已过期(添加日期 - 当前日期)
    3. (在设备上)当您从函数接收到 true 时,然后将生成的 id 保存在本地磁盘上并继续您想做的事情。如果为 false,则将用户锁定或显示您要处理的订阅。

    【讨论】:

    • 服务器端解决方案是实现这一点的正确方法。如果没有这个,就会出现许多漏洞,例如 1) 假收据 2) 购买后获得退款 3) 更改系统时间以继续订阅。和更多。这里缺少的是检查收据的频率超过 30 天,看它是否被取消/退款。
    • @enc_life 我同意。我提到了“当应用程序启动时......”所以这将在每个会话中发生。您将在每个会话中提出请求。如果返回 true,则继续,否则阻止用户。甚至可以进行锁定,这样您就不必再次执行请求,直到执行您的订阅逻辑并完成它。
    • 是的,您在每次应用启动时检查状态是对的。我指的是定期重新验证收据服务器端,以查看用户是否在预定的到期日期之前退款,您需要提前切断访问权限。
    • @enc_life 我明白了。好吧,希望 OP 也能读取这些 cmets,并让系统正常运行,而不是在设备上运行。
    • docs.revenuecat.com/discuss/5ea749abbbfeff0018f166f3 我正面临这个问题。请帮忙。我可以付钱给你。
    猜你喜欢
    • 2017-09-10
    • 1970-01-01
    • 2011-07-04
    • 2016-08-04
    • 1970-01-01
    • 2020-02-23
    • 2021-12-12
    • 2012-08-26
    • 1970-01-01
    相关资源
    最近更新 更多