Xử lý sự kiện flow & paywall - Android

Hướng dẫn này đề cập đến việc xử lý sự kiện cho các lần mua hàng, khôi phục, chọn sản phẩm và hiển thị flow. Bạn cũng cần triển khai xử lý nút bấm (đóng flow, mở liên kết, v.v.). Xem hướng dẫn xử lý hành động nút bấm của chúng tôi để biết thêm chi tiết.

Flow và paywall được cấu hình bằng Flow Builder hoặc 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. Các 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. Tìm hiểu cách phản hồi các sự kiện này bên dưới.

Muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng di động? Hãy xem ứng dụng mẫu của chúng tôi, nơi minh họa toàn bộ quá trình thiết lập, bao gồm hiển thị paywall, thực hiện mua hàng và các chức năng cơ bản khác.

Nếu bạn cần kiểm soát hoặc theo dõi các quy trình diễn ra trên màn hình thanh toán, hãy triển khai các phương thức AdaptyFlowEventListener. Nếu bạn muốn giữ nguyên hành vi mặc định trong một số trường hợp, bạn có thể extend AdaptyFlowDefaultEventListener và chỉ override những method bạn muốn thay đổi.

Dưới đây là các giá trị mặc định từ AdaptyFlowDefaultEventListener.

Sự kiện do người dùng tạo ra

Chọn sản phẩm

Nếu một sản phẩm được chọn để mua (bởi người dùng hoặc hệ thống), phương thức này sẽ được gọi:

public override fun onProductSelected(
    product: AdaptyPaywallProduct,
    context: Context,
) {}
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"
  }
}

Bắt đầu mua hàng

Nếu người dùng bắt đầu quá trình mua hàng, phương thức này sẽ được gọi:

public override fun onPurchaseStarted(
    product: AdaptyPaywallProduct,
    context: Context,
) {}
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"
  }
}

Phương thức này sẽ không được gọi trong chế độ Observer. Tham khảo chủ đề Android - Hiển thị paywall Paywall Builder trong chế độ Observer để biết thêm chi tiết.

Mua thành công, đã 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:

