Kotlin Multiplatform - Paywall olaylarını yönetme

Paywall Builder ile yapılandırılmış paywalllar, satın alma yapmak veya geri yüklemek için ekstra kod gerektirmez. Ancak uygulamanızın tepki verebileceği bazı olaylar üretirler. Bu olaylar arasında buton tıklamaları (kapatma butonları, URL’ler, ürün seçimleri vb.) ve paywall üzerinde gerçekleştirilen satın alma işlemlerine ilişkin bildirimler yer alır. Bu olaylara nasıl yanıt vereceğinizi aşağıda öğrenin.

Bu rehber yalnızca yeni Paywall Builder paywallları içindir.

Mobil uygulamanızdaki paywall ekranında gerçekleşen süreçleri kontrol etmek veya izlemek için AdaptyUIPaywallsEventsObserver arayüzü metodlarını uygulayın. Bazı metodların yaygın senaryoları otomatik olarak ele alan varsayılan uygulamaları vardır.

Bu metodlar, paywall olaylarına özel mantığınızı eklediğiniz yerlerdir. Paywallı kapatmak için view.dismiss() kullanabilir ya da ihtiyacınıza göre başka özel davranışlar uygulayabilirsiniz.

Kullanıcı kaynaklı olaylar

Paywallın görünmesi ve kaybolması

Bir paywall belirdiğinde veya kaybolduğunda bu metodlar çağrılır:

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’ta, kullanıcı bir paywall içindeki web paywall butonuna tıkladığında ve uygulama içi tarayıcıda bir web paywall açıldığında paywallViewDidAppear da çağrılır.
  • iOS’ta, bir paywalldan açılan web paywall uygulama içi tarayıcıdan ekranda kaybolduğunda paywallViewDidDisappear da çağrılır.
Olay örnekleri (Genişletmek için tıklayın)
// Paywall appeared
{
  // No additional data
}

// Paywall disappeared
{
  // No additional data
}

Ürün seçimi

Kullanıcı satın almak üzere bir ürün seçtiğinde bu metod çağrılır:

override fun paywallViewDidSelectProduct(view: AdaptyUIPaywallView, productId: String) {
    // Handle product selection
    // You can update UI or track analytics here
}
Olay örneği (Genişletmek için tıklayın)
{
  "productId": "premium_monthly"
}

Satın alma başlatıldı

Kullanıcı satın alma sürecini başlattığında bu metod çağrılır:

override fun paywallViewDidStartPurchase(view: AdaptyUIPaywallView, product: AdaptyPaywallProduct) {
    // Handle purchase start
    // You can show loading indicators or track analytics here
}
Olay örneği (Genişletmek için tıklayın)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Başarılı, iptal edilmiş veya bekleyen satın alma

Satın alma başarılı olduğunda bu metod çağrılır. Varsayılan olarak, kullanıcı tarafından iptal edilmedikçe paywallı otomatik olarak kapatır:

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
        }
    }
}
Olay örnekleri (Genişletmek için tıklayın)
// 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"
  }
}

Başarılı satın alma durumunda paywall ekranını kapatmanızı öneririz.

Başarısız satın alma

Bir hata nedeniyle satın alma başarısız olduğunda bu metod çağrılır. Bu durum; StoreKit/Google Play Billing hatalarını (ödeme kısıtlamaları, geçersiz ürünler, ağ hataları), işlem doğrulama hatalarını ve sistem hatalarını kapsar. Kullanıcının iptal etmesi durumunda ise bu metod değil, iptal sonucuyla birlikte paywallViewDidFinishPurchase tetiklenir; bekleyen ödemeler bu metodu tetiklemez.

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
}
Olay örneği (Genişletmek için tıklayın)
{
  "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"
    }
  }
}

Geri yükleme başlatıldı

Kullanıcı geri yükleme sürecini başlattığında bu metod çağrılır:

override fun paywallViewDidStartRestore(view: AdaptyUIPaywallView) {
    // Handle restore start
    // You can show loading indicators or track analytics here
}

Başarılı geri yükleme

Satın alma geri yükleme başarılı olduğunda bu metod çağrılır:

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()
    }
}
Olay örneği (Genişletmek için tıklayın)
{
  "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"
      }
    ]
  }
}

Kullanıcının gerekli accessLevel’a sahip olması durumunda ekranı kapatmanızı öneririz. Bunu nasıl kontrol edeceğinizi öğrenmek için Abonelik durumu konusuna bakın.

Başarısız geri yükleme

Adapty.restorePurchases() başarısız olduğunda bu metod çağrılır:

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
}
Olay örneği (Genişletmek için tıklayın)
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

Web ödeme navigasyonu tamamlandı

Kullanıcı web paywall üzerinden satın alma sürecini başlattığında bu metod çağrılır:

override fun paywallViewDidFinishWebPaymentNavigation(
    view: AdaptyUIPaywallView,
    product: AdaptyPaywallProduct?,
    error: AdaptyError?
) {
    if (error != null) {
        // Handle web payment navigation error
    } else {
        // Handle successful web payment navigation
    }
}
Olay örnekleri (Genişletmek için tıklayın)
// 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"
    }
  }
}

Veri çekme ve render etme

Ürün yükleme hataları

Başlatma sırasında ürünleri siz geçmezseniz AdaptyUI gerekli nesneleri sunucudan kendi alır. Bu işlem başarısız olursa AdaptyUI hatayı bu metodu çağırarak bildirir:

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
}
Olay örneği (Genişletmek için tıklayın)
{
  "error": {
    "code": "products_loading_failed",
    "message": "Failed to load products from the server",
    "details": {
      "underlyingError": "Network timeout"
    }
  }
}

Render hataları

Arayüz render edilirken bir hata oluşursa bu metod aracılığıyla bildirilir:

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
}
Olay örneği (Genişletmek için tıklayın)
{
    "error": {
        "code": "rendering_failed",
            "message": "Failed to render paywall interface",
            "details": {
            "underlyingError": "Invalid paywall configuration"
        }
    }
}

Normal koşullarda bu tür hatalar yaşanmaz; eğer böyle bir hatayla karşılaşırsanız lütfen bize bildirin.