Skip to content

Tích hợp Android SDK ​

Hướng dẫn tích hợp SmartOTP Android SDK, phiên bản 0.4.0. Viết bằng Kotlin; entry point là object SdkSoft.

Cài đặt ​

Giải nén Cake_SOTP_SDK_v0.4.0_1.zip vào project của bạn — trong project mẫu, nó nằm dưới thư mục libs.

groovy
repositories {
    maven { url rootDir.path + "/libs/" }
}
groovy
implementation "xyz.be.cake.smartotpsdk:legacy:0.4.0"

Khởi tạo ​

kotlin
SdkSoft.initialize(
  context = this,
  baseURL = "<BASE_URL>",
  networkConfig = NetworkConfig(),
  isDebug = false)  // không bao giờ phát hành bản release khi bật trace request

Tham số:

Tham sốKiểuBắt buộcMặc địnhMô tả
contextContextCó—Android context.
baseURLStringCó—Base URL cho các lệnh gọi API của SDK.
networkConfigNetworkConfigCó—Cấu hình network client.
isDebugBooleanKhôngfalseChế độ debug. Đặt true để trace log request.

NetworkConfig ​

kotlin
class NetworkConfig(
    val readTimeoutSeconds: Long = 60,
    val writeTimeoutSeconds: Long = 60,
    val connectTimeoutSeconds: Long = 60,
    val callTimeoutSeconds: Long = 0
)
Tham sốKiểuBắt buộcMặc địnhMô tả
readTimeoutSecondsLongKhông60Timeout đọc cho kết nối mới.
writeTimeoutSecondsLongKhông60Timeout ghi cho kết nối mới.
connectTimeoutSecondsLongKhông60Timeout kết nối cho kết nối mới.
callTimeoutSecondsLongKhông0Timeout cho toàn bộ lệnh gọi.

Các tham số này ánh xạ vào cấu hình OkHttpClient.

Header tùy chỉnh ​

kotlin
SdkSoft.setRequestHeaders(
    mapOf(
        Pair("key", "value")
    )
)
Tham sốKiểuBắt buộcMặc địnhMô tả
headersMap<String,String>Có—Header bổ sung được thêm vào mọi request API của SDK.

Kích hoạt ​

Gọi sau khi Đăng ký thành công trên backend của bạn.

kotlin
val activateBody = ActivateBody(
    partnerId = "{{partner_id}}",
    userId = "user_00000001",
    username = "nguyenvana",
    deviceId = "device_00000001",
    deviceOs = "Android",
    appVersion = "1.0.0",
    registrationId = "reg_00000001",
    activationKey = "fake_activation_key",
    token = "fake_device_token",
    pushToken = "fake_push_token",
)

SdkSoft.activate(activeBody = activateBody, overrideBaseUrl = overrideUrl, callback = {
    // Không ghi log response — nó chứa client secret key.
})

ActivateBody ​

Tham sốKiểuBắt buộcMặc địnhMô tả
partnerIdStringCó—ID partner.
deviceIdStringCó—UUID của thiết bị.
userIdStringCó—ID người dùng.
usernameStringKhông—Tên người dùng.
pushTokenStringCó—Token Firebase dùng để push khóa challenge từ server đến client.
tokenStringCó—Token đăng ký từ Đăng ký.
registrationIdStringCó—Registration id từ Đăng ký.
activationKeyStringCó—Activation key từ Đăng ký. Chỉ dùng một lần — gọi lại Đăng ký để lấy key mới.
deviceOsStringCó—Hệ điều hành thiết bị dùng để theo dõi, ví dụ Android.
appVersionStringCó—Phiên bản ứng dụng hiện tại.

Tham số lệnh gọi ​

Tham sốKiểuBắt buộcMặc địnhMô tả
activateBodyActivateBodyCó—Payload kích hoạt.
overrideBaseUrlStringKhông—Base URL ghi đè cho lệnh gọi này.
callbackUnitCó—Nhận một ActivateResponse.

Response ​