public override fun onPurchaseFinished(
    purchaseResult: AdaptyPurchaseResult,
    product: AdaptyPaywallProduct,
    context: Context,
) {
    if (purchaseResult !is AdaptyPurchaseResult.UserCanceled)
        context.getActivityOrNull()?.onBackPressed()
}
Ví dụ sự kiện (Nhấn để mở rộng)
// Successful purchase
{
  "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",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

// Cancelled purchase
{
  "purchaseResult": {
    "type": "UserCanceled"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

// Pending purchase
{
  "purchaseResult": {
    "type": "Pending"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Chúng tôi khuyến nghị đóng màn hình trong trường hợp đó.

Phương thức này sẽ không được gọi trong Observer mode. Tham khảo chủ đề Android - Hiển thị paywall Paywall Builder trong Observer mode để biết thêm chi tiết.

Giao dịch mua thất bại

Nếu một giao dịch 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 Google Play Billing (hạn chế 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 khi người dùng hủy, onPurchaseFinished sẽ được gọi với kết quả đã hủy thay thế, và các giao dịch đang chờ xử lý không kích hoạt phương thức này.

public override fun onPurchaseFailure(
    error: AdaptyError,
    product: AdaptyPaywallProduct,
    context: Context,
) {}
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "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",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Phương thức này sẽ không được gọi trong chế độ Observer. Tham khảo chủ đề Android - Hiển thị paywall Paywall Builder trong chế độ Observer để biết thêm chi tiết.

Hoàn tất điều hướng thanh toán web

Phương thức này được gọi sau khi có một lần thử mở web paywall cho một sản phẩm cụ thể. Điều này bao gồm cả các lần điều hướng thành công lẫn thất bại:

public override fun onFinishWebPaymentNavigation(
    product: AdaptyPaywallProduct?,
    error: AdaptyError?,
    context: Context,
) {}

Tham số:

Tham sốMô tả
productMột AdaptyPaywallProduct mà web paywall đã được mở. Có thể là null.
errorMột đối tượng AdaptyError nếu điều hướng web paywall thất bại; null nếu điều hướng thành công.
Ví dụ về sự kiện (Nhấn để mở rộng)
// 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": "web_navigation_failed",
    "message": "Failed to open web paywall",
    "details": {
      "underlyingError": "Browser unavailable"
    }
  }
}

Khôi phục thành công

Nếu việc khôi phục giao dịch mua thành công, phương thức này sẽ được gọi:

public override fun onRestoreSuccess(
    profile: AdaptyProfile,
    context: Context,
) {}
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 yêu cầu. 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:

public override fun onRestoreFailure(
    error: AdaptyError,
    context: Context,
) {}
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

Nâng cấp gói đăng ký

Khi người dùng cố mua một gói đăng ký mới trong khi đã có gói đăng ký đang hoạt động, bạn có thể kiểm soát cách xử lý giao dịch mới bằng cách ghi đè phương thức này. Bạn có hai lựa chọn:

  1. Thay thế gói đăng ký hiện tại bằng gói mới:
public override fun onAwaitingPurchaseParams(
    product: AdaptyPaywallProduct,
    context: Context,
    onPurchaseParamsReceived: AdaptyFlowEventListener.PurchaseParamsCallback,
): AdaptyFlowEventListener.PurchaseParamsCallback.IveBeenInvoked {
    onPurchaseParamsReceived(
        AdaptyPurchaseParameters.Builder()
            .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...))
            .build()
    )
    return AdaptyFlowEventListener.PurchaseParamsCallback.IveBeenInvoked
}
  1. Giữ cả hai gói đăng ký (thêm gói mới riêng biệt):
public override fun onAwaitingPurchaseParams(
    product: AdaptyPaywallProduct,
    context: Context,
    onPurchaseParamsReceived: AdaptyFlowEventListener.PurchaseParamsCallback,
): AdaptyFlowEventListener.PurchaseParamsCallback.IveBeenInvoked {
    onPurchaseParamsReceived(AdaptyPurchaseParameters.Empty)
    return AdaptyFlowEventListener.PurchaseParamsCallback.IveBeenInvoked
}

Nếu bạn không override phương thức này, hành vi mặc định là giữ nguyên cả hai gói đăng ký (tương đương với việc sử dụng AdaptyPurchaseParameters.Empty).

Bạn cũng có thể đặt thêm các tham số mua hàng nếu cần:

AdaptyPurchaseParameters.Builder()
    .withSubscriptionUpdateParams(AdaptySubscriptionUpdateParameters(...)) // optional - for replacing current subscription
    .withOfferPersonalized(true) // optional - if using personalized pricing
    .build()
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "product": {
    "vendorProductId": "premium_yearly",
    "localizedTitle": "Premium Yearly",
    "localizedDescription": "Premium subscription for 1 year",
    "localizedPrice": "$99.99",
    "price": 99.99,
    "currencyCode": "USD"
  },
  "subscriptionUpdateParams": {
    "replacementMode": "with_time_proration"
  }
}

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ừ server. 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 sau:

public override fun onLoadingProductsFailure(
    error: AdaptyError,
    context: Context,
): Boolean = false
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"
    }
  }
}

Nếu bạn trả về true, AdaptyUI sẽ lặp lại yêu cầu sau 2 giây.

Lỗi kết xuất giao diện

Nếu xảy ra lỗi trong quá trình kết xuất giao diện, lỗi đó sẽ được báo cáo thông qua phương thức này:

public override fun onError(
    error: AdaptyError,
    context: Context,
) {}
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "error": {
    "code": "rendering_failed",
    "message": "Failed to render flow interface",
    "details": {
      "underlyingError": "Invalid flow configuration"
    }
  }
}

Trong điều kiện bình thường, các lỗi này sẽ không xảy ra, vì vậy nếu bạn gặp phải, hãy cho chúng tôi biết.

Nút back của hệ thống

Theo mặc định, người dùng không thể thoát khỏi một flow bằng nút back của hệ thống hoặc thao tác vuốt để quay lại — họ thoát thông qua một đường dẫn bạn định nghĩa, chẳng hạn như nút Close hoặc một hành động on_device_back trong builder. Nếu bạn muốn nút back của hệ thống có thể đóng flow, hãy override onBackPressed và trả về false để activity hoặc fragment host xử lý sự kiện nhấn đó:

