Quick Start
Platform Examples
Checkout Customization
Mobile Recipes
start(...) có kiểu duy nhất, đồng thời tích hợp sẵn khả năng khôi phục
session bị bỏ dở. Chỉ sử dụng WebView thủ công nếu không SDK nào phù hợp với
stack của bạn.Điều kiện tiên quyết
Trước khi tích hợp Dodo Payments vào ứng dụng di động, hãy đảm bảo bạn có:- Tài khoản Dodo Payments: Tài khoản merchant đang hoạt động có quyền truy cập API
- Thông tin xác thực API: API key và webhook secret key từ dashboard
- Dự án ứng dụng di động: Ứng dụng Android, iOS, React Native hoặc Flutter
- Backend Server: Để xử lý việc tạo checkout session một cách an toàn
Quy trình tích hợp
Tích hợp trên thiết bị di động tuân theo quy trình bảo mật gồm 4 bước, trong đó backend xử lý các lệnh gọi API còn ứng dụng di động quản lý trải nghiệm người dùng.status chỉ là gợi ý UI về nội dung hiển thị cho người dùng. Luôn cấp quyền từ webhook payment.succeeded / subscription.active trên backend - không bao giờ chỉ dựa vào kết quả trên thiết bị di động.Backend: Create Checkout Session
Checkout Session API Docs
Mobile: Get Checkout URL
- iOS (Swift)
- Android (Kotlin)
- React Native (JavaScript)
- Flutter (Dart)
Mobile: Open Checkout in Browser
Pick your mobile SDK
Backend: Handle Payment Completion
Chọn SDK
Mọi SDK di động đều cung cấp cùng một contract: một lệnh gọistart(...) mở checkout được host bởi Dodo trong giao diện trình duyệt native của nền tảng và trả về CheckoutResult có kiểu, trong đó status là succeeded, failed, cancelled, pending hoặc expired. Không SDK nào chứa API key hoặc gọi Dodo Payments API, và cả bốn SDK đều hỗ trợ khôi phục session bị bỏ dở.
Android
com.dodopayments.api:checkout-android mở Chrome Custom Tab. Yêu cầu minSdk 23.iOS
dodopayments-mobile-sdk-ios mở SFSafariViewController. Yêu cầu iOS 16+.React Native
@dodopayments/react-native-checkout, Turbo Module hoạt động trên cả hai native core. Yêu cầu React Native 0.76+.Flutter
dodopayments_checkout, kênh Pigeon hoạt động trên cả hai native core. Yêu cầu Flutter 3.44+.Đăng ký Callback URL Scheme
Cả bốn SDK đều chuyển quyền điều khiển lại cho ứng dụng thông qua custom URL scheme do bạn chọn, ví dụmyapp://checkout/return. Đăng ký scheme này một lần cho
mỗi nền tảng:
- Android
- iOS
- Expo
checkout_url trong
trình duyệt hệ thống của nền tảng (Android Custom Tabs / iOS SFSafariViewController) và chặn
điều hướng đến return_url, sau đó đọc các query parameter status và payment_id. Các SDK ở trên thực hiện chính xác việc này thay cho bạn.Tùy chỉnh giao diện
Mọi SDK đều chấp nhận tham số tùy chọncustomization trên start(...) /
CheckoutParams để kiểm soát giao diện và hành vi của giao diện trình duyệt native - thanh công cụ, nút và cách hiển thị. Phần này tách biệt với theme riêng của trang checkout, được cấu hình phía server thông qua customization.theme_config trên checkout session.
Các tùy chọn được nhóm theo nền tảng vì Android Custom Tab và iOS
SFSafariViewController cung cấp các control native khác nhau. Tất cả field đều là tùy chọn; nếu bỏ qua hoàn toàn customization, giao diện mặc định của từng nền tảng sẽ được sử dụng.
Android - Custom Tab
Android - Custom Tab
default hiển thị biểu tượng “X” của hệ thống; back thay vào đó vẽ mũi tên quay lại.iOS - SFSafariViewController
iOS - SFSafariViewController
pageSheet hiển thị dưới dạng card có thể vuốt để dismiss; fullScreen bao phủ toàn bộ màn hình.presentationStyle là fullScreen - pageSheet giữ các thanh cố định bất kể cài đặt này.- React Native
- Flutter
- Android (Kotlin)
- iOS (Swift)
Tùy chỉnh trang Checkout
Phần Tùy chỉnh giao diện ở trên kiểm soát giao diện trình duyệt native - thanh công cụ, nút và bảng màu. Bản thân trang checkout - các field hiển thị, theme và phương thức thanh toán - được cấu hình phía server khi bạn tạo checkout session. Những tham số này có ảnh hưởng lớn nhất đến chuyển đổi trên thiết bị di động. Các tham số bên dưới nằm ở ba vị trí khác nhau trong request checkout session - cột Vị trí cho biết mỗi tham số thuộc object nào. Đây là lỗi phổ biến nhất: tham số đặt sai object sẽ bị bỏ qua mà không có thông báo.
show_order_details: false moves the contact and payment fields above the fold, instead of behind the order summary.
minimal_address: true để chỉ thu thập postcode thay vì toàn bộ các field street, city và state:

minimal_address: true reduces the billing address to a single postcode field.
theme: "system" để checkout tuân theo tùy chọn giao diện sáng hoặc tối của thiết bị:

With theme: system, the checkout follows the device's light or dark appearance automatically.
Full checkout session parameter reference
Recipe tối ưu cho thiết bị di động
Mỗi recipe bên dưới là một request body checkout session hoàn chỉnh. Sao chép recipe phù hợp với tình huống của bạn, thay product ID và truyền vào endpoint tạo session của backend.Minimal Mobile Checkout - fastest path to payment
Minimal Mobile Checkout - fastest path to payment
- Node.js SDK
- Python SDK
One-Click Returning Customer - saved card, instant confirmation
One-Click Returning Customer - saved card, instant confirmation
confirm: true để bỏ qua hoàn toàn form checkout.- Node.js SDK
- Python SDK
status trong deep-link return chỉ là gợi ý UI. Xác nhận quyền truy cập bằng cách lắng nghe webhook payment.succeeded trên backend.Subscription with Free Trial - trial before first charge
Subscription with Free Trial - trial before first charge
- Node.js SDK
- Python SDK
subscription.active - không phải khi SDK di động trả về. Xem Subscription Integration Guide để biết toàn bộ quy trình webhook.On-Demand Mandate - save a card for future variable charges
On-Demand Mandate - save a card for future variable charges
- Node.js SDK
- Python SDK
Quy trình Subscription trên thiết bị di động
Subscription được tạo thông qua cùng quy trình checkout session dùng cho thanh toán một lần - SDK di động mở checkout được host, khách hàng đăng ký và ứng dụng xử lý deep-link return. Sau đó, vòng đời subscription được quản lý hoàn toàn trên backend.Subscription định kỳ thông thường
Đối với billing theo khoảng thời gian cố định (hàng tháng, hàng năm), hãy tạo checkout session với sản phẩm subscription và deep-linkreturn_url. Backend của bạn nhận subscription.active khi subscription được xác nhận.
On-Demand Subscription
On-demand subscription cho phép bạn ủy quyền payment method của khách hàng một lần và charge các khoản biến đổi sau đó - phù hợp cho nạp ví, pay-as-you-go và mọi tình huống chưa biết trước số tiền charge. Xem recipe On-Demand Mandate ở trên để biết request body đầy đủ. Các lưu ý chính trên thiết bị di động:- Đặt
show_on_demand_tag: falseđể trang checkout không hiển thị ngôn ngữ “subscription” hoặc “on-demand”. Với các trường hợp tokenise card, khách hàng không mong đợi thuật ngữ subscription. - Sau khi mandate được ủy quyền, backend nhận
subscription.active. Lưusubscription_id- bạn sẽ sử dụng nó cho mọi khoản charge trong tương lai.
Subscription có Free Trial
Truyềnsubscription_data.trial_period_days trong checkout session để cung cấp thời gian dùng thử trước chu kỳ billing đầu tiên. Khách hàng ủy quyền payment method khi đăng ký dùng thử; khoản charge đầu tiên được thực hiện tự động khi thời gian dùng thử kết thúc. Xem recipe Subscription with Free Trial ở trên để biết request body đầy đủ.
Nâng cấp và hạ cấp
Thay đổi plan được thực hiện qua API trên backend, không phải qua checkout session mới. Dodo Payments tự động tính proration. Để cung cấp tùy chọn self-service cho khách hàng, hãy nhúng hoặc liên kết đến Customer Portal.Subscription Integration Guide
On-Demand Subscriptions
Upgrade / Downgrade
Customer Portal
Giảm tỷ lệ rời bỏ Checkout
Checkout trên thiết bị di động có tỷ lệ bỏ dở cao hơn web - màn hình nhỏ hơn, nhiều yếu tố gây xao nhãng hơn và form dài hơn đều góp phần vào điều này. Những cải thiện nhanh nhất đến từ chính cấu hình checkout session.Tối ưu Form
Điền sẵn dữ liệu khách hàng
Mỗi field mà khách hàng không phải nhập là một lý do giúp họ không rời bỏ:- Khách hàng mới - đặt
customer.emailvàcustomer.nametừ auth session. - Khách hàng quay lại - đặt
customer.customer_idđể tự động điền sẵn mọi thông tin đã lưu. - Currency - luôn truyền
billing_currencyvàbilling_address.countrycùng nhau.
Công cụ khôi phục
Abandoned Cart Recovery
Payment Retries
Subscription Dunning
Recovery Overview
Best Practices
- Bảo mật: Không bao giờ đưa API key vào ứng dụng. Tạo checkout session trên backend và chỉ truyền
checkout_urlkết quả đến client. - Quyền quyết định: Xem
CheckoutResult.statuslà gợi ý UI. Chỉ cấp quyền sau khi backend xác nhận thanh toán. - Trải nghiệm người dùng: Hiển thị trạng thái loading trong khi backend tạo session và xử lý
cancellednhư một kết quả bình thường thay vì lỗi. - Kiểm thử: Dùng test mode và test card, đồng thời xác minh vòng lặp return-URL trên thiết bị thật cũng như simulator.
- Chuyển đổi: Đặt
show_order_details: falsevàminimal_address: trueđể đạt tỷ lệ hoàn tất checkout di động tốt nhất. Đưa phương thức thanh toán lên phần đầu màn hình và giảm số field trong form là hai thay đổi có tác động lớn nhất. - Currency: Luôn truyền rõ ràng cả
billing_currencyvàbilling_address.country- nếu thiếu một trong hai, Adaptive Currency có thể thay đổi currency billing dựa trên địa chỉ IP của khách hàng. - On-demand billing: Đặt
show_on_demand_tag: falsekhi dùng on-demand subscription để tokenise card. Khách hàng sử dụng quy trình nạp ví không mong đợi thấy ngôn ngữ “subscription”. - Khôi phục: Bật khôi phục giỏ hàng bị bỏ dở trong dashboard Dodo Payments để tự động tái tương tác với khách hàng không hoàn tất checkout.
Khắc phục sự cố
Các vấn đề thường gặp
- Không bao giờ nhận được callback: Scheme trong
returnUrlphải khớp với scheme bạn đã đăng ký. Trên Android, đó là manifest placeholderdodoCallbackScheme; trên iOS và React Native, đó là URL typeInfo.plist. - Checkout quay lại trình duyệt thay vì ứng dụng (iOS): Bạn chưa chuyển tiếp URL đến. Gọi
DodoCheckout.handleOpenURL(url)từ.onOpenURL,scene(_:openURLContexts:)hoặc listenerLinkingcủa React Native. PLATFORM_ERRORtrên Android: Thường là do scheme không khớp. Cũng có thể xảy ra nếuMainActivityđặtandroid:taskAffinity=""(giá trị mặc địnhflutter create), khiến một số bản build OEM làm mất checkout đang thực hiện.ALREADY_IN_PROGRESS: Một checkout vẫn đang mở. Hãy chờ hoặc dismiss checkout trước đó rồi mới bắt đầu checkout khác.- Build thất bại với placeholder chưa được resolve: Bạn đã thêm Android SDK nhưng chưa đặt
manifestPlaceholders["dodoCallbackScheme"]. - Thanh toán thành công nhưng chưa cấp quyền: Đây là điều được dự đoán nếu bạn dựa vào kết quả trên thiết bị di động. Thay vào đó, hãy cấp quyền từ webhook
payment.succeeded/subscription.active. - Apple Pay / Google Pay không hiển thị trên thiết bị di động: Checkout đang được tải bên trong embedded WebView (
WKWebView/ AndroidWebView), làm ẩn các ví và có thể khiến 3-D Secure bị lỗi. Hãy mở bằng SDK hoặc trong trình duyệt hệ thống (Custom Tabs /SFSafariViewController).
Tài nguyên bổ sung
- Hướng dẫn tích hợp thanh toán
- Tài liệu Webhook
- Quy trình kiểm thử
- Câu hỏi thường gặp về kỹ thuật
- Tùy chỉnh Checkout Session
- On-Demand Subscriptions
- Nâng cấp/hạ cấp Subscription
- Khôi phục giỏ hàng bị bỏ dở
- Customer Portal