json
{
    "success": true,
    "code": 1,
    "message": "success",
    "data": {
        "key": "fake_client_secret_key",
        "period": "15",
        "algorithm": "HmacSHA512",
        "length": "6",
        "type": "totp",
        "issuer": "SOTP",
        "id": "123456"
    }
}
TrườngKiểuMô tả
keyStringKhóa bí mật dùng để tạo OTP.
periodStringSố giây một OTP còn hiệu lực.
lengthStringSố chữ số của một OTP.
issuerStringBên phát hành đã tạo OTP.
typeStringLoại soft OTP.
idStringID kích hoạt, còn gọi là số serial.

SDK trả kết quả này dưới dạng ActivateResponse, gồm key, period, algorithm, length, type, issuer, code, message, id và unhandledException.

INFO

period và length được trả về dưới dạng string ở đây, trong khi Đồng bộ thời gian trả về cùng hai trường đó dưới dạng integer. Hãy parse một cách thận trọng.

MãMô tả
3Parameter invalid
103Thông tin Partner không chính xác — Partner details are incorrect.
123Yêu cầu vượt giới hạn. Vui lòng thử lại sau ít phút — Request limit exceeded.
124OTP không hợp lệ — Invalid OTP.
125OTP hết hạn sử dụng — OTP expired.
129Token không hợp lệ — Invalid token.
-2Secret token decryption failed.

PIN và lưu trữ ​

kotlin
SdkSoft.storedSecureSmartOTP(pin = "1234")   // Boolean
SdkSoft.isValidPin(pin = "1234")             // Boolean
Tham sốKiểuBắt buộcMặc địnhMô tả
pinStringCó—PIN của SmartOTP, 4 chữ số.

storedSecureSmartOTP trả về true khi khóa bí mật được lưu thành công. Gọi hàm này một lần sau khi kích hoạt.

Đổi PIN ​

kotlin
val result = SdkSoft.changePin(oldPin = oldPin, newPin = newPin)

when (result) {
    ChangePinResult.UNKNOWN_FAILURE -> {}
    ChangePinResult.INVALID_OLD_PIN -> {}
    ChangePinResult.SUCCESS -> {}
}
TrườngKiểuMô tả
SUCCESSChangePinResultPIN đã được đổi.
INVALID_OLD_PINChangePinResultoldPin không khớp với PIN đã lưu.
UNKNOWN_FAILUREChangePinResultXảy ra lỗi nội bộ của SDK.

PIN mới không được trùng với hai PIN trước đó.

INFO

Android trả về ba giá trị ChangePinResult; iOS trả về năm giá trị, tách riêng sameOldAndNewPin và samePreviousPins. Trên Android, cả hai trường hợp đó đều gộp chung vào UNKNOWN_FAILURE, nên bạn không thể báo chính xác cho người dùng lý do PIN mới bị từ chối.

Tạo OTP ​

kotlin
val otp = SdkSoft.generateSmartOTP()                            // cơ bản
val otp = SdkSoft.generateAdvancedSotp(challengeKey = "fake_challenge_key")  // nâng cao
Tham sốKiểuBắt buộcMặc địnhMô tả
challengeKeyStringCó—Khóa challenge từ Tạo giao dịch. Chỉ dùng cho OTP nâng cao.

Cả hai đều trả về một chuỗi 6 chữ số, hoặc một chuỗi rỗng nếu thất bại.

Lấy trạng thái ​

kotlin
SdkSoft.getStatus(
  userId = "user_00000001",
  overrideBaseUrl = overrideUrl,
  callback = {
      Log.d("TAG", "${it?.code} ${it?.message} ${it?.status}")
  }
)
Tham sốKiểuBắt buộcMặc địnhMô tả
userIdString?Không—Người dùng cần kiểm tra. Khi là null, trả về trạng thái của người dùng đang được kích hoạt hiện tại.
overrideBaseUrlStringKhông—Base URL ghi đè.
callbackUnitCó—Nhận một StatusResponse với code, message, status.

