フローとペイウォールのイベントを処理する - React Native

Important

このガイドでは、購入・復元・プロダクト選択・フローのレンダリングに関するイベント処理について説明します。ボタンの処理(フローを閉じる、リンクを開く、カスタムアクションなど)も設定できます。詳細はボタンアクションの処理に関するガイドをご覧ください。

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

モバイルアプリ内のフロー画面で発生するプロセスを制御または監視するには、イベントハンドラーを実装してください:

イベントの例(クリックして展開)
// onCloseButtonPress
{
  //Record the event
}

// onAndroidSystemBack
{
  //Record the event
}

// onUrlPress
{
  "url": "https://example.com/terms"
}

// onCustomAction
{
  "actionId": "login"
}

// onProductSelected
{
  "productId": "premium_monthly"
}

// onPurchaseStarted
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseCompleted - Success
{
  "purchaseResult": {
    "type": "success",
    "profile": {
      "accessLevels": {
        "premium": {
          "id": "premium",
          "isActive": true,
          "expiresAt": "2024-02-15T10:30:00Z"
        }
      }
    }
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseCompleted - Cancelled
{
  "purchaseResult": {
    "type": "user_cancelled"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseFailed
{
  "error": {
    "code": "purchase_failed",
    "message": "Purchase failed due to insufficient funds",
    "details": {
      "underlyingError": "Insufficient funds in account"
    }
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onRestoreCompleted
{
  "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"
      }
    ]
  }
}

// onRestoreFailed
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

// onError
{
  "error": {
    "code": "rendering_failed",
    "message": "Failed to render flow interface",
    "details": {
      "underlyingError": "Invalid flow configuration"
    }
  }
}

// onLoadingProductsFailed
{
  "error": {
    "code": "products_loading_failed",
    "message": "Failed to load products from the server",
    "details": {
      "underlyingError": "Network timeout"
    }
  }
}

// onAppeared
{
  "view": {
    "id": "3f8a1c7e-9b24-4d51-8e30-6c5b2a9f1d47",
    "placementId": "onboarding_paywall",
    "variationId": "d21c4b6a-57e8-4f39-b0a2-8c7e13f5d94b",
    "locale": "es"
  }
}

// onDisappeared
{
  //Record the event
}

// onWebPaymentNavigationFinished
{
  //Record the event
}

必要なイベントハンドラーだけ登録すれば、不要なものは省略できます。未使用のイベントリスナーは作成されません。必須のイベントハンドラーはありません。

イベントハンドラーはブール値を返します。true が返された場合、表示プロセスが完了したとみなされ、フロー画面が閉じてそのビューのイベントリスナーが削除されます。 一部のイベントハンドラーには、必要に応じて上書きできるデフォルトの動作があります。

  • onCloseButtonPress: 閉じるボタンが押されたときにフローを閉じます。
  • onUrlPress: タップされた URL を開き、フローを開いたままにします。
  • onAndroidSystemBack(モーダル表示のみ): Back ボタンが押されたときにフローを開いたままにします。true を返すと閉じます。
  • onRestoreCompleted: リストアが成功した後もフローを開いたままにします。true を返すと閉じます。
  • onPurchaseCompleted: 購入完了後もフローを開いたままにします。true を返すと閉じます。
  • onError: フローのレンダリングに失敗した場合、フローを閉じます。

イベントハンドラー

イベントハンドラー説明
onCustomActionユーザーがカスタムアクションを実行したとき(例:カスタムボタンをクリックしたとき)に呼び出されます。
onUrlPressユーザーがフロー内のURLをクリックしたときに呼び出されます。
onAndroidSystemBackモーダル表示のみ:ユーザーがAndroidのシステムBackボタンをタップしたときに呼び出されます。
onCloseButtonPress閉じるボタンが表示されている状態でユーザーがタップしたときに呼び出されます。このハンドラー内でフロー画面を閉じることを推奨します。
onPurchaseCompleted購入が完了したとき(成功、ユーザーによるキャンセル、承認待ちを問わず)に呼び出されます。購入が成功した場合は更新されたAdaptyProfileが提供されます。ユーザーキャンセルや保留中の支払い(例:保護者の承認が必要な場合)はonPurchaseFailedではなくこのイベントをトリガーします。
onPurchaseStartedユーザーが「購入」アクションボタンをタップして購入プロセスを開始したときに呼び出されます。
onPurchaseFailedエラーにより購入が失敗したとき(例:支払い制限、無効なプロダクト、ネットワーク障害、トランザクション検証失敗)に呼び出されます。ユーザーキャンセルや保留中の支払いでは呼び出されず、それらは代わりにonPurchaseCompletedをトリガーします。
onRestoreStartedユーザーが購入の復元プロセスを開始したときに呼び出されます。
onRestoreCompleted購入の復元が成功したときに呼び出され、更新されたAdaptyProfileが提供されます。ユーザーが必要なaccessLevelを持っている場合は画面を閉じることを推奨します。確認方法はサブスクリプションステータスをご参照ください。
onRestoreFailed復元プロセスが失敗したときに呼び出され、AdaptyErrorが提供されます。
onProductSelectedフロービュー内のプロダクトが選択されたときに呼び出されます。購入前にユーザーが何を選んでいるかを監視できます。
onErrorビューのレンダリング中にエラーが発生したときに呼び出され、AdaptyErrorが提供されます。このようなエラーは発生しないはずですので、もし遭遇した場合はお知らせください。
onLoadingProductsFailedプロダクトの読み込みが失敗したときに呼び出され、AdaptyErrorが提供されます。ビュー作成時にprefetchProducts: trueを設定していない場合、AdaptyUIがサーバーから必要なオブジェクトを自動的に取得します。
onAppearedフローがユーザーに表示されたときに呼び出され、表示されたviewが提供されます(viewの引数を参照)。iOSでは、ユーザーがフロー内のウェブペイウォールボタンをタップしてインアプリブラウザでウェブペイウォールが開いたときにも呼び出されます。
onDisappearedモーダル表示のみ:ユーザーがフローを閉じたときに呼び出されます。iOSでは、フローからインアプリブラウザで開いたウェブペイウォールが画面から消えたときにも呼び出されます。
onWebPaymentNavigationFinishedウェブペイウォールを購入のために開こうとした後(成功・失敗を問わず)に呼び出されます。
onAnalyticsフローが画面表示などのアナリティクスイベントを報告したときに呼び出されます。下記のアナリティクスイベントを参照してください。
onRequestAppReviewフローからのアプリレビューリクエスト用に予約されています。フローはまだアプリレビューリクエストをトリガーしないため、実装は不要です。
onRequestPermissionフローからのシステム権限リクエスト(プッシュ通知やカメラアクセスなど)用に予約されています。フローはまだ権限リクエストをトリガーしないため、実装は不要です。
onObserverPurchaseInitiatedオブザーバーモードのみ:ユーザーがフロー内の購入ボタンをタップしたときに呼び出されます。Adaptyは購入を実行しません。独自の購入コードで購入を行い、トランザクションをAdaptyに報告してください。下記のオブザーバーモードでの購入処理を参照してください。
onObserverRestoreInitiatedオブザーバーモードのみ:ユーザーがフロー内の復元ボタンをタップしたときに呼び出されます。Adaptyは復元を実行しません。独自のコードで復元を行い、復元されたトランザクションを報告してください。下記のオブザーバーモードでの購入処理を参照してください。

viewアーギュメント

view アーギュメントは React Native SDK 4.0.3 以降が必要です。すべてのフローハンドラーの中で、onAppeared だけがビュー自体の説明を受け取ります。これは以下のフィールドを持つ FlowEventView オブジェクトです:

フィールド説明
idこのビューインスタンスの識別子。SDK 内部で使用されるものであり、Adapty ダッシュボードのいかなる項目とも対応しません。
placementIdフローが取得されたプレースメント
variationIdフローが解決されたバリアント。独自のアナリティクスをA/B テストに紐付けるために使用します。
localeビューの構築に使用されたフローのローカライズ。フローにリクエストしたローカライズが存在しない場合、指定したロケールとは異なる値になります。フローがレンダリングした言語に合わせて残りの画面を調整するために参照してください。詳細はローカライズとロケールコードの使用を参照してください。

アナリティクスイベント

const unsubscribe = view.setEventHandlers({
  onAnalytics(name, params) {
    return false; // keep the flow open
  },
});

フローは、ユーザーがいずれかの画面を開くたびに flow_screen_showed を報告します。Adapty はこれらのイベントを独自のフロー分析でカウントするとともに、アプリにも配信します。これにより、自社の分析ツールで同じファネルを構築できます。

パラメータ説明
instanceIdユーザーが開いた画面の ID。
screen_orderフロー内での画面の位置。
is_last_screenその画面に遷移先がない場合に true。分岐するフローは複数の異なる画面で終了する可能性があり、それぞれが true を報告します。

このイベントでは isBackendEventisCustomerEvent の両方が true です。Adapty はカウントを継続し、アプリにも配信されます。

これらのイベントの処理方法については、フロースクリーンのビューをトラッキングするを参照してください。

オブザーバーモードでの購入処理

SDKをオブザーバーモードobserverMode: true)で有効化し、Adaptyがレンダリングするフローを表示している場合、SDKは代わりに購入処理を行いません。ユーザーが購入ボタンまたは復元ボタンをタップすると、SDKはonObserverPurchaseInitiatedまたはonObserverRestoreInitiatedを呼び出します。独自のコードで購入または復元を実行し、提供されたコールバックでフローのローディングインジケーターを制御した後、Adaptyにトランザクションを報告してください。

const unsubscribe = view.setEventHandlers({
  onObserverPurchaseInitiated(product, onStartPurchase, onFinishPurchase) {
    onStartPurchase(); // show the flow's loading indicator
    myPurchaseApi(product.vendorProductId)
      .then((transactionId) => adapty.reportTransaction(transactionId))
      .finally(() => onFinishPurchase()); // hide the loading indicator
    return false; // keep the flow open; dismiss it yourself after success
  },
  onObserverRestoreInitiated(onStartRestore, onFinishRestore) {
    onStartRestore();
    myRestoreApi()
      .finally(() => onFinishRestore());
    return false;
  },
});
Important

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

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

Warning

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

ペイウォール画面上で発生するプロセスを制御・監視するには、イベントハンドラーを実装します。

イベントの例(クリックして展開)
// onCloseButtonPress
{
  //イベントを記録する
}

// onAndroidSystemBack
{
  //イベントを記録する
}

// onUrlPress
{
  "url": "https://example.com/terms"
}

// onCustomAction
{
  "actionId": "login"
}

// onProductSelected
{
  "productId": "premium_monthly"
}

// onPurchaseStarted
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseCompleted - Success
{
  "purchaseResult": {
    "type": "success",
    "profile": {
      "accessLevels": {
        "premium": {
          "id": "premium",
          "isActive": true,
          "expiresAt": "2024-02-15T10:30:00Z"
        }
      }
    }
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseCompleted - Cancelled
{
  "purchaseResult": {
    "type": "user_cancelled"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onPurchaseFailed
{
  "error": {
    "code": "purchase_failed",
    "message": "Purchase failed due to insufficient funds",
    "details": {
      "underlyingError": "Insufficient funds in account"
    }
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "price": {
      "amount": 9.99,
      "currencyCode": "USD",
      "currencySymbol": "$",
      "localizedString": "$9.99"
    }
  }
}

// onRestoreCompleted
{
  "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"
      }
    ]
  }
}

// onRestoreFailed
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

// onRenderingFailed
{
  "error": {
    "code": "rendering_failed",
    "message": "Failed to render paywall interface",
    "details": {
      "underlyingError": "Invalid paywall configuration"
    }
  }
}

// onLoadingProductsFailed
{
  "error": {
    "code": "products_loading_failed",
    "message": "Failed to load products from the server",
    "details": {
      "underlyingError": "Network timeout"
    }
  }
}

// onPaywallShown
{
  //イベントを記録する
}

// onPaywallClosed
{
  //イベントを記録する
}

// onWebPaymentNavigationFinished
{
  //イベントを記録する
}

必要なイベントハンドラのみを登録し、不要なものは省略できます。未使用のイベントリスナーは作成されません。必須のイベントハンドラはありません。

イベントハンドラはブール値を返します。true が返された場合、表示プロセスが完了したとみなされ、ペイウォール画面が閉じられ、このビューのイベントリスナーが削除されます。 一部のイベントハンドラーにはデフォルトの動作があり、必要に応じて上書きできます:

  • onCloseButtonPress: 閉じるボタンが押されたときにペイウォールを閉じます。
  • onUrlPress: タップされたURLを開き、ペイウォールは表示したままにします。
  • onAndroidSystemBack(モーダル表示のみ): Back ボタンが押されたときにペイウォールを閉じます。
  • onRestoreCompleted: リストアが成功した後にペイウォールを閉じます。
  • onPurchaseCompleted: ユーザーがキャンセルしない限り、ペイウォールを閉じます。
  • onRenderingFailed: レンダリングに失敗した場合にペイウォールを閉じます。

イベントハンドラー

イベントハンドラー説明
onCustomActionユーザーがカスタムアクションを実行したとき(例:カスタムボタンをクリックしたとき)に呼び出されます。
onUrlPressユーザーがペイウォール内のURLをクリックしたときに呼び出されます。
onAndroidSystemBackモーダル表示のみ:ユーザーがAndroidのシステム Back ボタンをタップしたときに呼び出されます。
onCloseButtonPress閉じるボタンが表示されており、ユーザーがそれをタップしたときに呼び出されます。このハンドラー内でペイウォール画面を閉じることを推奨します。
onPurchaseCompleted購入が完了したとき(成功・ユーザーによるキャンセル・承認待ちのいずれの場合も)に呼び出されます。購入が成功した場合は更新された AdaptyProfile が提供されます。ユーザーによるキャンセルや保護者の承認待ちなどの保留中の支払いはこのイベントをトリガーし、onPurchaseFailed はトリガーされません。
onPurchaseStartedユーザーが「購入」アクションボタンをタップして購入プロセスを開始したときに呼び出されます。
onPurchaseFailedエラー(支払い制限、無効なプロダクト、ネットワーク障害、トランザクション検証の失敗など)により購入が失敗したときに呼び出されます。ユーザーによるキャンセルや保留中の支払いでは呼び出されず、その場合は onPurchaseCompleted がトリガーされます。
onRestoreStartedユーザーが購入の復元プロセスを開始したときに呼び出されます。
onRestoreCompleted購入の復元が成功し、更新された AdaptyProfile が提供されたときに呼び出されます。ユーザーが必要な accessLevel を持っている場合はこの画面を閉じることを推奨します。確認方法についてはサブスクリプションのステータスをご参照ください。
onRestoreFailed復元プロセスが失敗し、AdaptyError が提供されたときに呼び出されます。
onProductSelectedペイウォールビュー内のプロダクトが選択されたときに呼び出されます。購入前にユーザーが何を選択しているかを確認できます。
onRenderingFailedビューのレンダリング中にエラーが発生し、AdaptyError が提供されたときに呼び出されます。このようなエラーは本来発生しないため、もし発生した場合はお知らせください。
onLoadingProductsFailedプロダクトの読み込みに失敗し、AdaptyError が提供されたときに呼び出されます。ビューの作成時に prefetchProducts: true を設定していない場合、AdaptyUI が必要なオブジェクトをサーバーから自動的に取得します。
onPaywallShownペイウォールがユーザーに表示されたときに呼び出されます。iOS では、ユーザーがペイウォール内のウェブペイウォールボタンをタップしてアプリ内ブラウザでウェブペイウォールが開いたときにも呼び出されます。
onPaywallClosedモーダル表示のみ:ユーザーによってペイウォールが閉じられたときに呼び出されます。iOS では、ペイウォールからアプリ内ブラウザで開いたウェブペイウォールが画面から消えたときにも呼び出されます。
onWebPaymentNavigationFinished購入のためにウェブペイウォールを開こうとした後、成功・失敗に関わらず呼び出されます。