Chuyển tới nội dung chính

XMDT — Android

SDK native, không dùng WebView. Viết bằng Kotlin, gọi được từ Java. Độc lập với SDK v2 — không trộn import vn.alogame.kycsdk với vn.oeg.sdk.v2, và đừng kỳ vọng chúng chia sẻ state với nhau.

Các môi trường
Môi trườngBase URL
Devhttps://api-xmdt.dev.alogame.vn
Prodhttps://api-xmdt.alogame.vn

Cả hai đều đang hoạt động. gameId của bạn phải được Alogame Operations bật XMDT trước khi dùng được ở cả hai — xem Tích hợp phía Server.

Đọc phần này trước

Tích hợp Server mô tả lệnh gọi duy nhất phía server của bạn để mint sessionToken. Client của bạn không bao giờ gọi trực tiếp API danh tính của Alogame và không bao giờ thấy secret HMAC của bạn.

1. Thêm dependency​

settings.gradle.kts
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}
app/build.gradle.kts
dependencies {
implementation("com.github.alo-game:alogame-kyc-sdk-android:0.1.1")
}
Coordinate là repo GitHub, không phải vn.alogame:kyc-sdk

Dùng com.github.alo-game:alogame-kyc-sdk-android:<version> — JitPack chỉ phục vụ build dưới đúng coordinate mà nó được request lần đầu, và đó luôn là dạng org/repo GitHub này. Một groupId tùy chỉnh như vn.alogame:kyc-sdk không resolve được dù nó có xuất hiện trong build.gradle của chính release repo; đã xác nhận bằng cách curl trực tiếp jitpack.io (404 ở vn/alogame/kyc-sdk/, 200 ở com/github/alo-game/alogame-kyc-sdk-android/).

Xem các version có sẵn tại jitpack.io/#alo-game/alogame-kyc-sdk-android.

Artifact đã publish có zero dependency runtime bên thứ ba — không có gì xung đột với dependency tree hiện tại của app bạn.

2. Khởi tạo​

Một lần, lúc app khởi động:

Kotlin
import vn.alogame.kycsdk.AlogameKycSdk
import vn.alogame.kycsdk.AlogameKycConfig
import vn.alogame.kycsdk.AlogameKycEnv

AlogameKycSdk.init(
context,
AlogameKycConfig(env = AlogameKycEnv.DEV)
)
Java
import vn.alogame.kycsdk.AlogameKycSdk;
import vn.alogame.kycsdk.AlogameKycConfig;
import vn.alogame.kycsdk.AlogameKycEnv;

AlogameKycSdk.INSTANCE.init(
context,
new AlogameKycConfig(AlogameKycEnv.DEV, null)
);
Game thương hiệu OEG

AlogameKycConfig có thêm tham số thứ ba tùy chọn, brand — AlogameKycBrand.ALO (mặc định) hoặc AlogameKycBrand.OEG. Nó chỉ đổi logo hiển thị ở phần header của màn hình; env vẫn là thứ duy nhất quyết định endpoint mạng.

Kotlin
AlogameKycConfig(env = AlogameKycEnv.DEV, brand = AlogameKycBrand.OEG)

3. Set game role​

Sau khi bạn có sessionToken từ server của mình (xem Tích hợp Server):

Kotlin
AlogameKycSdk.setGameRole(
uid = "player_account_name", // phải khớp với `username` mà server bạn dùng để mint session
sessionToken = sessionToken,
serverId = "server_01", // tùy chọn — bỏ qua nếu không áp dụng
roleId = "character_123" // tùy chọn
)
Java
AlogameKycSdk.INSTANCE.setGameRole("player_account_name", sessionToken, "server_01", "character_123");

uid và sessionToken luôn đến cùng nhau từ cùng một response của server — không bao giờ gọi hàm này với một trong hai mà thiếu cái còn lại. Đổi sang uid khác sẽ xóa mọi trạng thái đã-xác-thực được cache của uid trước đó.

4. Hiện màn hình​

Kotlin
import vn.alogame.kycsdk.AlogameKycListener
import vn.alogame.kycsdk.AlogameKycResult

AlogameKycSdk.show(activity, object : AlogameKycListener {
override fun onResult(result: AlogameKycResult) {
when (result) {
is AlogameKycResult.Success -> {
// Chỉ là tín hiệu giao diện — xem cảnh báo dưới đây trước khi unlock bất cứ thứ gì
}
is AlogameKycResult.Failed -> {
println("XMDT failed: ${result.reason}${result.message?.let { " ($it)" } ?: ""}")
}
is AlogameKycResult.Cancelled -> {
// Người chơi đóng form — chỉ xảy ra khi xmdtRequired là false
}
}
}
})
Java
AlogameKycSdk.INSTANCE.show(activity, new AlogameKycListener() {
@Override
public void onResult(AlogameKycResult result) {
if (result instanceof AlogameKycResult.Success) {
// Chỉ là tín hiệu giao diện — xem cảnh báo dưới đây
} else if (result instanceof AlogameKycResult.Failed) {
AlogameKycFailReason reason = ((AlogameKycResult.Failed) result).getReason();
String message = ((AlogameKycResult.Failed) result).getMessage();
} else if (result instanceof AlogameKycResult.Cancelled) {
// Người chơi đóng form
}
}

@Override
public void onSessionTokenNeeded(String uid) { /* xem "Làm mới token đã hết hạn" dưới đây */ }
});
onResult là tín hiệu giao diện, không phải bằng chứng

