Migrate Adapty Capacitor SDK sang v. 4.0

Adapty Capacitor 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 khảo 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 + AdaptyFlowPaywall
createPaywallView(paywall, params?)createFlowView(flow, params?)
PaywallViewControllerFlowViewController
EventHandlers (kiểu)FlowEventHandlers
CreatePaywallViewParamsInputCreateFlowViewParamsInput
onRenderingFailedonError
AdaptyPaywallProduct giữ nguyên tên — sản phẩm vẫn thuộc về một flow, và getPaywallProducts cũng giữ nguyên tên, nhưng giờ nhận vào một AdaptyFlow. Các phương thức getFlowgetFlowForDefaultAudience không còn nhận tham số locale nữa. Các API mua hàng và hồ sơ người dùng (makePurchase, restorePurchases, getProfile, identify, updateProfile) và fallback qua setFallback không thay đổi. 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. Các phương thức onboarding vẫn hoạt động nhưng đã bị deprecated — xem Deprecation API Onboarding. Một số hành vi mặc định đã thay đổi — xem Thay đổi hành vi mặc định.

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

Yêu cầu runtime không thay đổi so với v3.16+: iOS 15.0, Android minSdk 24, và Capacitor 8. Không cần thay đổi deployment target.

Có một yêu cầu build mới: Xcode 26 trở lên — native Adapty iOS SDK 4.0.0-beta.2 đi kèm với bản phát hành này sử dụng Swift tools 6.2.

v4 đi kèm với native Adapty SDK iOS 4.0.0-beta.2 và Android BOM 4.0.0-beta.1.

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 sẽ không tự chọn các phiên bản pre-release qua cú pháp caret/tilde:

npm install @adapty/capacitor@4.0.0-beta.1

Sau đó đồng bộ các dự án native:

npx cap sync

iOS: Chỉ dùng 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 kể từ v4, AdaptyCapacitor.podspec đã bị xóa và SDK chỉ cài đặt trên iOS thông qua Swift Package Manager (SPM). Dự án iOS của ứng dụng bạn phải sử dụng tích hợp SPM của Capacitor:

  • Ứng dụng mới: thêm platform iOS với package manager SPM:
npx cap add ios --packagemanager SPM

Xem Cài đặt Adapty SDK để biết toàn bộ các bước thiết lập.

Tải flow

getPaywall → getFlow

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

