Flutter - フロー & ペイウォールイベントの処理

このガイドでは、購入・復元・プロダクト選択・レンダリングのイベント処理について説明します。ビューを閉じる処理とリンクを開く処理は、デフォルトの flowViewDidPerformAction 実装によって行われます。これらをオーバーライドしたり、カスタムボタンアクションを処理したりする方法については、ボタンアクションの処理に関するガイドをご覧ください。

ビルダーで設定したフローやペイウォールは、購入や復元のために追加のコードは不要です。ただし、アプリが応答できるイベントがいくつか生成されます。これらのイベントには、ボタン押下(閉じるボタン、URL、プロダクト選択など)や、フローまたはペイウォール上での購入関連アクションの通知が含まれます。これらのイベントへの対応方法については、以下をご確認ください。

モバイルアプリ内でフローまたはペイウォール画面上の処理を制御・監視するには、AdaptyUIFlowsEventsObserver のメソッドを実装し、画面を表示する前にオブザーバーを設定してください。

AdaptyUI().setFlowsEventsObserver(this);

3つのオブザーバーメソッドは必須です — flowViewDidFinishPurchaseflowViewDidFinishRestoreflowViewDidReceiveError がないとクラスがコンパイルされません。その他のメソッドはすべて任意です。設定済みのオブザーバーを解除するには、setFlowsEventsObservernull を渡してください。

Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演しているサンプルアプリをご覧ください。

以下のイベント例では、各オブジェクトで使用できるプロパティをコメント内の例示値とともに示しています。

ユーザー生成イベント

画面表示

このメソッドは、フローまたはペイウォールのビューが画面に表示されたときに呼び出されます。

iOS では、ユーザーがペイウォール内のウェブペイウォールボタンをタップし、アプリ内ブラウザでウェブペイウォールが開いたときにも呼び出されます。

void flowViewDidAppear(AdaptyUIFlowView view) {
}

画面非表示

このメソッドは、フローまたはペイウォールのビューが画面から消えたときに呼び出されます。

iOSでは、ペイウォールのアプリ内ブラウザから開いたウェブペイウォールが画面から消えた場合にも呼び出されます。

void flowViewDidDisappear(AdaptyUIFlowView view) {
}

プロダクトの選択

ユーザーまたはシステムによってプロダクトが選択された場合、このメソッドが呼び出されます:

void flowViewDidSelectProduct(AdaptyUIFlowView view, String productId) {
}
イベントの例(クリックして展開)
void flowViewDidSelectProduct(AdaptyUIFlowView view, String productId) {
  // productId is a String:
  productId; // 'premium_monthly'
}

購入の開始

ユーザーが購入プロセスを開始すると、このメソッドが呼び出されます:

void flowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) {
}
イベントの例(クリックして展開)
void flowViewDidStartPurchase(AdaptyUIFlowView view, AdaptyPaywallProduct product) {
  // product — AdaptyPaywallProduct:
  product.vendorProductId;        // 'premium_monthly'
  product.localizedTitle;         // 'Premium Monthly'
  product.localizedDescription;   // 'Premium subscription for 1 month'
  product.price.amount;           // 9.99            (double)
  product.price.currencyCode;     // 'USD'
  product.price.localizedString;  // '$9.99'
}

購入完了

このメソッドは必須です。購入が成功したとき、ユーザーが購入をキャンセルしたとき、または購入が保留中と判断されたときに呼び出されます。

void flowViewDidFinishPurchase(AdaptyUIFlowView view, 
                               AdaptyPaywallProduct product, 
                               AdaptyPurchaseResult purchaseResult) {
    switch (purchaseResult) {
      case AdaptyPurchaseResultSuccess(profile: final profile):
        // successful purchase
        break;
      case AdaptyPurchaseResultPending():
        // purchase is pending
        break;
      case AdaptyPurchaseResultUserCancelled():
        // user cancelled the purchase
        break;
      default:
        break;
    }
}
イベントの例(クリックして展開)
void flowViewDidFinishPurchase(AdaptyUIFlowView view,
                               AdaptyPaywallProduct product,
                               AdaptyPurchaseResult purchaseResult) {
  // product — AdaptyPaywallProduct:
  product.vendorProductId; // 'premium_monthly'

  switch (purchaseResult) {
    case AdaptyPurchaseResultSuccess(profile: final profile):
      // profile — AdaptyProfile:
      profile.accessLevels['premium']?.isActive;  // true
      profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
      break;
    case AdaptyPurchaseResultPending():
      // no additional data
      break;
    case AdaptyPurchaseResultUserCancelled():
      // no additional data
      break;
  }
}