public override fun onBackPressed(context: Context): Boolean {
    return false // let the host handle the back press (e.g. finish the activity or pop the fragment)
}

Callback này chỉ được gọi khi không có hành động on_device_back nào được cấu hình cho màn hình hiện tại — hành động đã cấu hình sẽ được ưu tiên và xử lý nội bộ. Trả về true để tiêu thụ sự kiện nhấn (hành vi mặc định), hoặc false để cho phép logic xử lý back của host tự chạy.

Các sự kiện dành riêng

AdaptyFlowEventListener khai báo một số callback cho các tính năng mà flow chưa sử dụng. Bạn không cần triển khai chúng — AdaptyFlowDefaultEventListener đã cung cấp sẵn các giá trị mặc định không làm gì cả.

Phương thứcMô tả
onAnalyticEventDành riêng cho các sự kiện phân tích tùy chỉnh từ một flow. Hiện tại các flow chưa phát ra sự kiện này tới code của bạn, nên bạn chưa cần implement.
onShowAppRateDành riêng cho các yêu cầu đánh giá ứng dụng từ một flow. Hiện tại các flow chưa kích hoạt yêu cầu đánh giá ứng dụng, nên bạn chưa cần implement.
onShowRequestPermissionDành riêng cho các yêu cầu cấp quyền hệ thống (như thông báo đẩy hoặc quyền truy cập camera) từ một flow. Hiện tại các flow chưa kích hoạt yêu cầu cấp quyền, nên bạn chưa cần implement.

Hướng dẫn này đề cập đến việc xử lý sự kiện cho các giao dịch mua, khôi phục, lựa chọn sản phẩm và hiển thị paywall. Bạn cũng cần triển khai xử lý nút bấm (đóng paywall, mở liên kết, v.v.). Xem hướng dẫn xử lý hành động nút bấm của chúng tôi để biết thêm chi tiết.

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. Các sự kiện đó bao gồm các 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 được thực hiện trên paywall. Hãy 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 yêu cầu Adapty SDK v3.0 trở lên.

Muốn xem ví dụ thực tế về cách tích hợp Adapty SDK vào ứng dụng di động? Hãy xem ứng dụng mẫu của chúng tôi, nơi minh họa toàn bộ quá trình thiết lập, bao gồm hiển thị paywall, thực hiện mua hàng và các chức năng cơ bản khác.

Nếu bạn cần kiểm soát hoặc theo dõi các tiến trình diễn ra trên màn hình mua hàng, hãy implement các phương thức của AdaptyUiEventListener.

Nếu bạn muốn giữ nguyên hành vi mặc định trong một số trường hợp, bạn có thể extend AdaptyUiDefaultEventListener và chỉ override những phương thức bạn muốn thay đổi.

Dưới đây là các giá trị mặc định từ AdaptyUiDefaultEventListener.

Sự kiện do người dùng tạo ra

Chọn sản phẩm

Nếu một sản phẩm được chọn để mua (bởi người dùng hoặc hệ thống), phương thức này sẽ được gọi:

public override fun onProductSelected(
    product: AdaptyPaywallProduct,
    context: Context,
) {}
Ví dụ sự kiện (Nhấp để mở rộng)
{
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Bắt đầu mua hàng

Nếu người dùng bắt đầu quá trình mua hàng, phương thức này sẽ được gọi:

public override fun onPurchaseStarted(
    product: AdaptyPaywallProduct,
    context: Context,
) {}
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"
  }
}

Phương thức này sẽ không được gọi trong chế độ Observer. Tham khảo chủ đề Android - Present Paywall Builder paywalls in Observer mode để biết thêm chi tiết.

Mua hàng thành công, đã hủy hoặc đang chờ xử lý

Nếu mua hàng thành công, phương thức này sẽ được gọi:

