Migrate Adapty React Native SDK sang v. 4.0

Adapty React Native SDK 4.0 (beta) giới thiệu flows và đổi tên các API paywall tương ứng. Các API mới hoạt động với cả Flow Builder mới và Paywall Builder hiện có — không cần thay đổi cấu hình nào trên Adapty Dashboard.

Tham chiếu nhanh

v3v4
adapty.getPaywall(placementId, locale?, params?)adapty.getFlow(placementId, params?)
adapty.getPaywallForDefaultAudience(placementId, locale?, params?)adapty.getFlowForDefaultAudience(placementId, params?)
adapty.getPaywallProducts(paywall)adapty.getPaywallProducts(flow)
adapty.logShowPaywall(paywall)adapty.logShowFlow(flow)
AdaptyPaywall (kiểu)AdaptyFlow
createPaywallView(paywall)createFlowView(flow)
AdaptyPaywallView (component)AdaptyFlowView
EventHandlers (kiểu)FlowEventHandlers
onPaywallShownonAppeared
onPaywallClosedonDisappeared
onRenderingFailedonError
AdaptyPaywallProduct giữ nguyên tên — các sản phẩm vẫn thuộc về một flow, và getPaywallProducts giờ nhận một AdaptyFlow. Các phương thức getFlowgetFlowForDefaultAudience không còn nhận tham số locale nữa. Các phương thức view present, dismiss, setEventHandlers, và showDialog, cùng các event handler onCloseButtonPress, onUrlPress, onCustomAction, onProductSelected, onPurchaseStarted, onPurchaseCompleted, onPurchaseFailed, onRestoreStarted, onRestoreCompleted, onRestoreFailed, onLoadingProductsFailed, onWebPaymentNavigationFinished, và onAndroidSystemBack giữ nguyên tên như trong v3. Một số hành vi mặc định đã thay đổi — xem Thay đổi hành vi mặc định.

Phiên bản iOS tối thiểu

Adapty React Native SDK 4.0 nâng phiên bản iOS deployment target tối thiểu từ iOS 13.0 lên iOS 15.0. Hãy đặt iOS deployment target của bạn thành 15.0 hoặc cao hơn trước khi nâng cấp.

Cài đặt

Cập nhật gói

v4.0 là bản phát hành thử nghiệm (pre-release), vì vậy hãy chỉ định chính xác phiên bản — npm không tự động chọn các phiên bản pre-release qua cú pháp caret/tilde:

npm install react-native-adapty@4.0.0
# or
yarn add react-native-adapty@4.0.0

iOS: Các SDK native hiện được phân phối qua Swift Package Manager

Repo spec của CocoaPods sẽ chuyển sang chế độ chỉ đọc vào tháng 12 năm 2026, vì vậy bắt đầu từ v4, các SDK native Adapty, AdaptyUIAdaptyPlugin không còn được kéo vào dưới dạng sub-dependency của CocoaPods nữa — podspec sẽ kéo chúng qua Swift Package Manager (thông qua helper spm_dependency). Điều này yêu cầu hai thay đổi sau:

  • React Native 0.75 trở lên — cần thiết cho helper spm_dependency trong podspec. Nếu dùng phiên bản cũ hơn, pod install sẽ báo lỗi rõ ràng; hãy nâng cấp React Native trước, hoặc tiếp tục dùng react-native-adapty 3.x.
  • Dynamic frameworks — các dependency SPM yêu cầu dynamic linkage. Cách bật tính năng này khác nhau giữa Expo và bare React Native.

Expo

Thêm config plugin expo-build-properties và đặt iOS frameworks thành dynamic trong app.json (hoặc app.config.js):

{
  "expo": {
    "plugins": [
      [
        "expo-build-properties",
        {
          "ios": {
            "useFrameworks": "dynamic"
          }
        }
      ]
    ]
  }
}

Sau đó cài plugin và tạo lại native project:

npx expo install expo-build-properties
npx expo prebuild --clean

Bare React Native

Thêm dynamic frameworks vào iOS target, sau đó cài lại pods:

use_frameworks! :linkage => :dynamic
cd ios && pod install --repo-update

Nếu trước đây bạn đã kéo Adapty, AdaptyUI, hoặc AdaptyPlugin dưới dạng sub-dependencies của CocoaPods, hãy xóa các dòng pod 'Adapty', pod 'AdaptyUI', hoặc pod 'AdaptyPlugin' khỏi Podfile trước.

Chuyển từ liên kết tĩnh mặc định sang dynamic framework có thể xung đột với các thư viện chưa hỗ trợ modular headers, và không tương thích với Flipper. Nếu gặp lỗi build, xem bài viết này về tích hợp Swift Package Manager với thư viện React Native.

Xem Cài đặt Adapty SDK để biết hướng dẫn thiết lập đầy đủ.

Lấy flows

getPaywall → getFlow

Kiểu trả về thay đổi từ AdaptyPaywall sang AdaptyFlow, và tham số locale bị xóa — khi render một flow, locale sẽ được tự động xác định; với các paywall tùy chỉnh, tất cả locale được trả về trong flow.remoteConfigs:

- const paywall = await adapty.getPaywall('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');

getPaywallForDefaultAudience được đổi tên theo cách tương tự:

- const paywall = await adapty.getPaywallForDefaultAudience('YOUR_PLACEMENT_ID', 'en');
+ const flow = await adapty.getFlowForDefaultAudience('YOUR_PLACEMENT_ID');

getPaywallProducts(paywall) → getPaywallProducts(flow)

getPaywallProducts giữ nguyên tên nhưng giờ nhận một AdaptyFlow:

- const products = await adapty.getPaywallProducts(paywall);
+ const products = await adapty.getPaywallProducts(flow);

Mô hình dữ liệu

getFlow trả về AdaptyFlow thay vì AdaptyPaywall, và cấu trúc đối tượng đã thay đổi:

Trường AdaptyPaywall v3Trường AdaptyFlow v4Hành động
remoteConfig? (đơn lẻ)remoteConfigs?: AdaptyRemoteConfig[] (mảng)Một flow chứa một remote config cho mỗi ngôn ngữ đã cấu hình. Đọc cái phù hợp với người dùng: flow.remoteConfigs?.find((c) => c.lang === 'en').
productsflow.paywalls[i].productIdentifiersCác định danh sản phẩm hiện nằm trên từng biến thể flow, không còn trên flow nữa.
webPurchaseUrl?flow.paywalls[i].webPurchaseUrlChuyển từ flow sang từng biến thể paywall.
version?: numberflowVersionId?: stringĐổi tên, và kiểu dữ liệu thay đổi từ number sang string.
hasViewConfigurationđã xóaXóa mọi kiểm tra hasViewConfiguration khỏi code của bạn.
requestLocaleđã xóaLocale không còn là một phần của model nữa.
(mới)paywalls: AdaptyFlowPaywall[]Mỗi mục là một biến thể paywall trong flow.
(mới)responseCreatedAt: numberTimestamp phản hồi từ server, tính bằng mili giây.
Product identifiers moved from the flow to each variation:
- const ids = paywall.products;
+ const ids = flow.paywalls[0].productIdentifiers;

Các phương thức Web paywall

openWebPaywallcreateWebPaywallUrl vẫn giữ nguyên tên, nhưng tham số đầu tiên bây giờ là AdaptyFlowPaywall (một biến thể flow) thay vì AdaptyPaywall. Bạn vẫn có thể truyền vào AdaptyPaywallProduct.

  const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
- await adapty.openWebPaywall(paywall);
+ await adapty.openWebPaywall(flow.paywalls[0]);

Theo dõi lượt xem flow

logShowPaywall → logShowFlow

logShowPaywall được đổi tên thành logShowFlow và giờ nhận vào một AdaptyFlow. Sự kiện vẫn được ghi lại theo cùng một biến thể, nên các chỉ số funnel và A/B test hiện có vẫn hoạt động bình thường mà không cần thay đổi trên dashboard.

- await adapty.logShowPaywall(paywall);
+ await adapty.logShowFlow(flow);

Giống như ở v3, bạn không cần gọi phương thức này khi hiển thị các flow hoặc paywall được dựng bởi Flow Builder hoặc Paywall Builder — Adapty tự động theo dõi các lượt xem đó.

Hiển thị flow

createPaywallView → createFlowView

Đổi tên hàm factory và truyền vào AdaptyFlow. Các phương thức của controller được trả về (present, dismiss, setEventHandlers, showDialog) không thay đổi:

- import { createPaywallView } from 'react-native-adapty';
+ import { createFlowView } from 'react-native-adapty';

- const view = await createPaywallView(paywall);
+ const view = await createFlowView(flow);
  await view.present();

AdaptyPaywallView → AdaptyFlowView

Nếu bạn render bằng React component, hãy đổi tên component và truyền prop flow:

- import { AdaptyPaywallView } from 'react-native-adapty';
+ import { AdaptyFlowView } from 'react-native-adapty';

- <AdaptyPaywallView paywall={paywall} /* … */ />
+ <AdaptyFlowView flow={flow} /* … */ />

Một flow view được tạo bằng createFlowView chỉ dùng một lần: sau khi gọi dismiss(), view đó sẽ bị hủy, vì vậy hãy gọi lại createFlowView để hiển thị flow thêm lần nữa. Một AdaptyFlowView được nhúng sẽ bị đóng khi unmount — trả về true từ một handler không đóng view được nhúng, vì vậy hãy tự thay đổi state của bạn thay thế, ví dụ trong onCloseButtonPress.

Xử lý sự kiện

Giao diện xử lý sự kiện được đổi tên từ EventHandlers thành FlowEventHandlers, và ba callback cũng được đổi tên. Phần thân của các handler hiện có không cần thay đổi code — chỉ cần đổi tên:

- onPaywallShown: () => { /* … */ },
+ onAppeared: () => { /* … */ },

- onPaywallClosed: () => { /* … */ },
+ onDisappeared: () => { /* … */ },

- onRenderingFailed: (error) => { /* … */ },
+ onError: (error) => { /* … */ },