v3 とは異なり、このメソッドにはデフォルトの動作がありません。購入が成功しても画面は自動的に閉じられません。次の動作は自分で決める必要があります。フローを続けるか、view.dismiss() を呼び出してください。画面を閉じる方法については、ボタンアクションへの対応を参照してください。

ウェブ決済ナビゲーションの完了

このメソッドは、特定のプロダクトに対してウェブペイウォールを開こうとした後に呼び出されます。ナビゲーションの成功・失敗に関わらず、両方のケースで呼び出されます。

void flowViewDidFinishWebPaymentNavigation(AdaptyUIFlowView view, 
                                           AdaptyPaywallProduct? product, 
                                           AdaptyError? error) {
}

パラメーター:

パラメーター説明
productウェブペイウォールが開かれた AdaptyPaywallProductnull の場合があります。
errorウェブペイウォールのナビゲーションに失敗した場合は AdaptyError オブジェクト。成功した場合は null

購入失敗

このメソッドは、購入が失敗した場合(例:決済エラーやネットワークエラー)に呼び出されます。ユーザーが自らキャンセルした場合や保留中のトランザクションには呼び出されません—それらはflowViewDidFinishPurchaseで処理されます:

void flowViewDidFailPurchase(AdaptyUIFlowView view, 
                             AdaptyPaywallProduct product, 
                             AdaptyError error) {
}

復元の開始

ユーザーが復元プロセスを開始した場合、このメソッドが呼び出されます:

void flowViewDidStartRestore(AdaptyUIFlowView view) {
}

復元の成功

このメソッドは必須です。購入の復元が成功した場合に呼び出されます:

void flowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) {
}
イベントの例(クリックして展開)
void flowViewDidFinishRestore(AdaptyUIFlowView view, AdaptyProfile profile) {
  // profile — AdaptyProfile:
  profile.accessLevels['premium']?.isActive;            // true
  profile.accessLevels['premium']?.expiresAt;           // DateTime(2027, 2, 15, 10, 30)
  profile.subscriptions['premium_monthly']?.isActive;   // true
  profile.subscriptions['premium_monthly']?.expiresAt;  // DateTime(2027, 2, 15, 10, 30)
}

ユーザーが必要な accessLevel を持っている場合は、画面を閉じることをお勧めします。確認方法については サブスクリプションステータス を、画面を閉じる方法については ボタン操作への対応 を参照してください。

リストアの失敗

購入のリストアに失敗した場合、このメソッドが呼び出されます:

void flowViewDidFailRestore(AdaptyUIFlowView view, AdaptyError error) {
}

データの取得とレンダリング

プロダクト読み込みエラー

初期化時にプロダクト配列を渡さなかった場合、AdaptyUI はサーバーから必要なオブジェクトを自動的に取得します。この処理が失敗した場合、AdaptyUI は次のメソッドを呼び出してエラーを通知します。

void flowViewDidFailLoadingProducts(AdaptyUIFlowView view, AdaptyError error) {
}

ビューのエラー

このメソッドは必須です。v3 の paywallViewDidFailRendering メソッドの代替となります。インターフェースのレンダリング中に発生したエラーやその他のビューエラーは、このメソッドを呼び出すことで報告されます。実装後の画面の閉じ方はご自身で決定できますが、このようなエラー時にはビューを閉じることをお勧めします。これは、オブザーバーが設定されていない場合の SDK 組み込みのデフォルト動作でもあります:

void flowViewDidReceiveError(AdaptyUIFlowView view, AdaptyError error) {
  // log the error and dismiss the broken view
  view.dismiss();
}

通常、レンダリングエラーは発生しないため、もし遭遇した場合はご連絡ください。

アナリティクスイベント

オプションの flowViewDidReceiveAnalyticEvent メソッドは、フローからのカスタムアナリティクスイベント用に予約されています。現時点ではフローからこのコードへのイベント送信は行われないため、実装は不要です。

オブザーバーモードで購入を処理する

SDKをオブザーバーモードで有効化し、Adaptyがレンダリングするフローやペイウォールを表示している場合、SDKは代わりに購入処理を行いません。ユーザーが購入ボタンまたは復元ボタンをタップすると、SDKは代わりにAdaptyUIObserverModeResolverを呼び出します。詳細なセットアップ手順については、オブザーバーモードでフローを表示するを参照してください。

システムリクエストの処理

AdaptyUISystemRequestsHandlerAdaptyUI().setSystemRequestsHandler(...) で登録)は、フローからのシステムリクエスト(プッシュ通知やカメラアクセスなどのOS権限プロンプト、App Storeレビューリクエスト)のために予約されています。現時点ではフローがこれらのリクエストをトリガーすることはないため、ハンドラーを登録する必要はありません。 handlePermission はクラスの必須メソッドです。独自のコードでパーミッションをリクエストし、AdaptyUIPermissionResult.granted() または AdaptyUIPermissionResult.denied() を返してください。handleAppReviewRequest は任意です。