public override fun onPurchaseFinished(
    purchaseResult: AdaptyPurchaseResult,
    product: AdaptyPaywallProduct,
    context: Context,
) {
    if (purchaseResult !is AdaptyPurchaseResult.UserCanceled)
        context.getActivityOrNull()?.onBackPressed()
}
Ví dụ về sự kiện (Nhấn để mở rộng)
// Successful purchase
{
  "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",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

// Cancelled purchase
{
  "purchaseResult": {
    "type": "UserCanceled"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

// Pending purchase
{
  "purchaseResult": {
    "type": "Pending"
  },
  "product": {
    "vendorProductId": "premium_monthly",
    "localizedTitle": "Premium Monthly",
    "localizedDescription": "Premium subscription for 1 month",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Chúng tôi khuyến nghị bạn đóng màn hình trong trường hợp đó.

Phương thức này sẽ không được gọi trong Observer mode. Tham khảo chủ đề Android - Hiển thị paywall Paywall Builder trong Observer mode để biết thêm chi tiết.

Mua hàng thất bại

Nếu một giao dịch 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 Google Play Billing (hạn chế 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 khi người dùng hủy giao dịch, onPurchaseFinished sẽ được gọi với kết quả đã hủy thay thế, và các khoản thanh toán đang chờ xử lý sẽ không kích hoạt phương thức này.

public override fun onPurchaseFailure(
    error: AdaptyError,
    product: AdaptyPaywallProduct,
    context: Context,
) {}
Ví dụ sự kiện (Nhấn để mở rộng)
{
  "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",
    "localizedPrice": "$9.99",
    "price": 9.99,
    "currencyCode": "USD"
  }
}

Phương thức này sẽ không được gọi trong chế độ Observer. Tham khảo chủ đề Android - Hiển thị paywall Paywall Builder trong chế độ Observer để biết thêm chi tiết.

Hoàn tất điều hướng thanh toán web

Phương thức này được gọi sau khi có một lần thử mở web paywall cho một sản phẩm cụ thể. Điều này bao gồm cả các lần điều hướng thành công lẫn thất bại:

public override fun onFinishWebPaymentNavigation(
    product: AdaptyPaywallProduct?,
    error: AdaptyError?,
    context: Context,
) {}

Tham số:

Tham sốMô tả
productMột AdaptyPaywallProduct mà web paywall được mở cho sản phẩm đó. Có thể là null.
errorMột đối tượng AdaptyError nếu điều hướng web paywall thất bại; null nếu điều hướng thành công.
Ví dụ sự kiện (Nhấn để mở rộng)
// 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": "web_navigation_failed",
    "message": "Failed to open web paywall",
    "details": {
      "underlyingError": "Browser unavailable"
    }
  }
}

Khôi phục thành công

Nếu việc khôi phục giao dịch thành công, phương thức này sẽ được gọi:

public override fun onRestoreSuccess(
    profile: AdaptyProfile,
    context: Context,
) {}
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 yêu cầu. Tham khảo tài liệu Trạng thái gói đăng ký để biết 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:

public override fun onRestoreFailure(
    error: AdaptyError,
    context: Context,
) {}
Ví dụ sự kiện (Nhấp để mở rộng)
{
  "error": {
    "code": "restore_failed",
    "message": "Purchase restoration failed",
    "details": {
      "underlyingError": "No previous purchases found"
    }
  }
}

Nâng cấp gói đăng ký

Ví dụ sự kiện (Nhấp để mở rộng)
{
  "product": {
    "vendorProductId": "premium_yearly",
    "localizedTitle": "Premium Yearly",
    "localizedDescription": "Premium subscription for 1 year",
    "localizedPrice": "$99.99",
    "price": 99.99,
    "currencyCode": "USD"
  },
  "subscriptionUpdateParams": {
    "replacementMode": "with_time_proration"
  }
}

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ừ server. 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 sau:

public override fun onLoadingProductsFailure(
    error: AdaptyError,
    context: Context,
): Boolean = false
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"
    }
  }
}

Nếu bạn trả về true, AdaptyUI sẽ thực hiện lại yêu cầu sau 2 giây.

Lỗi rendering

Nếu xảy ra lỗi trong quá trình render giao diện, lỗi đó sẽ được báo cáo qua phương thức này:

public override fun onRenderingError(
    error: AdaptyError,
    context: Context,
) {}
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 trường hợp bình thường, những lỗi nà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.