Success ở đây chỉ có nghĩa là thiết bị người chơi báo rằng luồng đã hoàn tất — một client bị mod có thể tạo ra callback này mà chưa từng xác thực gì cả. Trước khi cho người chơi qua bất cứ thứ gì phụ thuộc vào XMDT, hãy gọi lại POST /xmdt/session từ server của bạn và tin vào trường xmdtCompleted trong response đó. Xem Tích hợp Server.

SDK tự quản lý toàn bộ màn hình của nó — họ tên, ngày sinh, nhập số điện thoại, OTP, và consent đều được xử lý nội bộ, và không có gì người chơi nhập vào từng hiện ra trước app của bạn. onResult chỉ fire đúng một lần cho mỗi lệnh show(), trên main thread, sau khi màn hình đã đóng — an toàn để hiện UI của bạn ngay lập tức.

Gọi show() lần nữa khi một luồng đang mở sẽ bị bỏ qua (có log, không crash).

Xử lý Failed​

Kotlin
import vn.alogame.kycsdk.AlogameKycFailReason

when (result.reason) {
AlogameKycFailReason.notInitialized,
AlogameKycFailReason.noGameRole -> {
// Lỗi tích hợp phía bạn — init()/setGameRole() chưa được gọi
// trước. Không bao giờ hiện cái này cho người chơi; sửa lại thứ tự gọi.
}
AlogameKycFailReason.sessionUnavailable,
AlogameKycFailReason.sessionInvalid -> {
// Không lấy được session token dùng được. Mint một token mới và thử lại
// show() từ đầu.
}
AlogameKycFailReason.otpAttemptsExceeded,
AlogameKycFailReason.otpUnavailable,
AlogameKycFailReason.rateLimited -> {
// Người chơi (hoặc mạng của họ) chạm giới hạn chống lạm dụng. Hiện thông báo chung
// "thử lại sau" — không tiết lộ giới hạn nào bị chạm.
}
AlogameKycFailReason.serviceUnavailable -> {
// Dịch vụ danh tính của Alogame bị down sau khi người chơi đã
// tự thử lại một lần trong màn hình. Cho họ thử show() lại sau.
}
AlogameKycFailReason.unknownError -> {
// Catch-all để tương thích về sau. Không bao giờ crash.
}
}

Các lỗi có thể phục hồi (nhập sai OTP, lỗi validate, mạng chập chờn tạm thời) được xử lý ngay trong màn hình riêng của SDK và không bao giờ tới onResult — mọi lý do Failed ở trên đều là trường hợp luồng không thể tiếp tục, không phải trường hợp người chơi lỡ gõ nhầm.

Làm mới token đã hết hạn​

Hai cách để cấp một sessionToken mới khi token từ setGameRole hết hạn giữa luồng — chọn một trong hai:

Dùng closure (dùng được nếu app của bạn giữ được closure qua ranh giới SDK):

Kotlin
AlogameKycSdk.init(
context,
AlogameKycConfig(
env = AlogameKycEnv.DEV,
tokenProvider = AlogameKycTokenProvider { uid, callback ->
// Gọi lại endpoint mint của server bạn cho uid này, rồi:
callback.onToken(newSessionTokenOrNull)
}
)
)

Dùng callback (cho lớp bridge/engine không truyền được closure qua ranh giới ngôn ngữ — không set tokenProvider, cài đặt hàm dưới đây thay vào đó):

Kotlin
override fun onSessionTokenNeeded(uid: String) {
// Mint token mới cho `uid`, rồi:
AlogameKycSdk.provideSessionToken(newToken)
// hoặc, nếu không lấy được:
AlogameKycSdk.abortPendingToken()
}

Nếu bạn không cài đặt cách nào, một token hết hạn sẽ kết thúc luồng với sessionUnavailable thay vì treo mãi.

Xoay màn hình​

Màn hình hỗ trợ cả dọc và ngang — không cần cấu hình gì phía bạn.

Tham khảo​

TypeMục đích
AlogameKycSdkToàn bộ API công khai — init, setGameRole, setPrefill, isVerified, show, provideSessionToken, abortPendingToken
AlogameKycConfig(env, tokenProvider, brand)Truyền một lần vào init — brand tùy chọn, mặc định AlogameKycBrand.ALO
AlogameKycEnvDEV | PROD
AlogameKycBrandALO | OEG — chỉ thay đổi giao diện, không ảnh hưởng tới việc chọn env/endpoint
AlogameKycResultSuccess | Failed(reason, message) | Cancelled
AlogameKycFailReason9 giá trị cố định — xem phần trên
AlogameKycListeneronResult(result), tùy chọn onSessionTokenNeeded(uid)

AlogameKycSdk.setPrefill(fullName) là tùy chọn — nếu lớp đăng nhập của bạn đã có sẵn tên người chơi (ví dụ từ social login), truyền vào đây trước khi gọi show() để prefill field trong form. Nó chỉ giữ trong memory và không bao giờ được gửi đi đâu cho tới khi người chơi đã thấy và có thể sửa nó.

AlogameKycSdk.isVerified() đọc từ một cache trong memory của lần chạy thành công gần nhất — không phải một nguồn để authorize, cùng lưu ý như onResult ở trên. Chỉ dùng nó cho trạng thái UI (ví dụ: ẩn nút "Xác thực ngay"), không bao giờ dùng làm cổng chặn thực sự.