Skip to main content
Version: 1.1.0 (Latest)

Tích hợp SDK Android Native

Thư viện TingeePaySDK (AAR) hỗ trợ tích hợp cổng thanh toán Tingee vào ứng dụng Android Native sử dụng ngôn ngữ Kotlin hoặc Java.

Android API 24+ Target SDK 36


1. Cài đặt SDK

Thực hiện các bước sau để tích hợp tệp AAR vào ứng dụng của bạn:

  1. Tải về file thư viện: tingeepaysdk-release.aar.
  2. Sao chép tệp tingeepaysdk-release.aar vừa tải vào thư mục app/libs/ của dự án (tự tạo thư mục libs nếu chưa tồn tại).
  3. Mở tệp build cấu hình của ứng dụng (trong module app) và thêm cấu hình dependencies tùy thuộc vào Gradle DSL bạn sử dụng:
app/build.gradle.kts
dependencies {
// Tích hợp tệp AAR cục bộ
implementation(files("libs/tingeepaysdk-release.aar"))

// Các thư viện bắt buộc SDK phụ thuộc (nhập nếu chưa có)
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("com.google.android.material:material:1.6.1")
implementation("androidx.constraintlayout:constraintlayout:2.0.0")
implementation("androidx.activity:activity:1.8.0")
}
  1. Đồng bộ lại dự án của bạn bằng cách nhấn FileSync Project with Gradle Files.

2. Khai báo quyền ứng dụng

SDK yêu cầu kết nối Internet để tải cổng thanh toán. Hãy chắc chắn rằng bạn đã định nghĩa quyền INTERNET trong tệp AndroidManifest.xml của ứng dụng:

app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.microsoft.com/apk/res/android"
package="your.package.name">

<!-- Thêm dòng này nếu chưa có -->
<uses-permission android:name="android.permission.INTERNET" />

<application ...>
...
</application>
</manifest>

3. Khởi động màn hình thanh toán

Cổng thanh toán cung cấp hai phương thức hiển thị chính: Toàn màn hình (FullScreen) hoặc Nửa màn hình (Bottom Sheet).

Trước khi mở SDK, bạn cần lấy paymentUrl từ hệ thống máy chủ (Backend) của bạn (qua API Tạo link thanh toán) và chuẩn bị returnUrl đã đăng ký.

3.1. Gọi từ Activity (Khuyên dùng)

Sử dụng ActivityResultLauncher để khởi động màn hình thanh toán và nhận kết quả trả về một cách hiện đại.

Bước 1: Đăng ký Launcher trong Activity của bạn

private val paymentResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
val status = data?.getStringExtra("EXTRA_PAYMENT_STATUS")
val orderId = data?.getStringExtra("EXTRA_ORDER_ID")
val transactionCode = data?.getStringExtra("EXTRA_TRANSACTION_CODE")
val errorCode = data?.getStringExtra("EXTRA_ERROR_CODE")
val errorMessage = data?.getStringExtra("EXTRA_ERROR_MESSAGE")
val rawJson = data?.getStringExtra("EXTRA_PAYMENT_DATA_JSON")

when (status) {
"success" -> { /* Thanh toán thành công */ }
"failed" -> { /* Thanh toán thất bại */ }
"cancelled" -> { /* Người dùng đã hủy giao dịch trên cổng */ }
"expired" -> { /* Mã thanh toán hết hạn */ }
"error" -> { /* Lỗi hệ thống phát sinh */ }
}
} else {
// Người dùng đóng màn hình SDK (bằng cử chỉ vuốt, nút quay lại vật lý) mà không có kết quả
}
}

Bước 2: Mở cổng thanh toán khi có URL

val intent = TingeePaySDK.createIntent(
context = this,
paymentUrl = paymentUrl, // URL thanh toán lấy từ API Backend của bạn
returnUrl = returnUrl, // URL/Deep link trả về đã khai báo
isEmbedded = true, // true: Ẩn các phần header/footer không cần thiết của web (khuyên dùng)
immediateResult = true, // true: Bắn kết quả trả về ngay khi hoàn tất
primaryColor = "#1E88E5", // Màu sắc thương hiệu dạng Hex (null = sử dụng mặc định)
isFullScreen = true // true: Toàn màn hình | false: Hiển thị Bottom Sheet (nửa màn hình)
)
paymentResultLauncher.launch(intent)

3.2. Gọi từ Fragment

Khi mở SDK từ một Fragment, bạn cần lưu ý hai điểm quan trọng sau:

  1. registerForActivityResult bắt buộc phải được khai báo dưới dạng thuộc tính (Property) ở cấp lớp của Fragment. Không được khai báo bên trong các hàm callback như onViewCreated(), onStart(), hoặc trong các sự kiện click listener (vi phạm sẽ gây lỗi IllegalStateException khi chạy ứng dụng).
  2. Sử dụng hàm requireContext() thay thế cho this khi truyền tham số ngữ cảnh.
