我应该使用哪种IAP服务来销售non consumable products个(一次性支付产品)的Ffltter应用程序?

我环顾四周,所有我能找到的都是为RevenueCat做宣传的人,他们的观点听起来更像是广告.

所以我想听听你的意见:

我应该创建自己的后端来处理交易,还是应该 Select 第三方选项(这将花费我收入的%1%左右[听起来不是很多,但当你仔细想想,他们的定价真的没有那么大意义吗?])?

推荐答案

我从来没有try 过RevenueCat,但几年前,在我自己的Flight应用程序中,我使用了in_app_purchase个包+Firebase Cloud函数(firebase_corefirebase_functions个包)来实现非消费品的应用内购买.

这种方法确实相当复杂,特别是对于新手来说.在这种情况下,您还需要一些JavaScript/TypeScrip技能,因为这些是编写FB函数的语言.最终,您的功能将与Play Developer API交互.

你最好在谷歌上搜索一些关于这个主题的最新教程,但这里有一个计划草案:

  1. 使用Firebase CLI设置项目并将其连接到Firebase.
  2. 安装所需的Flutter 组件并仔细阅读他们的文档.
  3. 在项目的根目录下创建一个functions文件夹,并安装NPM依赖项("Firebase-admin"、"Firebase-Functions"、"googleapis"等).
  4. src/index.ts文件中编写您的函数
  5. 将这些功能部署到您的Firebase帐户.
  6. 根据需要调用应用程序代码中的函数.

下面是index.ts中与IAP相关的典型FB函数的外观:

export const loadProducts = functions
  .region('europe-west1', 'us-central1')
  .https.onCall(async (data) => {
    const packageName: string = data.packageName;

    try {
      await authClient.authorize();
      const res = await playDeveloperApiClient.inappproducts.list({
        packageName: packageName,
      });
      const activeProducts = res.data.inappproduct?.filter(
        (product) => product.status == 'active'
      );

      if (res.status === 200) {
        return {
          data: activeProducts,
          status: 200,
          message: 'Product list fetch successful!',
        };
      }
    } catch (error) {
      console.log('CloudFunction error: ', error);
    }

    return {
      status: 500,
      message: 'Failed to fetch product list. Try again!',
    };
  });

下面是你在你的应用程序中调用它的方式:

final packageName = appInfo.packageName;
      final httpsCallable = fbFunctions.httpsCallable('loadProducts');

      httpsCallable.call({'packageName': packageName}).then(
        (rawResult) async {
          final resultMap = Map<String, dynamic>.from(rawResult.data as Map);
          final result = FbFunctionResult.fromJson(resultMap);
          final isProductListFetched = result.status == 200;

          if (isProductListFetched && result.data != null) {
            final productList = result.data! as List<dynamic>;
            // ignore: avoid_dynamic_calls
            final productIdsSet = productList.map((e) => e['sku'] as String).toSet();
            final productDetailsList = await loadProducts(productIdsSet);

            if (isMounted() && productDetailsList != null) {
              products.value = productDetailsList;
            }
          }
        },
      );

这是可行的,但这确实需要努力和勇气.因此,如果时间有限,你只需要完成工作,那么 Select 第三方服务可能会更好.否则,请抓住机会更多地了解Google Play API和IAP的内部工作原理.

这是一张good article美元的钞票,尽管已经过时了.

Flutter相关问答推荐

当MyChangeNotifier更改时如何计算函数,而无需在构建方法中进行不必要的调用- Flutter

在Flutter 中实现中小型应用程序栏标题

通过Ffltter应用程序与Docker服务器进行交互以进行身份验证

应为Map String,dynamic类型的值,但得到的值为type()= Map String,dynamic'

Dart 和 flutter 错误无法在您的 PATH 中找到 git

Flutter Dismissible 不会在 startToEnd 滑动时被关闭

如何使Flutter 边框宽度在外面而不是在里面?

如何从Firebase登录获取用户信息,如电话号码、出生日期和性别

在允许屏幕 Select 和点击的同时保持通用对话框显示

通过在父窗口小部件功能上设置状态来浏览屏幕

启动画面中的淡入淡出图像

Flutter canvas 绘制不同 colored颜色 的原始点

Flutter - 展开图标无法正常工作

Flutter 错误:OutletListModel类型的值不能分配给List类型的变量?

如何在两个不同的路由(屏幕)之间正确设置 BlocProvider?

访问 AsyncSnapshot 中的嵌套属性

有没有办法为文本中的下划线创建自定义样式?

如何根据字符串值动态构建和显示小部件?

http响应在Flutter 中返回307

如何在 CircleAvatar 中使用 Stack