- const paywall = await adapty.getPaywall({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en' });
+ const flow = await adapty.getFlow({ placementId: 'YOUR_PLACEMENT_ID' });

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

- const paywall = await adapty.getPaywallForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID', locale: 'en' });
+ const flow = await adapty.getFlowForDefaultAudience({ placementId: 'YOUR_PLACEMENT_ID' });

getPaywallProducts(paywall) → getPaywallProducts(flow)

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

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

Mô hình dữ liệu

getFlow trả về một 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)remoteConfigs?: AdaptyRemoteConfig[] (mảng)Một flow mang một Remote Config cho mỗi ngôn ngữ đã cấu hình. Đọc ngôn ngữ phù hợp với người dùng: flow.remoteConfigs?.find((c) => c.lang === 'en').
productsflow.paywalls[i].productIdentifiersMã định danh sản phẩm giờ nằm trong từng biến thể flow, không nằm 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 — createFlowView giờ sẽ throw thay thế (xem Hiển thị flow).
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.
hasViewConfigurationrequestLocale vẫn nằm trên AdaptyOnboarding — chỉ có flow model là bỏ chúng.

Mã định danh sản phẩm được chuyển từ flow sang từng variation:

- const ids = paywall.products;
+ const ids = flow.paywalls[0].productIdentifiers;

Phương thức Web Paywall

openWebPaywallcreateWebPaywallUrl giữ nguyên tên, nhưng tùy chọn paywallOrProduct giờ nhận một AdaptyFlowPaywall (biến thể flow) thay vì AdaptyPaywall. Bạn vẫn có thể truyền vào AdaptyPaywallProduct. Hãy kiểm tra flow.paywalls không rỗng trước khi đọc phần tử đầu tiên:

  const flow = await adapty.getFlow({ placementId: 'YOUR_PLACEMENT_ID' });
- await adapty.openWebPaywall({ paywallOrProduct: paywall });
+ await adapty.openWebPaywall({ paywallOrProduct: 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 variation, do đó 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 });

Cũng giống như trong 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 sẽ tự động theo dõi các lượt xem đó.

Hiển thị flows

createPaywallView → createFlowView

Đổi tên hàm factory và truyền vào AdaptyFlow. Controller trả về được đổi tên từ PaywallViewController thành FlowViewController, nhưng các phương thức của nó (present, dismiss, setEventHandlers, showDialog) vẫn giữ nguyên. Kiểu params được đổi tên từ CreatePaywallViewParamsInput thành CreateFlowViewParamsInput:

- import { createPaywallView } from '@adapty/capacitor';
+ import { createFlowView } from '@adapty/capacitor';

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

createFlowView sẽ throw một AdaptyError nếu flow chưa được cấu hình view — thay thế cho việc kiểm tra hasViewConfiguration ở v3:

- if (paywall.hasViewConfiguration) {
-   const view = await createPaywallView(paywall);
-   await view.present();
- }
+ try {
+   const view = await createFlowView(flow);
+   await view.present();
+ } catch (error) {
+   // the flow has no view configured, or view creation failed
+ }

Flow view chỉ dùng một lần: sau khi bạn gọi dismiss(), view sẽ bị hủy và các event handler của nó sẽ bị xóa, vì vậy hãy gọi lại createFlowView nếu muốn hiển thị flow thêm một lần nữa.

Vùng an toàn trên Android

CreateFlowViewParamsInput bổ sung một tham số mới: enableSafeArea, kiểm soát padding vùng an toàn trên Android khi chạy ứng dụng. Tham số này nằm trong khóa android và mặc định là true:

const view = await createFlowView(flow, {
  android: { enableSafeArea: true },
});

Xử lý sự kiện

Giao diện event-handler được đổi tên từ EventHandlers sang FlowEventHandlers, và một callback cũng được đổi tên. Phần thân handler hiện tại không cần thay đổi code — chỉ cần đổi tên:

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

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

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

  • 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 ngay mà không cần cấu hình thêm. Chỉ gọi trực tiếp khi bạn override các handler đó.
  • Xử lý giao dịch trong Observer mode bên trong flow thông qua các handler mới onObserverPurchaseInitiated / onObserverRestoreInitiated. Xem Hiển thị flow trong Observer mode.

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

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

  • onAndroidSystemBack: Mặc định đã thay đổi từ đóng view sang giữ nguyên. Để khôi phục hành vi cũ, hãy 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ũ, hãy 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ũ, hãy trả về true từ handler.
  • onUrlPress: Mặc định hiện mở URL thông qua native layer, tuân theo cài đặt trình duyệt in-app hoặc bên ngoài từ dashboard. Ghi đè handler để tự mở URL.
  • View chỉ dùng một lần: Sau khi gọi dismiss(), view sẽ bị hủy. Gọi lại createFlowView để hiển thị flow một lần nữa.

Các API đã bị xóa

Các export đã bị xóa

Các symbol này không còn được export từ @adapty/capacitor nữa. Hãy xóa các import tương ứng:

  • AdaptyPaywall: Dùng AdaptyFlowAdaptyFlowPaywall thay thế.
  • ProductReference: Dùng AdaptyProductIdentifier, đọc từ flow.paywalls[i].productIdentifiers.
  • AdaptyPaywallBuilder: Đã bị xóa. Flow và paywall được render trực tiếp trên thiết bị.
  • AdaptyAndroidSubscriptionUpdateParameters: Dùng cấu trúc tham số mua hàng android lồng nhau (xem bên dưới).

activate: lockMethodsUntilReady

lockMethodsUntilReady (đã bị deprecated và không hoạt động từ v3) đã được xóa. Hãy xóa nó khỏi lời gọi activate — giữ lại sẽ không thể biên dịch:

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

makePurchase: Tham số Android

Kiểu dữ liệu phẳng (flat) đã bị deprecated của MakePurchaseParamsInput dành cho Android đã bị xóa — chỉ còn dạng lồng nhau (nested). Hãy chuyển các tham số mua hàng Android vào params: { android: { ... } }. Xem Thực hiện mua hàng để xem ví dụ đầy đủ.

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

API onboarding cũ đã bị deprecated trong v4.0, thay thế bằng Flow Builder. API này vẫn hoạt động, nhưng sẽ bị xóa trong phiên bản 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à OnboardingViewController.