CheckoutFragment.kt
class CheckoutFragment : Fragment() {

// ✅ Khai báo Launcher như một Property ở cấp lớp
private val paymentResultLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val status = result.data?.getStringExtra("EXTRA_PAYMENT_STATUS")
val orderId = result.data?.getStringExtra("EXTRA_ORDER_ID")
// Xử lý logic kết quả...
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

btnPay.setOnClickListener {
// ✅ Khởi tạo Intent và kích hoạt Launcher từ sự kiện click
val intent = TingeePaySDK.createIntent(
context = requireContext(), // Dùng requireContext()
paymentUrl = paymentUrl,
returnUrl = returnUrl,
isEmbedded = true,
immediateResult = true,
primaryColor = "#1E88E5",
isFullScreen = false // Ví dụ: mở dạng Bottom Sheet
)
paymentResultLauncher.launch(intent)
}
}
}

4. Mô tả các tham số cấu hình

Hàm TingeePaySDK.createIntent hỗ trợ các tham số cấu hình linh hoạt:

Tham sốKiểu dữ liệuMặc địnhMô tả
contextContextNgữ cảnh của Activity/Fragment đang gọi.
paymentUrlStringBắt buộc. Đường dẫn thanh toán được tạo từ API Backend.
returnUrlString?nullURL hoặc deep link để chuyển hướng ứng dụng sau khi hoàn thành.
isEmbeddedBooleantrueNếu đặt là true, SDK sẽ ẩn thanh header và footer mặc định của web cổng thanh toán để tạo cảm giác native.
immediateResultBooleantruetrue để gửi kết quả ngay lập tức khi hệ thống cổng thanh toán hoàn thành xử lý.
primaryColorString?nullMàu sắc chủ đạo của giao diện thanh toán dạng chuỗi Hex (ví dụ: "#E53935"). Nếu null, hệ thống sử dụng màu mặc định của cổng.
isFullScreenBooleantrueCấu hình chế độ hiển thị:
- true: Hiển thị toàn màn hình.
- false: Hiển thị dạng Bottom Sheet (chiếm khoảng 50% chiều cao màn hình, hỗ trợ kéo xuống để đóng).

5. Dữ liệu trả về từ SDK

Khi màn hình thanh toán kết thúc, SDK sẽ gọi hàm setResult(RESULT_OK, intent) và tự động đóng. Bạn có thể lấy các thông tin sau từ tệp Intent kết quả:

Key định danh dữ liệuKiểu dữ liệuMô tả
EXTRA_PAYMENT_STATUSStringTrạng thái giao dịch trả về: success / failed / cancelled / expired / error
EXTRA_ORDER_IDStringMã đơn hàng tương ứng trên hệ thống của bạn.
EXTRA_TRANSACTION_CODEStringMã giao dịch được ghi nhận trên hệ thống cổng thanh toán Tingee.
EXTRA_ERROR_CODEStringMã lỗi chi tiết (nếu có lỗi xảy ra).
EXTRA_ERROR_MESSAGEStringNội dung thông báo lỗi chi tiết (nếu có lỗi xảy ra).
EXTRA_PAYMENT_DATA_JSONStringToàn bộ thông tin cấu trúc JSON payload gốc từ cổng thanh toán.

[!NOTE] Nếu người dùng chủ động đóng màn hình SDK (như vuốt đóng Bottom Sheet) trước khi có trạng thái cuối cùng, resultCode trả về sẽ là RESULT_CANCELED (0) và không chứa bất kỳ dữ liệu bổ sung nào trong Intent.


6. Yêu cầu hệ thống tối thiểu

Danh mụcYêu cầu
Android SDK tối thiểuAPI 24 (Android 7.0 trở lên)
Target SDKAPI 36
Tương thích JavaJava 11
Quyền mạngBắt buộc quyền sử dụng INTERNET
Ngôn ngữ phát triểnKotlin hoặc Java

7. Các lưu ý quan trọng khi tích hợp

  • Quy trình tạo link: SDK di động không trực tiếp xử lý việc gọi API tạo đường dẫn thanh toán. Ứng dụng tích hợp có nhiệm vụ gọi về Backend của mình để nhận paymentUrl trước khi chuyển tiếp cho SDK.
  • Tự động Deeplink: Khi người dùng chọn hình thức thanh toán bằng ứng dụng ngân hàng, SDK sẽ tự động phát hiện và mở ứng dụng ngân hàng tương thích đã cài trên thiết bị. Trong trường hợp thiết bị chưa cài đặt ứng dụng ngân hàng đó, SDK sẽ hiển thị thông báo popup thân thiện để người dùng thử lại hoặc chọn cách thanh toán khác.
  • Bộ nhớ: SDK tự động giải phóng tài nguyên và dọn dẹp bộ nhớ đệm WebView khi đóng màn hình thanh toán để tránh gây rò rỉ bộ nhớ (memory leak).