【Flutter】RevenueCatの Products / Packages / Entitlements / Offerings がわからん！！！

[RevenueCat](https://www.revenuecat.com/)は、アプリ内課金やサブスクリプション管理を簡単にするための強力なツールです。FlutterでRevenueCatを使ってサブスクリプションを実装する際、特に難しいのが以下の4つの概念です。

1. **Products (商品)**
2. **Packages (パッケージ)**
3. **Entitlements (エンタイトルメント)**
4. **Offerings (オファリング)**

公式ドキュメントにこれらの説明が載っていますが、そもそもが難しいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870340/c8487eda-3fc2-4d88-904d-7b0a7b2bebde.png)


この記事では、これらの概念を具体例とともに分かりやすく解説し、Flutterでの実装コードを紹介します。

---

## 1. Products (商品)

**Product** は実際にユーザーが購入するアイテムです。例えば、1ヶ月間のプレミアム会員権や、広告を消すための一回限りの購入アイテムが該当します。

### 具体例
- **Monthly Premium Subscription**: 1ヶ月間のプレミアム機能を使えるサブスクリプション。
- **Remove Ads**: アプリ内の広告を永久に削除する一回限りの購入アイテム。

### Flutterコード例

まず、`PurchasesFlutter`パッケージを導入します。以下は、Productsの取得方法です。

```dart
import 'package:purchases_flutter/purchases_flutter.dart';

Future<void> fetchProducts() async {
  try {
    // RevenueCatに登録されている商品一覧を取得
    List<StoreProduct> products = await Purchases.getProducts(['monthly_premium', 'remove_ads']);
    for (var product in products) {
      print('Product: ${product.title} - ${product.priceString}');
    }
  } catch (e) {
    print('Failed to fetch products: $e');
  }
}
```

## 2. Packages (パッケージ)

Package は、同じ内容の商品を異なるプラットフォームや異なる価格プランで提供する場合に使います。例えば、App StoreやGoogle Playで同じ商品を提供する際、価格や期間が異なる場合があります。これらをまとめて1つのエンタイトルメントに紐づけることができます。

### 具体例
- Monthly Premium (App Store): iOS向けの1ヶ月プレミアム。
- Monthly Premium (Google Play): Android向けの1ヶ月プレミアム。

### Flutterコード例

パッケージはgetOfferings()メソッドを使用して取得できます。

```dart
Future<void> fetchPackages() async {
  try {
    Offerings offerings = await Purchases.getOfferings();
    if (offerings.current != null) {
      List<Package> availablePackages = offerings.current!.availablePackages;
      for (var package in availablePackages) {
        print('Package: ${package.packageType} - ${package.product.title}');
      }
    }
  } catch (e) {
    print('Failed to fetch packages: $e');
  }
}
```


## 3. Entitlements (エンタイトルメント)
Entitlement は、サブスクリプションを購入したユーザーが得られる権利や機能のことです。ユーザーが特定のサブスクリプションを購入した後に、アプリ内で何ができるかを制御します。

### 具体例
- Premium Access: プレミアムユーザー向けに特別なコンテンツや機能にアクセスできる権利。
- Ads Free Experience: 広告なしでアプリを利用できる権利。

### Flutterコード例
以下のコードでは、ユーザーが購入したエンタイトルメントの情報を取得し、それに基づいてプレミアム機能をアンロックします。

```dart
Future<void> checkEntitlements() async {
  try {
    CustomerInfo customerInfo = await Purchases.getCustomerInfo();
    EntitlementInfo? entitlement = customerInfo.entitlements.all['premium_access'];
    if (entitlement != null && entitlement.isActive) {
      print('User has premium access');
      // プレミアム機能をアンロック
    } else {
      print('User does not have premium access');
    }
  } catch (e) {
    print('Failed to check entitlements: $e');
  }
}
```


## 4. Offerings (オファリング)
Offering は、異なる時期に異なる商品を提供する際に使います。例えば、通常時は通常価格で商品を販売し、キャンペーン期間中には割引価格で提供する場合、これをOfferingで管理します。

### 具体例
- Regular Offering: 通常価格のプレミアムサブスクリプション。
- Campaign Offering: 期間限定の割引サブスクリプション。

### Flutterコード例
オファリングを取得して、ユーザーに適切なオファーを表示するには以下のようにします。

```dart
Future<void> fetchOfferings() async {
  try {
    Offerings offerings = await Purchases.getOfferings();
    Offering? currentOffering = offerings.current;
    if (currentOffering != null) {
      for (var package in currentOffering.availablePackages) {
        print('Offering: ${currentOffering.identifier}, Package: ${package.packageType}');
        // ユーザーにパッケージを表示
      }
    }
  } catch (e) {
    print('Failed to fetch offerings: $e');
  }
}
```


## 5. まとめ
RevenueCatを使ったFlutterでのサブスクリプション実装には、Products、Packages、Entitlements、Offeringsといった概念が絡み合っていますが、それぞれの役割を理解することでスムーズに実装が進みます。この記事で解説したコード例を参考に、RevenueCatの強力な機能を活用してアプリにサブスクリプションを導入してみてください。

良いサブスクリプションライフを！！！

## 999. 参考

https://www.revenuecat.com/docs/getting-started/entitlements

https://pub.dev/packages/purchases_flutter

https://zenn.dev/hal1986/books/react-native-monetize/viewer/7_revenuecat_products