Trả về một trong các giá trị NOT_REGISTERED, NOT_CURRENT_USER, NON_ACTIVATED, ACTIVATED, TEMPORARY_BLOCKED. Ý nghĩa thay đổi tùy vào việc bạn có truyền userId hay không — xem Tổng quan Mobile SDK § Các giá trị trạng thái.

Đồng bộ thời gian ​

kotlin
val syncTimeBody = SyncTimeBody(appId = "app_00000001")

SdkSoft.syncTime(
    syncTimeBody = syncTimeBody,
    useOtp = false,
    overrideBaseUrl = overrideUrl,
    callback = { }
)
Tham sốKiểuBắt buộcMặc địnhMô tả
syncTimeBodySyncTimeBodyCó—Mang theo appId, dùng để theo dõi.
useOtpBooleanCó—Gửi OTP của chu kỳ hiện tại và chu kỳ trước để mở khóa tài khoản. SDK dùng PIN đã lưu để tạo chúng.
overrideBaseUrlStringKhông—Base URL ghi đè.
callbackUnitCó—Nhận một SyncTimeResponse.

useOtp = true là cách một tài khoản TEMPORARY_BLOCKED được mở khóa — cặp OTP liên tiếp chứng minh thiết bị vẫn giữ đúng khóa bí mật.

MãMô tả
103Thông tin Partner không chính xác — Partner details are incorrect.
129Token không hợp lệ — Invalid token.
190108Tài khoản chưa hoạt động — Account not activated.
190302OTP không chính xác — Incorrect OTP.
-1Thông tin không hợp lệ — Invalid information.

Hủy kích hoạt ​

kotlin
SdkSoft.retire(
    overrideBaseUrl = overrideUrl,
    callback = {
        Log.d("TAG", "${it?.code} ${it?.message}")
    }
)

Hủy kích hoạt SmartOTP đang hoạt động hiện tại. Xem Hủy kích hoạt để biết thao tác này làm gì ở phía server.

Giao dịch mới nhất ​

kotlin
SdkSoft.getLatestTransaction(
  overrideBaseUrl = overrideUrl,
  callback = { }
)

Trả về một TransactionResponse mang theo challengeKey cùng các trường giao dịch — appId, transactionId, transactionDesc, transactionAmount, receiverAccount, senderAccount, currency, type, transactionDate, createdAt, transactionMetadata.

Tương đương với Lấy giao dịch mới nhất; áp dụng cùng lưu ý về việc nó trả về giao dịch mới nhất bất kể đó là giao dịch nào.

Polling trạng thái ​

kotlin
SdkSoft.startStatusPolling(
    interval = 30,
    appId = "app_00000001"
)

SdkSoft.cancelStatusPolling()
Tham sốKiểuBắt buộcMặc địnhMô tả
intervalIntKhông30Số giây giữa các lần kiểm tra trạng thái.
appIdStringKhông—App ID dùng trong lệnh gọi đồng bộ thời gian.

Job này kiểm tra trạng thái SmartOTP ở mỗi tick và chạy đồng bộ thời gian bất cứ khi nào trạng thái là ACTIVATED. Luôn đi kèm với cancelStatusPolling khi teardown.

Accessor ​

TrườngKiểuMô tả
getRegistrationId()StringRegistration id được lưu khi kích hoạt.
getSerialId()StringSerial ID đã đăng ký. Rỗng nếu chưa đăng ký hoặc có lỗi.
getCurrentUserId()String?User ID đã đăng ký. Null nếu chưa đăng ký hoặc có lỗi.
getCurrentUsername()StringUsername đã đăng ký. Rỗng nếu chưa đăng ký.
isSmartOtpRegistered()BooleanThiết bị này đã đăng ký SmartOTP hay chưa.
getTime()LongTimestamp của server.
getPeriod()IntCấu hình chu kỳ hiện tại tính bằng giây.
getRemainingValidityTime()IntSố giây còn lại của OTP hiện tại.

INFO

ActivateResponse.length có kiểu String?.

Bước tiếp theo ​

Developers