Thực hiện mua hàng trong ứng dụng di động với Capacitor SDK
Hiển thị paywall trong ứng dụng di động là bước thiết yếu để cung cấp cho người dùng quyền truy cập vào nội dung hoặc dịch vụ cao cấp. Tuy nhiên, chỉ khi Adapty tự render màn hình — tức là một flow, hoặc paywall từ Paywall Builder cũ — thì việc hiển thị paywall mới tự hỗ trợ mua hàng mà không cần thêm gì.
Nếu bạn tự render màn hình trong code của mình, bạn cần sử dụng một phương thức riêng gọi là .makePurchase() để hoàn tất giao dịch và mở khóa nội dung mong muốn. Phương thức này là cổng để người dùng tương tác với các paywall và thực hiện giao dịch của họ.
Nếu paywall của bạn có ưu đãi đang hoạt động cho sản phẩm mà người dùng muốn mua, Adapty sẽ tự động áp dụng ưu đãi đó tại thời điểm thanh toán.
Hãy đảm bảo bạn đã hoàn thành cấu hình ban đầu mà không bỏ qua bất kỳ bước nào. Nếu không, chúng tôi sẽ không thể xác thực các giao dịch mua.
Thực hiện mua hàng
Adapty có hiển thị màn hình của bạn không? Đối với paywall dạng flow hoặc Paywall Builder, giao dịch mua hàng được xử lý tự động — bạn có thể bỏ qua bước này.
Cần hướng dẫn từng bước? Xem hướng dẫn quickstart để có hướng dẫn triển khai đầy đủ từ đầu đến cuối.
try {
const result = await adapty.makePurchase({ product });
if (result.type === 'success') {
const isSubscribed = result.profile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
console.log('User is now subscribed!');
}
} else if (result.type === 'user_cancelled') {
console.log('Purchase cancelled by user');
} else if (result.type === 'pending') {
console.log('Purchase is pending');
}
} catch (error) {
console.error('Purchase failed:', error);
}
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
| product | bắt buộc | Một đối tượng AdaptyPaywallProduct lấy từ flow thông qua getPaywallProducts. |
Tham số phản hồi:
| Tham số | Mô tả |
|---|---|
| result | Một đối tượng AdaptyPurchaseResult với trường type cho biết kết quả giao dịch ('success', 'user_cancelled', hoặc 'pending') và trường profile chứa AdaptyProfile đã được cập nhật khi mua hàng thành công. |
Thay đổi gói đăng ký khi thực hiện mua hàng
Khi người dùng chọn một gói đăng ký mới thay vì gia hạn gói hiện tại, cách hoạt động sẽ khác nhau tùy theo cửa hàng:
- Đối với App Store, gói đăng ký được tự động cập nhật trong nhóm gói đăng ký. Nếu người dùng mua một gói đăng ký từ nhóm này trong khi đã có gói đăng ký từ nhóm khác, cả hai gói sẽ hoạt động cùng lúc.
- Đối với Google Play, gói đăng ký không được tự động cập nhật. Bạn cần xử lý việc chuyển đổi trong code ứng dụng của mình như mô tả bên dưới.
Để thay thế gói đăng ký bằng một gói khác trên Android, hãy gọi phương thức .makePurchase() với tham số bổ sung:
try {
const result = await adapty.makePurchase({
product,
params: {
android: {
subscriptionUpdateParams: {
oldSubVendorProductId: 'old_product_id',
prorationMode: 'charge_prorated_price'
},
isOfferPersonalized: true
}
}
});
if (result.type === 'success') {
const isSubscribed = result.profile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
console.log('Subscription updated successfully!');
}
} else if (result.type === 'user_cancelled') {
console.log('Purchase cancelled by user');
} else if (result.type === 'pending') {
console.log('Purchase is pending');
}
} catch (error) {
console.error('Purchase failed:', error);
}
Tham số yêu cầu bổ sung:
| Tham số | Bắt buộc | Mô tả |
|---|---|---|
| params | tùy chọn | Một object kiểu MakePurchaseParamsInput chứa các tham số mua hàng theo từng nền tảng. |
Cấu trúc MakePurchaseParamsInput bao gồm:
{
android: {
subscriptionUpdateParams: {
oldSubVendorProductId: 'old_product_id',
prorationMode: 'charge_prorated_price'
},
isOfferPersonalized: true
}
}
Bạn có thể đọc thêm về gói đăng ký và các chế độ thay thế trong tài liệu Google Developer:
- Về các chế độ thay thế
- Khuyến nghị từ Google về các chế độ thay thế
- Chế độ thay thế
CHARGE_PRORATED_PRICE. Lưu ý: phương thức này chỉ khả dụng khi nâng cấp gói đăng ký. Hạ cấp không được hỗ trợ. - Chế độ thay thế
DEFERRED. Lưu ý: Việc thay đổi gói đăng ký thực sự chỉ diễn ra khi chu kỳ thanh toán hiện tại kết thúc.
Quản lý gói trả trước (Android)
Nếu người dùng ứng dụng của bạn có thể mua gói trả trước (ví dụ: mua gói đăng ký không tự gia hạn cho vài tháng), bạn có thể bật giao dịch đang chờ xử lý cho các gói trả trước.
await adapty.activate({
apiKey: 'YOUR_PUBLIC_SDK_KEY',
params: {
android: {
pendingPrepaidPlansEnabled: true,
},
}
});
Đổi mã ưu đãi trên iOS
Về offer code
Offer code cho phép bạn cung cấp giảm giá hoặc dùng thử miễn phí cho những người dùng cụ thể. Khác với các ưu đãi thông thường được áp dụng tự động, offer code được phân phối bên ngoài ứng dụng — qua email marketing, mạng xã hội, hoặc tài liệu in ấn. Người dùng đổi code bằng cách nhập code trong App Store, truy cập URL đổi thưởng, hoặc thông qua hộp thoại trong ứng dụng.
Để thiết lập offer code, mở một gói đăng ký trong App Store Connect và vào mục Offer Codes. Bạn có thể tạo ba loại offer code:
- Free — gói đăng ký miễn phí trong một khoảng thời gian nhất định, sau đó gia hạn theo giá đầy đủ.
- Pay as you go — người dùng trả giá giảm mỗi chu kỳ thanh toán trong một khoảng thời gian nhất định, sau đó gói đăng ký gia hạn theo giá đầy đủ.
- Pay up front — người dùng trả một mức giá giảm duy nhất cho toàn bộ thời gian ưu đãi, sau đó gói đăng ký gia hạn theo giá đầy đủ.
Bạn không cần thêm offer code vào Adapty. Apple gắn thẻ mọi giao dịch trong thời gian ưu đãi với danh mục offer code. Điều này bao gồm lần đổi code đầu tiên và tất cả các lần gia hạn có giảm giá tiếp theo. Adapty phát hiện thẻ này và ghi lại mỗi giao dịch với danh mục ưu đãi offer_code. Khi thời gian ưu đãi kết thúc và gói đăng ký gia hạn theo giá đầy đủ, thẻ sẽ không còn nữa. Bạn có thể lọc analytics theo loại ưu đãi Offer Code trong Adapty Dashboard.
Xử lý sự chênh lệch doanh thu
Nếu bạn nhận thấy một giao dịch offer code xuất hiện trong Adapty với giá sản phẩm đầy đủ thay vì giá ưu đãi đã giảm, hãy kiểm tra các điều sau trong App Store Connect:
- Offer code đã được cấu hình đúng giá cho tất cả các khu vực mà người dùng có thể đổi.
- Giá ưu đãi được thiết lập cho quốc gia hoặc khu vực cụ thể của người dùng. Apple gửi giá theo khu vực trong giao dịch. Nếu không có giá theo khu vực được cấu hình cho ưu đãi, Apple có thể gửi giá sản phẩm đầy đủ thay thế.
Bạn có thể lọc và xác minh các giao dịch offer code trong Adapty Dashboard theo loại ưu đãi Offer Code và bộ lọc Offer Discount Type.
Promo code cũ (đã ngừng hỗ trợ)
Apple đã ngừng hỗ trợ promo code cho in-app purchase vào tháng 3 năm 2026. Offer code thay thế chúng với nhiều tính năng hơn: điều kiện đủ điều kiện có thể cấu hình, ngày hết hạn, và lên đến 1 triệu code mỗi quý. Nếu trước đây bạn sử dụng promo code cho in-app purchase, hãy chuyển sang offer code trong App Store Connect.
Promo code cũ (giới hạn 100 code mỗi ứng dụng mỗi phiên bản) cấp quyền truy cập miễn phí vào gói đăng ký. Khác với offer code, Apple không bao gồm thông tin giảm giá trong các giao dịch promo code — Apple gửi giá sản phẩm đầy đủ trong biên lai. Kết quả là Adapty đã ghi lại những giao dịch này theo giá đầy đủ, gây ra sự chênh lệch doanh thu giữa analytics Adapty và App Store Connect.
Nếu bạn thấy các giao dịch lịch sử theo giá đầy đủ mà đáng ra phải miễn phí, nhiều khả năng chúng đến từ promo code cũ. Vì những code này hiện đã ngừng hỗ trợ, hãy chuyển sang offer code để theo dõi doanh thu chính xác.
Để hiển thị giao diện nhập mã trong ứng dụng của bạn:
try {
await adapty.presentCodeRedemptionSheet();
} catch (error) {
console.error('Failed to present code redemption sheet:', error);
}
Theo quan sát của chúng tôi, giao diện nhập mã ưu đãi trong một số ứng dụng có thể hoạt động không ổn định. Chúng tôi khuyến nghị bạn chuyển hướng người dùng trực tiếp đến App Store.
Để thực hiện điều này, bạn cần mở URL theo định dạng sau:
https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}
Sản phẩm được quảng bá từ App Store
Ứng dụng của bạn có thể tiếp quản các in-app purchase được quảng bá kể từ SDK phiên bản 4.1.1, trên iOS 16.4 trở lên. Với iOS dưới 16.4, sự kiện này sẽ không bao giờ kích hoạt và các sản phẩm được quảng bá sẽ tự hoàn tất. Sự kiện này cũng không kích hoạt trên Android.
Khi người dùng bắt đầu mua hàng từ trang sản phẩm App Store của bạn và giao dịch được chuyển sang ứng dụng, SDK sẽ tự động hoàn tất giao dịch đó — màn hình mua hàng của Apple hiển thị ngay lập tức và Adapty xử lý giao dịch như bất kỳ sản phẩm mua hàng nào khác. Bạn không cần viết thêm bất kỳ đoạn code nào.
Nếu sản phẩm được quảng bá kèm theo ưu đãi gói đăng ký, SDK sẽ tự động áp dụng ưu đãi đó khi mua hàng. Ưu đãi được đọc từ purchase intent của App Store, tính năng này chỉ khả dụng trên iOS 18.0 trở lên. Trên iOS 16.4–17.x, giao dịch mua sẽ được thực hiện theo giá gốc.
Để tự xử lý việc hoàn tất giao dịch — ví dụ như hiển thị màn hình của bạn trước — hãy lắng nghe sự kiện 'onPromotedPurchaseReceived' và truyền sản phẩm vào makePromotedPurchase:
const listener = await adapty.addListener('onPromotedPurchaseReceived', async ({ product }) => {
const result = await adapty.makePromotedPurchase({ product });
// process the purchase result
});
Trong khi listener của bạn được đăng ký, SDK sẽ ngừng hoàn tất các promoted purchase thay bạn. Nếu handler của bạn không bao giờ gọi makePromotedPurchase, giao dịch mua sẽ không xảy ra: App Store chuyển sản phẩm đến app của bạn và chờ đợi.
makePromotedPurchase không nhận tham số mua — một promoted product đến từ App Store chứ không phải từ paywall, nên nó không mang theo ngữ cảnh paywall. Hàm này trả về cùng AdaptyPurchaseResult như makePurchase.
Việc gọi adapty.removeAllListeners() sẽ xóa cả listener xử lý promoted-purchase cùng với các listener còn lại, và SDK sẽ tự động tiếp quản việc hoàn tất giao dịch. Hãy đăng ký lại listener nếu ứng dụng của bạn vẫn cần tự xử lý việc hoàn tất.