チュートリアル: アプリ内購入をFlutterアプリに実装する方法
Updated: 3月 20, 2023
Flutterは、Googleが開発した比較的新しいフレームワークで、クロスプラットフォーム アプリをすばやく作成できます。もう1つの一般的なフレームワークは、FacebookのReact Nativeです。 Flutterアプリは、iOSとAndroidの両方を一度に構築できます。そのため、購入ライブラリは、StoreKitとBilling Libraryの両方と互換性がある必要があります。
アーキテクチャに関しては、Adapty Flutter SDKを含むすべての支払いプラグインは、ネイティブライブラリであるStoreKitとBilling Libraryのラッパーです。この場合、これは独自のAdapty iOSおよびAndroid SDKライブラリのラッパーです。
Flutterベースのアプリでのアプリ内購入 (in-app purchase) 用のオープンソースライブラリ
Flutterアプリでの購入の一般的なソリューションは、オープンソースプラグインの in_app_purchase (Flutter開発チームによって開発) とflutter_inapp_purchase (非公式プラグイン) です。
これらのプラグインは、クライアントサイドの購入を実装するために作成されました。サーバーサイド (server-side) のレシート検証 (receipt validation) 機能はありません。レシートを検証して、更新、返金、試用 (trial)、キャンセルなどに関する支払い分析を収集するには、独自のサーバーサイドインフラストラクチャを設定する必要があります。
さらに、これらのライブラリは通常、ストアの新しい機能をサポートするまで時間がかかります。例として、現時点ではプロモーションオファー (promo offer)、従量課金制 (pay as you go) の機能、iOSの前払い (pay upfront) 機能がありません。
当社のライブラリはサーバーと通信するため、次のすべてが揃っています。
● 購入サーバーの検証
● ネイティブ支払い機能の完全なサポート
● DRY構文
● サブスクリプション (定期購入) (subscription) と購入の分析およびその他のデータ収集
● A/Bテスト (A/B test) と、購入、価格設定、プロモーション期間の簡単な実験
● ペイウォール (paywall) とプロモーションオファー
簡潔で読みやすい記事にするために、Flutterアプリの購入について説明する前に、実行すべき手順について以前に公開した記事のリンクを記載しておきます。
iOSおよびAndroidでの購入の作成
まず、デペロッパーアカウントをお持ちでない場合は作成してください。次に、iOSとAndroidの両方で毎週の購入を作成する必要があります。これを行う方法については、以前の記事で取り上げました。
完了したら、プロジェクトの作成と設定を開始できます。
プロジェクトの作成と設定
実装と当社のシステムの両方で購入を実行するには、以下の技術的な詳細情報を入力していただく必要があります。
iOSの場合、次のことを行う必要があります。
● バンドルIDを指定して、Adaptyプロジェクトをアプリに紐付ける
● App Store ConnectでApp Storeサーバ通知を設定して、サブスクリプションイベント(event) に関する通知を受け取れるようにします。
● AdaptyサーバーがAppleのサーバーへの接続を確立して、レシートを検証するために使用するApp Store共有シークレット (shared secret) を指定します。
Androidの場合、パッケージ名とサービスアカウントキーファイルの両方を指定する必要があります。パッケージ名は、Android版のiOSのバンドルIDです。コードで使用されているものと同じ名前を使用する必要があります。これは、android.defaultConfig.applicationIdディレクトリの/android/app/build.gradleファイルで確認できます。
プロダクトとペイウォールの設定
Adaptyプロダクトは、さまざまなストアのプロダクトを包括します。ここではApp StoreとGoogle Playのみを取り上げますが、今後他のストアも紹介していきます。このアプローチの目的は、クロスプラットフォームの統計収集を容易にして、識別子ではなくトップレベルのエンティティを操作できるようにすることです。
ペイウォールは、プロダクトの配列とリモート設定 (remote config) ファイル (ダッシュボードで指定したメタデータを含むJSONファイル) を含む抽象的なエンティティです。ペイウォールIDをアプリにハードコーディングします。このIDは、設定ファイルとプロダクトデータを取得するために使用されます。アプリを更新しなくても、これらの両方を編集できます。通常のシナリオでは、ペイウォールを設計して、当社から受け取ったデータを入力します。
プロダクトの作成
Google Play ConsoleとApp Store Connectを使用して、毎週のサブスクリプション (定期購入) に対応するプロダクトを作成してみましょう。支払いシステムから取得できる、対応するプロダクトのIDを入力します。 App Store ConnectにはAPIがないため、一度のみ手動で行う必要があることに注意してください。
ペイウォールの作成
ペイウォールを作成する際の重要な点は、便利な形式でIDを指定できることです。この識別子は、後でSDKによってペイウォールデータをリクエストするために使用されます。これは、良いアプローチになるでしょう。このアーキテクチャでは、クライアントサイドでプロダクトをハードコーディングする必要はありません。プロダクト管理、バージョニング、テストなどを柔軟に行うことができます。代替のオプションは、一連の組み込みプロダクトを含むFirebase JSON です。ただし、エラー検証に対応していないため、利便性に欠けます。
以上です。プロダクトとペイウォールを作成したので、最初の購入の準備が整いました。 SDKのインストールに進みましょう。
SDKの使用方法
サブスクリプション (定期購入) を設定して使用するために必要な主な機能を見てみましょう。
ライブラリのインストール
まず、adapty_flutterライブラリをプロジェクトに追加する必要があります。これを行うには、次の依存関係をpubspec.yamlファイルに追加します。
dependencies:
adapty_flutter: ^1.0.4
その後、以下のコードを実行します。
flutter pub get
ここから、次のようにAdapty SDKをアプリにインポートできます。
import 'package:adapty_flutter/adapty_flutter.dart';
設定
Adaptyで動作するようにアプリを設定する必要があります。その際には、パブリック SDKキーを使用して、AdaptyPublicSdkKeyフラグをInfo.plist (iOS の場合) またはAndroidManifest.xml (Android の場合) に追加します。
Adapty設定でSDKキーを確認できます。
Info.plist:
<dict>
...
<key>AdaptyPublicSdkKey</key>
AndroidManifest.xml:
<application ...>
...
<meta-data
android:name="AdaptyPublicSdkKey"
android:value="PUBLIC_SDK_KEY" />
</application>
次に、Flutter側でこのコードを呼び出してSDKを有効にします (プロジェクトのmain()メソッドなど)。
void main() {
runZoned(() async {
Adapty.activate();
final installId = await Service.getOrCreateInstallId();
await Adapty.identify(***customer-user-id***);
await Adapty.setLogLevel(AdaptyLogLevel.verbose);
runApp(MyApp());
});
}
void Adapty.activate()関数は、Adapty_Flutterライブラリを有効にします。
Future<bool> Adapty.identify(String customerUserId)
Adapty.identifyを使用すると、ユーザーのIDを取得できます。 AdaptyはそのIDをサブスクリプション (定期購入) および分析システムに送信して、イベントをこのプロファイルに割り当てます。また、プロファイルのcustomerUserIdでクライアントを見つけることもできます。
Adaptyは、エラーメッセージやその他の重要なデータをログに記録して、現状を把握するのに役立ちます。
Future<void> Adapty.identify(AdaptyLogLevel value)
この関数を使用すると、想定される3つの値のいずれかを選択できます。
● AdaptyLogLevel.none (デフォルト設定):何も記録されません。
● AdaptyLogLevel.errors:エラーメッセージのみが記録されます。
● AdaptyLogLevel.verbose:メソッド呼び出し、APIリクエストと応答、エラーメッセージがログに記録されます。
ペイウォールの取得
ペイウォールリストを取得するには、次のコードを実行します。
try {
final GetPaywallsResult getPaywallsResult = await Adapty.getPaywalls(forceUpdate: Bool);
final List<AdaptyPaywall> paywalls = getPaywallsResult.paywalls;
} on AdaptyError(adaptyError) {}
catch(e) {}
Adapty.getPaywalls()関数は、以下を含むGetPaywallsResultオブジェクトを返します。
● ペイウォール:ペイウォール配列 (AdaptyPaywall)。モデルには、プロダクトリスト、ペイウォールID、カスタムペイロードなど、その他いくつかの値が含まれています。
購入
前回の手順で、ペイウォール配列を取得しました。次に、これらのプロダクトをUIに表示するために必要なものを確認します。このペイウォールの名前がyour_paywall_idであるとします
final List<AdaptyPaywall>? paywalls = getPaywallsResult.paywalls;
myPaywall = paywalls?.firstWhere((paywall) => paywall.developerId == "your_paywall_id", orElse: null);
次に、productsフィールドのproduct配列を使用して、すべての項目を表示します。ユーザーが最初のプロダクトを購入したいとしましょう。わかりやすくするために、product配列の最初の項目であると仮定します。
final AdaptyProduct? product = myPaywall?.products?.first;
購入を開始するには、makePurchaseResult関数を呼び出します (SDKからすべてのエラーメッセージを引き続き受け取るには、必ずtry-catchブロックでラップしてください)。
final MakePurchaseResult makePurchaseResult = await Adapty.makePurchase(product);
関数が正常に実行されると、makePurchaseResult変数はその結果を値として受け取ります。購入完了後にアクセスレベルを確認する方法は、次のとおりです。
final isPremium = makePurchaseResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false;
AdaptyErrorCode.paymentCancelledは、ユーザー自身で購入をキャンセルしたことを意味します。これは、実際のエラーメッセージではありません。
購入を復元するには、.restorePurchases()メソッドを使用します。
try {
final RestorePurchasesResult restorePurchasesResult = await Adapty.restorePurchases();
// "premium" is an identifier of default access level
if (restorePurchasesResult?.purchaserInfo?.accessLevels['premium']?.isActive ?? false) {
// grant access to premium features
}
} on AdaptyError catch (adaptyError) {}
catch (e) {}
MakePurchaseResultオブジェクトとRestorePurchasesResultオブジェクトの両方にpurchaserInfoが含まれていることを考慮してください。このオブジェクトには、アクセス レベル、サブスクリプション (定期購入)、購入に関するデータが含まれています。通常、アクセスレベルを確認するだけで、ユーザーがアプリの有料機能を利用できるかどうかを判断できます。
サブスクリプション (定期購入) のステータス
先行するトランザクションチェーン全体を確認する必要がないように、「アクセスレベル」という用語を導入しています。アクセスレベルは、ユーザーが利用可能なアプリの機能の範囲を説明するフラグです。まだ有料プランを購入していない場合、アクセスレベルは「null」になります。それ以外の場合は、プロダクトで指定した値になります。
たとえば、シルバーとゴールドの2つのアクセスレベルを設定できます。各レベルに応じて、購入すると異なるアクセスレベルと機能を利用できるようになります。ほとんどのアプリには、1つのアクセスレベルしかありません。
サブスクリプションがアクティブかどうかを確認するには、ユーザーにアクティブなアクセスレベルがあるかどうかを確認するだけで十分です。.getPurchaserInfo()メソッドを使用して、確認することができます。
try {
AdaptyPurchaserInfo purchaserInfo = await Adapty.getPurchaserInfo();
// "premium" is an identifier of default access level
if (purchaserInfo.accessLevels['premium']?.isActive ?? false) {
// grant access to premium features
}
} on AdaptyError catch (adaptyError) {}
catch (e) {}
.purchaserInfoUpdateStreamストリームに登録すると、サブスクリプショユーザーのアクセスレベルの変更に関する通知をリアルタイムで受け取ることもできます。方法は次のとおりです。
Adapty.purchaserInfoUpdateStream.listen((purchaserInfo) {
print('#Adapty# Purchaser Info Updated');
if (purchaserInfo.accessLevels['premium'].isActive) {
// grant access to premium features
}
});
まとめ
当社のSDKは、支払いをアプリにすばやく統合できるように設計されています。さらに、A/Bテスト、分析、追加の統合など、必要となる他のすべての手順を効率化できるよう努めています。
お客様の収益が月額10,000ドル未満の場合、すべての購入機能を無料で提供します。数か月にわたって作業負担を軽減して、最も重要なプロダクトに集中できます。