Kotlin Multiplatform - Xử lý sự kiện paywall
Các paywall được cấu hình bằng Paywall Builder không cần thêm code để thực hiện và khôi phục giao dịch mua. Tuy nhiên, chúng tạo ra một số sự kiện mà ứng dụng của bạn có thể phản hồi. Những sự kiện đó bao gồm thao tác nhấn nút (nút đóng, URL, chọn sản phẩm, v.v.) cũng như thông báo về các hành động liên quan đến giao dịch mua trên paywall. Tìm hiểu cách phản hồi các sự kiện này bên dưới.
Hướng dẫn này chỉ dành cho paywall Paywall Builder mới.
Để kiểm soát hoặc theo dõi các quy trình diễn ra trên màn hình paywall trong ứng dụng di động của bạn, hãy triển khai các phương thức của interface AdaptyUIPaywallsEventsObserver. Một số phương thức có triển khai mặc định tự động xử lý các tình huống phổ biến.
Đây là nơi bạn thêm logic tùy chỉnh để phản hồi các sự kiện paywall. Bạn có thể dùng view.dismiss() để đóng paywall, hoặc triển khai bất kỳ hành vi tùy chỉnh nào khác mà bạn cần.
Sự kiện do người dùng tạo ra
Paywall hiển thị và ẩn đi
Khi một paywall xuất hiện hoặc biến mất, các phương thức này sẽ được gọi:
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
}
- Trên iOS,
paywallViewDidAppearcũng được gọi khi người dùng nhấn vào nút web paywall bên trong một paywall, và một web paywall mở trong trình duyệt trong ứng dụng. - Trên iOS,
paywallViewDidDisappearcũng được gọi khi một web paywall mở từ paywall trong trình duyệt trong ứng dụng biến mất khỏi màn hình.
Ví dụ sự kiện (Nhấn để mở rộng)
// Paywall appeared
{
// No additional data
}
// Paywall disappeared
{
// No additional data
}Chọn sản phẩm
Nếu người dùng chọn một sản phẩm để mua, phương thức này sẽ được gọi:
override fun paywallViewDidSelectProduct(view: AdaptyUIPaywallView, productId: String) {
// Handle product selection
// You can update UI or track analytics here
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"productId": "premium_monthly"
}Bắt đầu mua
Nếu người dùng khởi tạo quá trình mua, phương thức này sẽ được gọi:
override fun paywallViewDidStartPurchase(view: AdaptyUIPaywallView, product: AdaptyPaywallProduct) {
// Handle purchase start
// You can show loading indicators or track analytics here
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"product": {
"vendorProductId": "premium_monthly",
"localizedTitle": "Premium Monthly",
"localizedDescription": "Premium subscription for 1 month",
"localizedPrice": "$9.99",
"price": 9.99,
"currencyCode": "USD"
}
}Mua thành công, bị hủy hoặc đang chờ xử lý
Nếu giao dịch mua thành công, phương thức này sẽ được gọi. Theo mặc định, nó sẽ tự động đóng paywall trừ khi người dùng hủy giao dịch:
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
}
}
}
Ví dụ sự kiện (Nhấn để mở rộng)
// 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"
}
}Chúng tôi khuyến nghị đóng màn hình paywall khi giao dịch mua thành công.
Mua thất bại
Nếu giao dịch mua thất bại do lỗi, phương thức này sẽ được gọi. Điều này bao gồm các lỗi StoreKit/Google Play Billing (giới hạn thanh toán, sản phẩm không hợp lệ, lỗi mạng), lỗi xác minh giao dịch và lỗi hệ thống. Lưu ý rằng việc người dùng hủy sẽ kích hoạt paywallViewDidFinishPurchase với kết quả đã hủy, và các khoản thanh toán đang chờ xử lý không kích hoạt phương thức này.
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
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"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"
}
}
}Bắt đầu khôi phục
Nếu người dùng khởi tạo quá trình khôi phục, phương thức này sẽ được gọi:
override fun paywallViewDidStartRestore(view: AdaptyUIPaywallView) {
// Handle restore start
// You can show loading indicators or track analytics here
}
Khôi phục thành công
Nếu khôi phục giao dịch mua thành công, phương thức này sẽ được gọi:
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()
}
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"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"
}
]
}
}Chúng tôi khuyến nghị đóng màn hình nếu người dùng có accessLevel cần thiết. Tham khảo chủ đề Trạng thái gói đăng ký để tìm hiểu cách kiểm tra.
Khôi phục thất bại
Nếu Adapty.restorePurchases() thất bại, phương thức này sẽ được gọi:
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
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"error": {
"code": "restore_failed",
"message": "Purchase restoration failed",
"details": {
"underlyingError": "No previous purchases found"
}
}
}Hoàn tất điều hướng thanh toán web
Nếu người dùng khởi tạo quá trình mua bằng web paywall, phương thức này sẽ được gọi:
override fun paywallViewDidFinishWebPaymentNavigation(
view: AdaptyUIPaywallView,
product: AdaptyPaywallProduct?,
error: AdaptyError?
) {
if (error != null) {
// Handle web payment navigation error
} else {
// Handle successful web payment navigation
}
}
Ví dụ sự kiện (Nhấn để mở rộng)
// 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"
}
}
}Tải dữ liệu và hiển thị
Lỗi tải sản phẩm
Nếu bạn không truyền sản phẩm trong quá trình khởi tạo, AdaptyUI sẽ tự động lấy các đối tượng cần thiết từ máy chủ. Nếu thao tác này thất bại, AdaptyUI sẽ báo lỗi bằng cách gọi phương thức này:
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
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"error": {
"code": "products_loading_failed",
"message": "Failed to load products from the server",
"details": {
"underlyingError": "Network timeout"
}
}
}Lỗi hiển thị
Nếu xảy ra lỗi trong quá trình hiển thị giao diện, lỗi đó sẽ được báo cáo bởi phương thức này:
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
}
Ví dụ sự kiện (Nhấn để mở rộng)
{
"error": {
"code": "rendering_failed",
"message": "Failed to render paywall interface",
"details": {
"underlyingError": "Invalid paywall configuration"
}
}
}Trong điều kiện bình thường, các lỗi như vậy không nên xảy ra, vì vậy nếu bạn gặp phải, hãy cho chúng tôi biết.