フローとペイウォールのイベントを処理する - Unity
このガイドでは、購入・復元・プロダクト選択・フロー描画に関するイベント処理について説明します。ボタン操作(フローを閉じる、リンクを開くなど)の処理も実装する必要があります。詳細については、フローアクションの処理に関するガイドを参照してください。
フローBuilderやペイウォールビルダーで作成したフローやペイウォールは、購入や復元のために追加のコードは必要ありません。ただし、アプリが応答できるイベントが発生します。イベントには、ボタン押下(閉じるボタン、URL、プロダクト選択など)や、購入関連アクションの通知が含まれます。これらのイベントへの対応方法については、以下をご覧ください。
Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演しているサンプルアプリをご覧ください。
イベントの処理
フロー画面上で発生するプロセスをモバイルアプリ内で制御・監視するには、IAdaptyFlowsEventsListener インターフェースを実装し、Adapty.SetFlowsEventsListener() で登録します。
using UnityEngine;
using AdaptySDK;
public class FlowEventsHandler : MonoBehaviour, IAdaptyFlowsEventsListener
{
void Start()
{
Adapty.SetFlowsEventsListener(this);
}
// Implement all interface methods below
}これらのメソッドには、フローイベントに応答するカスタムロジックを追加します。SDKはこれらに対してデフォルトの動作を適用しません。購入の成功やエラーが発生しても、ビューは自動的に閉じられません。適切なタイミングで view.Dismiss(...) を自分で呼び出してください。
ユーザー生成イベント
フローが表示された
フロービューが画面に表示されたときに呼び出されます。
iOS では、ユーザーがフロー内のウェブペイウォールボタンをタップしてウェブペイウォールがアプリ内ブラウザで開いたときにも呼び出されます。
public void FlowViewDidAppear(AdaptyUIFlowView view) { }フローが非表示になった
フロービューが画面から消えたときに呼び出されます。
iOSでは、フローのアプリ内ブラウザから開かれたウェブペイウォールが画面から消えたときにも呼び出されます。
public void FlowViewDidDisappear(AdaptyUIFlowView view) { }プロダクトの選択
プロダクトが(ユーザーまたはシステムによって)購入のために選択されたときに呼び出されます。
public void FlowViewDidSelectProduct(
AdaptyUIFlowView view,
string productId
) { }イベントの例(クリックして展開)
{
"productId": "premium_monthly"
}購入の開始
ユーザーが購入プロセスを開始したときに呼び出されます。
public void FlowViewDidStartPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product
) { }オブザーバーモードでは、フローから開始された購入は IAdaptyUIObserverModeResolver に配信されます。
イベントの例(クリックして展開)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}購入成功、キャンセル、または保留中の場合
購入が成功した場合、ユーザーが購入をキャンセルした場合、または購入が保留中(例:保護者の承認が必要な場合)に、このメソッドが呼び出されます。ユーザーによるキャンセルや保留中の支払いは、FlowViewDidFailPurchase ではなくこのメソッドをトリガーします。
フローは購入後も閉じずに表示されたままになるため、ユーザーがアクセス権を取得したら view.Dismiss(...) を自分で呼び出してください。
public void FlowViewDidFinishPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) {
switch (purchasedResult.Type) {
case AdaptyPurchaseResultType.Success:
// Check if user has access to premium features
if (purchasedResult.Profile != null
&& purchasedResult.Profile.AccessLevels.TryGetValue("premium", out var premium)
&& premium.IsActive) {
view.Dismiss(null);
}
break;
case AdaptyPurchaseResultType.Pending:
// Handle pending purchase (e.g., user will pay offline with cash)
break;
case AdaptyPurchaseResultType.UserCancelled:
// Handle user cancellation
break;
default:
break;
}
}イベント例(クリックして展開)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "UserCancelled"
}
}
// Pending purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Pending"
}
}購入が成功した場合は、フロー画面を閉じることをお勧めします。
購入失敗
エラーにより購入が失敗した場合、このメソッドが呼び出されます。これには、StoreKit/Google Play Billing のエラー(支払い制限、無効なプロダクト、ネットワーク障害)、トランザクション検証の失敗、およびシステムエラーが含まれます。なお、ユーザーによるキャンセルは FlowViewDidFinishPurchase をキャンセル結果で呼び出し、保留中の支払いはこのメソッドを呼び出しません。
public void FlowViewDidFailPurchase(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }イベント例(クリックして展開)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}復元開始
ユーザーが復元プロセスを開始したときに呼び出されます。
public void FlowViewDidStartRestore(AdaptyUIFlowView view) { }復元成功
購入の復元が成功したときに呼び出されます。フローは、あなたが閉じるまで復元後も開いたままです:
public void FlowViewDidFinishRestore(
AdaptyUIFlowView view,
AdaptyProfile profile
) {
// Check if user has access to premium features
if (profile.AccessLevels.TryGetValue("premium", out var premium) && premium.IsActive) {
view.Dismiss(null);
}
}イベント例(クリックして展開)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}ユーザーが必要な accessLevel を持っている場合は、画面を閉じることを推奨します。確認方法については、サブスクリプションのステータス を参照してください。
復元の失敗
購入の復元が失敗した場合に呼び出されます:
public void FlowViewDidFailRestore(
AdaptyUIFlowView view,
AdaptyError error
) { }イベント例(クリックして展開)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}ウェブ決済のナビゲーション完了
購入のためにウェブペイウォールを開こうとした後(成功・失敗を問わず)、このメソッドが呼び出されます。
public void FlowViewDidFinishWebPaymentNavigation(
AdaptyUIFlowView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }パラメータ:
product: ウェブペイウォールが開かれた(または開こうとした)プロダクト、もしくはnullerror: ウェブペイウォールが正常に開いた場合はnull、失敗した場合はAdaptyError
イベントの例(クリックして展開)
// Successful navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": null
}
// Failed navigation
{
"product": null,
"error": {
"code": "wrong_param",
"message": "Current method is not available for this product",
"details": {
"underlyingError": "Product not configured for web purchases"
}
}
}データ取得とレンダリング
プロダクト読み込みエラー
プロダクトの読み込みに失敗し、AdaptyError が提供されたときに呼び出されます。初期化時にプロダクト配列を渡さなかった場合、AdaptyUI はサーバーから必要なオブジェクトを自動的に取得します。この処理が失敗した場合、AdaptyUI はこのメソッドを呼び出してエラーを報告します。
public void FlowViewDidFailLoadingProducts(
AdaptyUIFlowView view,
AdaptyError error
) { }イベント例(クリックして展開)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}レンダリングおよびランタイムエラー
インターフェースのレンダリング中にエラーが発生した場合、またはその他の購入以外のランタイムエラーが発生した場合、このメソッドによって報告されます。ビューは自動的に閉じられません。必要に応じて view.Dismiss(...) を呼び出してください:
public void FlowViewDidReceiveError(
AdaptyUIFlowView view,
AdaptyError error
) { }イベント例(クリックして展開)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render flow interface",
"details": {
"underlyingError": "Invalid flow configuration"
}
}
}通常の状況では、このようなエラーは発生しないはずです。もし遭遇した場合は、ご連絡ください。
アナリティクスイベント
FlowViewDidReceiveAnalyticEventはフローからのカスタム分析イベント専用です。フローはまだこれらのイベントをコードに送信しないため、メソッドの本体は空のままにしてください。ただし、IAdaptyFlowsEventsListenerはC#インターフェースなので、メソッド自体は必ず実装する必要があります。
public void FlowViewDidReceiveAnalyticEvent(
AdaptyUIFlowView view,
string name,
IDictionary<string, object> @params
) { }システムリクエストの処理
IAdaptyUISystemRequestsHandler(Adapty.SetSystemRequestsHandler(...) で登録)は、フローからのシステムリクエスト(プッシュ通知やカメラアクセスなどの OS 権限プロンプト、アプリレビューリクエストなど)のために予約されています。フローはまだこれらのリクエストをトリガーしないため、ハンドラーを登録する必要はありません。
ナビゲーション
Androidのシステム戻るボタン
Androidのシステム戻るボタン(または戻るジェスチャー)は、FlowViewDidPerformActionにSystemBackアクションとして渡されますが、それだけではフローは閉じられません。ユーザーがフローを終了するには、Closeボタンやビルダーのon_device_backアクションなど、あなたが定義したパスを通る必要があります。システムの戻るボタンでフローを閉じたい場合は、自分でアクションを処理してください:
public void FlowViewDidPerformAction(
AdaptyUIFlowView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
case AdaptyUIUserActionType.SystemBack:
view.Dismiss(null);
break;
default:
// handle other events
break;
}
}フローアクションの完全なリストについては、フローアクションの処理に関するガイドを参照してください。
このガイドでは、購入・復元・プロダクト選択・ペイウォールのレンダリングに関するイベント処理について説明します。ボタン操作(ペイウォールを閉じる、リンクを開くなど)の処理も実装する必要があります。詳しくはボタンアクションの処理に関するガイドをご覧ください。
ペイウォールビルダーで設定したペイウォールは、購入や復元のために追加のコードは不要です。ただし、アプリが反応できるいくつかのイベントが生成されます。これらのイベントには、ボタン押下(閉じるボタン、URL、プロダクト選択など)やペイウォール上での購入関連アクションの通知が含まれます。これらのイベントへの対応方法については、以下をご覧ください。
このガイドは、Adapty SDK v3.3.0 以降が必要な新しいペイウォールビルダーのペイウォール専用です。
Adapty SDK がモバイルアプリにどのように統合されているか、実際の例を見てみませんか?ペイウォールの表示、購入処理、その他の基本機能を含む完全なセットアップを実演しているサンプルアプリをご覧ください。
イベントの処理
モバイルアプリ内のペイウォール画面で発生するプロセスを制御・監視するには、AdaptyPaywallsEventsListener インターフェースを実装します。
using UnityEngine;
using AdaptySDK;
public class PaywallEventsHandler : MonoBehaviour, AdaptyPaywallsEventsListener
{
void Start()
{
Adapty.SetPaywallsEventsListener(this);
}
// Implement all required interface methods below
}ユーザーが生成するイベント
ペイウォールの表示
ペイウォールビューが画面に表示されたときに呼び出されます。
iOS では、ユーザーがペイウォール内のウェブペイウォールボタンをタップして、インアプリブラウザでウェブペイウォールが開いたときにも呼び出されます。
public void PaywallViewDidAppear(AdaptyUIPaywallView view) { }ペイウォールの非表示
ペイウォールビューが画面から閉じられたときに呼び出されます。
iOS では、ペイウォールからインアプリブラウザで開いたウェブペイウォールが画面から消えたときにも呼び出されます。
public void PaywallViewDidDisappear(AdaptyUIPaywallView view) { }プロダクト選択
プロダクトが購入対象として選択されたとき(ユーザーまたはシステムによる)に呼び出されます。
public void PaywallViewDidSelectProduct(
AdaptyUIPaywallView view,
string productId
) { }イベント例(クリックして展開)
{
"productId": "premium_monthly"
}購入開始
ユーザーが購入プロセスを開始したときに呼び出されます。
public void PaywallViewDidStartPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product
) { }イベント例(クリックして展開)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}購入成功・キャンセル・保留
購入が成功した場合、ユーザーが購入をキャンセルした場合、または購入が保留中になった場合に、このメソッドが呼び出されます。ユーザーによるキャンセルや保留中の支払い(保護者の承認が必要な場合など)は、PaywallViewDidFailPurchase ではなくこのメソッドをトリガーします。
public void PaywallViewDidFinishPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyPurchaseResult purchasedResult
) { }イベント例(クリックして展開)
// Successful purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Success",
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
}
}
}
}
// Cancelled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "UserCancelled"
}
}
// Pending purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "Pending"
}
}その場合は画面を閉じることをお勧めします。
購入失敗
エラーにより購入が失敗した場合に、このメソッドが呼び出されます。StoreKit/Google Play Billing のエラー(支払い制限、無効なプロダクト、ネットワーク障害)、トランザクション検証の失敗、システムエラーが含まれます。なお、ユーザーによるキャンセルはキャンセル結果として PaywallViewDidFinishPurchase をトリガーし、保留中の支払いはこのメソッドをトリガーしません。
public void PaywallViewDidFailPurchase(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }イベントの例(クリックして展開)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "purchase_failed",
"message": "Purchase failed due to insufficient funds",
"details": {
"underlyingError": "Insufficient funds in account"
}
}
}リストアの開始
ユーザーがリストアプロセスを開始したときに呼び出されます:
public void PaywallViewDidStartRestore(AdaptyUIPaywallView view) { }復元成功
購入の復元が成功したときに呼び出されます。
public void PaywallViewDidFinishRestore(
AdaptyUIPaywallView view,
AdaptyProfile profile
) { }イベント例(クリックして展開)
{
"profile": {
"accessLevels": {
"premium": {
"id": "premium",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
},
"subscriptions": [
{
"vendorProductId": "premium_monthly",
"isActive": true,
"expiresAt": "2024-02-15T10:30:00Z"
}
]
}
}ユーザーが必要な accessLevel を持っている場合は、画面を閉じることをお勧めします。確認方法については、サブスクリプションのステータスを参照してください。
復元失敗
購入の復元が失敗したときに呼び出されます。
public void PaywallViewDidFailRestore(
AdaptyUIPaywallView view,
AdaptyError error
) { }イベント例(クリックして展開)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}ウェブ支払いナビゲーション完了
購入のためにウェブペイウォールを開こうとした後(成功・失敗に関わらず)、このメソッドが呼び出されます。
public void PaywallViewDidFinishWebPaymentNavigation(
AdaptyUIPaywallView view,
AdaptyPaywallProduct product,
AdaptyError error
) { }パラメータ:
product: ウェブペイウォールが開かれた(または開こうとした)プロダクトerror: ウェブペイウォールが正常に開いた場合はnull、失敗した場合はAdaptyError
イベント例(クリックして展開)
// Successful navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": null
}
// Failed navigation
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"error": {
"code": "wrong_param",
"message": "Current method is not available for this product",
"details": {
"underlyingError": "Product not configured for web purchases"
}
}
}データの取得とレンダリング
プロダクト読み込みエラー
プロダクトの読み込みに失敗したときに呼び出され、AdaptyError を提供します。初期化時にプロダクト配列を渡さなかった場合、AdaptyUI は必要なオブジェクトをサーバーから自動的に取得します。この操作が失敗した場合、AdaptyUI は以下のメソッドを呼び出してエラーを報告します:
public void PaywallViewDidFailLoadingProducts(
AdaptyUIPaywallView view,
AdaptyError error
) { }イベントの例(クリックして展開)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}レンダリングエラー
インターフェースのレンダリング中にエラーが発生し、AdaptyError が提供されたときに呼び出されます。
public void PaywallViewDidFailRendering(
AdaptyUIPaywallView view,
AdaptyError error
) { }イベント例(クリックして展開)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}通常、このようなエラーは発生しないはずです。もし遭遇した場合は、ご連絡ください。