Kotlin Multiplatform - ペイウォールイベントの処理
ペイウォールビルダーで設定されたペイウォールは、購入や復元を行うための追加コードは不要です。ただし、アプリが対応できるいくつかのイベントが発生します。これらのイベントには、ボタン操作(閉じるボタン、URL、プロダクト選択など)や、ペイウォール上で行われた購入関連のアクションに関する通知が含まれます。以下でこれらのイベントへの対応方法を説明します。
このガイドは新しいペイウォールビルダーのペイウォール専用です。
モバイルアプリのペイウォール画面で発生するプロセスを制御・監視するには、AdaptyUIPaywallsEventsObserver インターフェースのメソッドを実装してください。一部のメソッドには、一般的なシナリオを自動的に処理するデフォルト実装があります。
これらのメソッドは、ペイウォールイベントに応じたカスタムロジックを追加する場所です。view.dismiss() を使ってペイウォールを閉じることも、その他のカスタム動作を実装することもできます。
ユーザー生成イベント
ペイウォールの表示・非表示
ペイウォールが表示または非表示になると、これらのメソッドが呼び出されます:
override fun paywallViewDidAppear(view: AdaptyUIPaywallView) {
// Handle paywall appearance
// You can track analytics or update UI here
}
override fun paywallViewDidDisappear(view: AdaptyUIPaywallView) {
// Handle paywall disappearance
// You can track analytics or update UI here
}
- iOS では、ユーザーがペイウォール内のウェブペイウォールボタンをタップしてアプリ内ブラウザでウェブペイウォールが開いたときにも、
paywallViewDidAppearが呼び出されます。 - iOS では、ペイウォールからアプリ内ブラウザで開いたウェブペイウォールが画面から消えたときにも、
paywallViewDidDisappearが呼び出されます。
イベント例(クリックして展開)
// Paywall appeared
{
// No additional data
}
// Paywall disappeared
{
// No additional data
}プロダクト選択
ユーザーが購入するプロダクトを選択すると、このメソッドが呼び出されます:
override fun paywallViewDidSelectProduct(view: AdaptyUIPaywallView, productId: String) {
// Handle product selection
// You can update UI or track analytics here
}
イベント例(クリックして展開)
{
"productId": "premium_monthly"
}購入開始
ユーザーが購入プロセスを開始すると、このメソッドが呼び出されます:
override fun paywallViewDidStartPurchase(view: AdaptyUIPaywallView, product: AdaptyPaywallProduct) {
// Handle purchase start
// You can show loading indicators or track analytics here
}
イベント例(クリックして展開)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}購入成功・キャンセル・保留
購入が成功すると、このメソッドが呼び出されます。デフォルトでは、ユーザーによってキャンセルされた場合を除き、ペイウォールを自動的に閉じます:
override fun paywallViewDidFinishPurchase(
view: AdaptyUIPaywallView,
product: AdaptyPaywallProduct,
purchaseResult: AdaptyPurchaseResult
) {
when (purchaseResult) {
is AdaptyPurchaseResult.Success -> {
// Check if user has access to premium features
if (purchaseResult.profile.accessLevels["premium"]?.isActive == true) {
view.dismiss()
}
}
AdaptyPurchaseResult.Pending -> {
// Handle pending purchase (e.g., user will pay offline with cash)
}
AdaptyPurchaseResult.UserCanceled -> {
// Handle user cancellation
}
}
}
イベント例(クリックして展開)
// 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"
}
}
}
}
}
// 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"
}
}
// User canceled purchase
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
},
"purchaseResult": {
"type": "UserCanceled"
}
}購入が成功した場合は、ペイウォール画面を閉じることをお勧めします。
購入失敗
エラーにより購入が失敗すると、このメソッドが呼び出されます。これには StoreKit/Google Play Billing のエラー(支払い制限、無効なプロダクト、ネットワーク障害)、トランザクション検証の失敗、システムエラーが含まれます。なお、ユーザーによるキャンセルの場合は、キャンセル結果とともに paywallViewDidFinishPurchase が呼び出され、保留中の支払いではこのメソッドは呼び出されません。
override fun paywallViewDidFailPurchase(
view: AdaptyUIPaywallView,
product: AdaptyPaywallProduct,
error: AdaptyError
) {
// Add your purchase failure handling logic here
// For example: show error message, retry option, or custom error handling
}
イベント例(クリックして展開)
{
"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"
}
}
}復元開始
ユーザーが復元プロセスを開始すると、このメソッドが呼び出されます:
override fun paywallViewDidStartRestore(view: AdaptyUIPaywallView) {
// Handle restore start
// You can show loading indicators or track analytics here
}
復元成功
購入の復元が成功すると、このメソッドが呼び出されます:
override fun paywallViewDidFinishRestore(view: AdaptyUIPaywallView, profile: AdaptyProfile) {
// Add your successful restore handling logic here
// For example: show success message, update UI, or dismiss paywall
// Check if user has access to premium features
if (profile.accessLevels["premium"]?.isActive == true) {
view.dismiss()
}
}
イベント例(クリックして展開)
{
"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 を持っている場合は、画面を閉じることをお勧めします。確認方法については、サブスクリプションステータスを参照してください。
復元失敗
Adapty.restorePurchases() が失敗すると、このメソッドが呼び出されます:
override fun paywallViewDidFailRestore(view: AdaptyUIPaywallView, error: AdaptyError) {
// Add your restore failure handling logic here
// For example: show error message, retry option, or custom error handling
}
イベント例(クリックして展開)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}ウェブ決済ナビゲーション完了
ユーザーがウェブペイウォールを使って購入プロセスを開始すると、このメソッドが呼び出されます:
override fun paywallViewDidFinishWebPaymentNavigation(
view: AdaptyUIPaywallView,
product: AdaptyPaywallProduct?,
error: AdaptyError?
) {
if (error != null) {
// Handle web payment navigation error
} else {
// Handle successful web payment navigation
}
}
イベント例(クリックして展開)
// Successful web payment 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 web payment navigation
{
"product": null,
"error": {
"code": "web_payment_failed",
"message": "Web payment navigation failed",
"details": {
"underlyingError": "Network connection error"
}
}
}データ取得とレンダリング
プロダクト読み込みエラー
初期化時にプロダクトを渡さない場合、AdaptyUI は必要なオブジェクトをサーバーから自動的に取得します。この操作が失敗した場合、AdaptyUI はこのメソッドを呼び出してエラーを報告します:
override fun paywallViewDidFailLoadingProducts(view: AdaptyUIPaywallView, error: AdaptyError) {
// Add your product loading failure handling logic here
// For example: show error message, retry option, or custom error handling
}
イベント例(クリックして展開)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}レンダリングエラー
インターフェースのレンダリング中にエラーが発生した場合、このメソッドによって報告されます:
override fun paywallViewDidFailRendering(view: AdaptyUIPaywallView, error: AdaptyError) {
// Handle rendering error
// In a normal situation, such errors should not occur
// If you come across one, please let us know
}
イベント例(クリックして展開)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}通常の状況では、このようなエラーは発生しないはずです。もし遭遇した場合は、ぜひお知らせください。