このガイドでは、購入・復元・プロダクト選択・ペイウォールレンダリングのイベント処理について説明します。ボタン操作(ペイウォールを閉じる、リンクを開くなど)の実装も必要です。詳細はボタンアクションの処理に関するガイドをご参照ください。

ペイウォールビルダーで設定されたペイウォールは、購入や復元のために追加のコードは不要です。ただし、アプリが応答できるいくつかのイベントが生成されます。これらのイベントには、ボタン押下(閉じるボタン、URL、プロダクト選択など)や、ペイウォール上での購入関連アクションの通知が含まれます。これらのイベントへの応答方法については、以下をご覧ください。

このガイドは、Adapty SDK v3.0 以降が必要な新しいペイウォールビルダーのペイウォール専用です。

ペイウォール画面で発生するプロセスを制御または監視するには、AdaptyUIPaywallsEventsObserver のメソッドを実装し、画面を表示する前にオブザーバーを設定してください。

AdaptyUI().setPaywallsEventsObserver(this);

Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演しているサンプルアプリをご覧ください。

以下のイベントの例では、各オブジェクトで利用可能なプロパティと、コメント内の説明用の値を示しています。

ユーザー生成イベント

ペイウォールが表示された

このメソッドは、ペイウォールビューが画面に表示されたときに呼び出されます。

iOS では、ユーザーがペイウォール内のウェブペイウォールボタンをタップしてインアプリブラウザでウェブペイウォールが開いた場合にも呼び出されます。

void paywallViewDidAppear(AdaptyUIPaywallView view) {
}

ペイウォールが非表示になった

このメソッドは、ペイウォールビューが画面から閉じられたときに呼び出されます。

iOSでは、ペイウォール内のアプリ内ブラウザで開いたウェブペイウォールが画面から消えたときにも呼び出されます。

void paywallViewDidDisappear(AdaptyUIPaywallView view) {
}

プロダクトの選択

ユーザーまたはシステムによってプロダクトが購入のために選択されると、このメソッドが呼び出されます:

void paywallViewDidSelectProduct(AdaptyUIPaywallView view, String productId) {
}
イベントの例(クリックして展開)
void paywallViewDidSelectProduct(AdaptyUIPaywallView view, String productId) {
  // productId is a String:
  productId; // 'premium_monthly'
}

購入開始

ユーザーが購入プロセスを開始すると、このメソッドが呼び出されます:

void paywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) {
}
イベントの例(クリックして展開)
void paywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) {
  // product — AdaptyPaywallProduct:
  product.vendorProductId;        // 'premium_monthly'
  product.localizedTitle;         // 'Premium Monthly'
  product.localizedDescription;   // 'Premium subscription for 1 month'
  product.price.amount;           // 9.99            (double)
  product.price.currencyCode;     // 'USD'
  product.price.localizedString;  // '$9.99'
}

購入完了

この方法は、購入が成功した場合、ユーザーが購入をキャンセルした場合、または購入が保留中と判断された場合に呼び出されます。

void paywallViewDidFinishPurchase(AdaptyUIPaywallView view, 
                                  AdaptyPaywallProduct product, 
                                  AdaptyPurchaseResult purchaseResult) {
    switch (purchaseResult) {
      case AdaptyPurchaseResultSuccess(profile: final profile):
        // successful purchase
        break;
      case AdaptyPurchaseResultPending():
        // purchase is pending
        break;
      case AdaptyPurchaseResultUserCancelled():
        // user cancelled the purchase
        break;
      default:
        break;
    }
}
イベントの例(クリックして展開)
void paywallViewDidFinishPurchase(AdaptyUIPaywallView view,
                                  AdaptyPaywallProduct product,
                                  AdaptyPurchaseResult purchaseResult) {
  // product — AdaptyPaywallProduct:
  product.vendorProductId; // 'premium_monthly'

  switch (purchaseResult) {
    case AdaptyPurchaseResultSuccess(profile: final profile):
      // profile — AdaptyProfile:
      profile.accessLevels['premium']?.isActive;  // true
      profile.accessLevels['premium']?.expiresAt; // DateTime(2027, 2, 15, 10, 30)
      break;
    case AdaptyPurchaseResultPending():
      // no additional data
      break;
    case AdaptyPurchaseResultUserCancelled():
      // no additional data
      break;
  }
}

このような場合はスクリーンを閉じることをおすすめします。ペイウォール画面を閉じる方法については、ボタンアクションへの対応を参照してください。

ウェブ決済ナビゲーションの完了

このメソッドは、特定のプロダクトに対してウェブペイウォールを開こうとした後に呼び出されます。ナビゲーションの成功・失敗いずれの場合も対象となります。

void paywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view, 
                                               AdaptyPaywallProduct? product, 
                                               AdaptyError? error) {
}

パラメーター:

パラメーター説明
productウェブペイウォールが開かれた AdaptyPaywallProductnull の場合があります。
errorウェブペイウォールのナビゲーションに失敗した場合は AdaptyError オブジェクト。成功した場合は null
イベント例(クリックして展開)
void paywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view,
                                               AdaptyPaywallProduct? product,
                                               AdaptyError? error) {
  // product — AdaptyPaywallProduct?:
  product?.vendorProductId; // 'premium_monthly'

  if (error == null) {
    // navigation succeeded
  } else {
    // error — AdaptyError:
    error.code;    // AdaptyErrorCode.networkFailed (2005)
    error.message; // 'Network request failed'
    error.detail;  // platform-specific underlying error, or null
  }
}

購入失敗

このメソッドは、支払いの問題やネットワークエラーなどにより購入が失敗した場合に呼び出されます。ユーザーが自発的にキャンセルした場合やペンディング中のトランザクションには呼び出されません。それらは paywallViewDidFinishPurchase で処理されます:

void paywallViewDidFailPurchase(AdaptyUIPaywallView view, 
                                AdaptyPaywallProduct product, 
                                AdaptyError error) {
}
イベントの例(クリックして展開)
void paywallViewDidFailPurchase(AdaptyUIPaywallView view,
                                AdaptyPaywallProduct product,
                                AdaptyError error) {
  // product — AdaptyPaywallProduct:
  product.vendorProductId; // 'premium_monthly'

  // error — AdaptyError:
  error.code;    // AdaptyErrorCode.productPurchaseFailed (1006)
  error.message; // 'Product purchase failed.'
  error.detail;  // platform-specific underlying error, or null
}

復元の開始

ユーザーが復元プロセスを開始すると、このメソッドが呼び出されます:

void paywallViewDidStartRestore(AdaptyUIPaywallView view) {
}

復元成功

購入の復元が成功すると、このメソッドが呼び出されます:

void paywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) {
}
イベント例(クリックして展開)
void paywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) {
  // profile — AdaptyProfile:
  profile.accessLevels['premium']?.isActive;            // true
  profile.accessLevels['premium']?.expiresAt;           // DateTime(2027, 2, 15, 10, 30)
  profile.subscriptions['premium_monthly']?.isActive;   // true
  profile.subscriptions['premium_monthly']?.expiresAt;  // DateTime(2027, 2, 15, 10, 30)
}

ユーザーが必要な accessLevel を持っている場合は、画面を閉じることを推奨します。確認方法については サブスクリプションのステータス を、ペイウォール画面を閉じる方法については ボタン操作への対応 を参照してください。

復元の失敗

購入の復元に失敗した場合、このメソッドが呼び出されます:

void paywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) {
}
イベントの例(クリックして展開)
void paywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) {
  // error — AdaptyError:
  error.code;    // AdaptyErrorCode.receiveRestoredTransactionsFailed (1011)
  error.message; // 'Error occurred in the process of restoring purchases.'
  error.detail;  // platform-specific underlying error, or null
}

データの取得とレンダリング

プロダクト読み込みエラー

初期化時にプロダクト配列を渡さなかった場合、AdaptyUIはサーバーから必要なオブジェクトを自動的に取得します。この処理が失敗した場合、AdaptyUIは以下のメソッドを呼び出してエラーを通知します:

void paywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) {
}
イベント例(クリックして展開)
void paywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) {
  // error — AdaptyError:
  error.code;    // AdaptyErrorCode.productRequestFailed (1002)
  error.message; // 'Unable to fetch available In-App Purchase products at the moment.'
  error.detail;  // platform-specific underlying error, or null
}

レンダリングエラー

インターフェースのレンダリング中にエラーが発生した場合、このメソッドを呼び出すことでエラーが報告されます。デフォルトでは(v3.15.2以降)、レンダリングエラーが発生するとペイウォールは自動的に閉じられますが、必要に応じてこの動作をオーバーライドできます。

void paywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) {
  // Default behavior: view.dismiss()
  // Override with custom logic if needed, for example:
  // - Log the error
  // - Show an error message to the user
}
イベントの例(クリックして展開)
void paywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) {
  // error — AdaptyError:
  error.code;    // AdaptyErrorCode.jsException (4105)
  error.message; // 'An exception was thrown from JS during AdaptyUI flow execution.'
  error.detail;  // platform-specific underlying error, or null

  // Default behavior: view.dismiss()
}

通常の状況では、このようなエラーは発生しないはずです。もし遭遇した場合は、ぜひご連絡ください。