Tất cả các event handler khác vẫn giữ nguyên tên. Hai handler cũng nhận thêm tham số thứ hai: onPurchaseCompleted nay là (purchaseResult, product)onPurchaseFailed nay là (error, product), trong đó productAdaptyPaywallProduct liên quan. Xem Xử lý sự kiện flow & paywall để biết danh sách đầy đủ.

onDisappeared chỉ kích hoạt khi một flow được trình bày dưới dạng modal với createFlowView().present(). Component AdaptyFlowView không expose nó dưới dạng prop — để đóng một embedded view, hãy unmount nó.

v4 cũng bổ sung một số tính năng bạn có thể tùy chọn bật:

  • Các phương thức adapty.openWebUrl(url, openIn?)adapty.requestAppReview() — hỗ trợ các handler mặc định onUrlPressonRequestAppReview, giúp xử lý URL và yêu cầu đánh giá ứng dụng theo cách native ngay từ đầu. Chỉ gọi trực tiếp khi bạn ghi đè các handler đó.
  • Xử lý giao dịch mua trong Observer mode bên trong flow thông qua các handler mới onObserverPurchaseInitiated / onObserverRestoreInitiated. Xem Xử lý giao dịch mua trong Observer mode.

Các API đã bị xóa và deprecated

setFallbackPaywalls → setFallback

setFallbackPaywalls đã bị xóa. Hãy dùng setFallback, nhận cùng tham số:

- await adapty.setFallbackPaywalls(fileLocation);
+ await adapty.setFallback(fileLocation);

Các export đã bị xóa

Các symbol này không còn được export từ react-native-adapty nữa. Hãy xóa các import liên quan:

  • AdaptyPaywall: Dùng AdaptyFlow thay thế.
  • ProductReference: Dùng AdaptyProductIdentifier, đọc từ flow.paywalls[i].productIdentifiers.
  • AdaptyPaywallBuilder: Đã bị xóa. Flow và paywall được render natively.
  • AdaptyAndroidSubscriptionUpdateParameters: Dùng shape lồng nhau subscriptionUpdateParams (xem bên dưới).

activate: lockMethodsUntilReady

lockMethodsUntilReady đã bị xóa và hành vi này hiện luôn được bật. Hãy xóa nó khỏi lệnh gọi activate — giữ lại nó sẽ gây lỗi biên dịch:

- await adapty.activate('PUBLIC_SDK_KEY', { lockMethodsUntilReady: true });
+ await adapty.activate('PUBLIC_SDK_KEY');

Cập nhật gói đăng ký Android trong makePurchase

Cấu trúc phẳng cho việc cập nhật gói đăng ký Android đã bị loại bỏ. Hãy chuyển oldSubVendorProductIdprorationMode vào một object lồng nhau tên là subscriptionUpdateParams, và giữ isOfferPersonalized ở cấp cao nhất. Xem Thực hiện mua hàng để xem ví dụ đầy đủ.

Android: safe-area paddings

Tài nguyên boolean Android <bool name="adapty_paywall_enable_safe_area_paddings">…</bool> đã bị xóa. Hãy xóa nó khỏi res/values/bools.xml và kiểm soát safe-area paddings tại runtime bằng tham số enableSafeArea khi bạn tạo flow view. Mặc định là true cho kiểu hiển thị modal và false cho component nhúng.

Chế độ mock

Nếu bạn chạy SDK ở chế độ mock (Expo Go hoặc web preview), hãy đổi tên khóa cấu hình mock paywalls thành flows.

Thay đổi hành vi mặc định

Những thay đổi này không gây lỗi biên dịch, vì vậy hãy kiểm tra chúng trong khi chạy:

  • onAndroidSystemBack: Mặc định đã thay đổi từ đóng view sang giữ nguyên. Để khôi phục hành vi cũ, trả về true từ handler.
  • onPurchaseCompleted: Mặc định đã thay đổi từ đóng view (trừ khi người dùng hủy mua) sang luôn giữ nguyên. Để khôi phục hành vi cũ, trả về purchaseResult.type !== 'user_cancelled' từ handler.
  • onRestoreCompleted: Mặc định đã thay đổi từ đóng view sau khi khôi phục thành công sang giữ nguyên. Để khôi phục hành vi cũ, trả về true từ handler.
  • onUrlPress: Mặc định hiện tại mở URL thông qua native layer, tuân theo cài đặt trình duyệt trong ứng dụng hoặc trình duyệt ngoài từ dashboard. Ghi đè handler để tự xử lý việc mở URL.

Onboarding API không còn được hỗ trợ

Onboarding API cũ đã bị deprecated trong v4.0, thay thế bằng Flow Builder. API này vẫn hoạt động bình thường, và IDE của bạn sẽ đánh dấu các symbol bị deprecated thông qua annotation @deprecated — không có cảnh báo nào xuất hiện lúc runtime. Các symbol này sẽ bị xóa trong một bản phát hành tương lai, vì vậy hãy lên kế hoạch migration các onboarding của bạn sang Flow Builder.

Các symbol bị deprecated: getOnboarding, getOnboardingForDefaultAudience, createOnboardingView, và AdaptyOnboardingView.