Nhảy tới nội dung

Tích hợp Android

Yêu cầu
  • Yêu cầu Android SDK >= 6.0 (API level 23).

Bước 1: Tải SDK và cấu hình Project

Lưu ý

Ứng dụng viết bằng Flutter hoặc tích hợp Flutter module không copy thư mục repo

  • Thêm thông tin cấu hình vào file settings.gradle như dưới:
pluginManagement {  
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}

// Bỏ qua nếu ứng dụng viết bằng Flutter hoặc tích hợp Flutter module
String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"

dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
jcenter()
maven { url "https://jitpack.io" }

// Bỏ qua nếu ứng dụng viết bằng Flutter hoặc tích hợp Flutter module
maven {
//Đường dẫn thư mục chứa **repo** ở bước 1
url 'app/libs/repo'
}
// Bỏ qua nếu ứng dụng viết bằng Flutter hoặc tích hợp Flutter module
maven {
url "$storageUrl/download.flutter.io"
}

}
}
  • Thêm các thông tin cấu hình vào app/build.gradle
//...
aaptOptions {
noCompress "bic"
}

dependencies {
//...
// Bỏ qua nếu ứng dụng viết bằng Flutter hoặc tích hợp Flutter module
implementation 'com.vnpt.smartca.module.vnpt_smartca_module:flutter_release:1.0'

// Đường dẫn tới các file aar (xem bước 1)
implementation files('libs/vnpt_smartca_sdk_lib-release-v1.0.aar')
implementation files('libs/ekyc_sdk-release-v3.2.7.aar')
implementation files('libs/eContract-v3.6.12.aar')
implementation 'com.auth0.android:jwtdecode:2.0.0'

implementation 'com.github.gcacace:signature-pad:1.3.1'
implementation "androidx.multidex:multidex:2.0.1"
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

implementation 'androidx.test.espresso:espresso-idling-resource:3.5.1'
implementation 'com.github.mhiew:android-pdf-viewer:3.2.0-beta.3'

implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.6.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'com.karumi:dexter:6.0.0'

implementation 'com.android.support:exifinterface:28.0.0'
implementation 'com.google.code.gson:gson:2.10'

implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.12'
}

//..
  • Thêm FlutterActivity trong file AndroidManifest.xml như sau:
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
//......
<application
//......

// Bỏ qua nếu app tích hợp viết bằng Flutter
<activity android:name="io.flutter.embedding.android.FlutterFragmentActivity"
android:theme="@style/Theme.Smartca_android_example"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"/>

</application>
  • Bổ sung thuộc tính dưới đây vào file gradle.properties
    android.enableJetifier=true
  • Bổ sung thuộc tính dưới đây vào file proguard-rules.pro
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn android.support.**
-dontwarn com.squareup.**
-dontwarn com.google.android.**
-verbose

# -keepattributes *Annotation*
-dontwarn lombok.**
-dontwarn io.realm.**

-dontwarn java.awt.**

# okhttp3
-dontwarn okhttp3.**
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase

# Application classes that will be serialized/deserialized over Gson
-keep class vnpt.it3.econtract.data.model.** { *; }
-keep class vnpt.it3.econtract.data.** { *; }

# Java 8
-dontwarn java.lang.invoke.*
-dontwarn **$$Lambda$*

# Retrofit 2
-dontnote retrofit2.Platform
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
-dontwarn retrofit2.Platform$Java8
-keepattributes Signature
-keepattributes Exceptions
-keepclassmembernames,allowobfuscation interface * {
@retrofit2.http.* <methods>;
}
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
}
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement


# pdf lib
-keep class com.shockwave.**

#To remove debug logs:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** w(...);
public static *** i(...);
}

-keep public enum vnpt.it3.econtract.data.**{
*;
}

-keepclassmembers class **.R$* {
public static <fields>;
}
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keep class com.vnptit.innovation.sample.model.** { *; }
-keep class ai.icenter.face3d.native_lib.Face3DConfig { *; }
-keep class ai.icenter.face3d.native_lib.CardConfig { *; }

Bước 2: Khởi tạo SDK tại nơi muốn bắt đầu kết nối

  • Thêm code kết nối với SDK tại Activity muốn sử dụng các chức năng:

    ````kotlin
    // ...
    import com.google.gson.Gson
    import com.vnpt.smartca.*

    class MainActivity: AppCompatActivity() {
    //...
    var VNPTSmartCA = VNPTSmartCASDK()

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    //...
    var customParams = CustomParams(
    customerId = "", // Số CCCD, giấy tờ của KH đăng nhập SDK, để trống KH tự nhập
    borderRadiusBtn = 999.0, // Border radius của button
    colorSecondBtn = "", // Màu background nút phụ ví dụ: #FFFFFF
    colorPrimaryBtn = "", // Màu background nút chính ví dụ: #4788FF
    featuresLink = "", // Đường dẫn tới trang hướng dẫn sử dụng các tính năng sdk
    customerPhone = "", // Số ĐT mặc định của KH
    packageDefault = "", // Gói mặc định hiển thị khi mua Chứng thư số, ví dụ: PS0
    password = "", // Mật khẩu mặc định khi tạo tài khoản
    logoCustom = "", // Logo của đối tác theo mã hoá Base64 dạng "iVBORw0KGgoAAAANSUhEUgAAANgAAA......"
    backgroundLogin = "" // Background của đối tác theo mã hoá Base64 dạng "iVBORw0KGgoAAAANSUhEUgAAANgAAA......"
    );

    var config = ConfigSDK(
    clientId = "", // clientId tương ứng với môi trường được cấp qua email
    clientSecret = "", // clientSecret tương ứng với môi trường được cấp qua email
    env = SmartCAEnvironment.DEMO_ENV, // Môi trường kết nối DEMO/PROD
    customParams = customParams,
    lang = SmartCALanguage.VI, // Ngôn ngữ vi/en
    isFlutter = true, // true nếu ứng dụng phát triển bằng Flutter, hoặc tích hợp Flutter module
    )

    VNPTSmartCA.initSDK(this, config)
    //...

    }
    ````

Bước 3: Sử dụng các hàm chính

  • Quản lý tài khoản: Đăng ký tài khoản, Quản lý chứng thư, Lịch sử giao dịch, Tài khoản,...
  • Lấy thông tin xác thực người dùng (accessToken & credentiald & serial)
  • Xác nhận / Hủy giao dịch ký số
  • Tạo tài khoản
  • Đăng xuất
  • Hủy kết nối SDK

📦 Hàm quản lý tài khoản

  • Đối tác tạo 1 chức năng riêng trên ứng dụng của mình để người dùng sử dụng các chức năng của SDK như: Đăng ký tài khoản, Quản lý chứng thư, Lịch sử giao dịch, Tài khoản,...
```` kotlin
private fun getMainInfo() {
try {
VNPTSmartCA.getMainInfo { result ->
when (result.status) {
SmartCAResultCode.SUCCESS_CODE -> {
// Xử lý khi thành công
}
else -> {
// Xử lý khi có lỗi
// result.statusDesc
// result.data
}
}
}
} catch (ex: java.lang.Exception) {
throw ex;
}
}
````

📦 Lấy thông tin người dùng, chứng thư số

  • Lấy accessToken, credentialId hoặc serial của chứng thư để tạo giao dịch phía backend. SDK sẽ tự kiểm tra tài khoản như: đã kích hoạt hay chưa, chứng thư hợp lệ hay không, tự động làm mới token khi hết hạn,...
  • Sau khi lấy được thông tin đối tác tạo giao dịch từ phía backend của mình với hệ thống backend VNPT SmartCA để lấy tranId sau đó gọi hàm getWaitingTransaction.
  • Tài liệu tích hợp phía backend được cung cấp khi đăng ký tích hợp.
Lưu ý

tranId là mã giao dịch do hệ thống VNPT SmartCA sinh ra và trả về cho đối tác. Ví dụ trandId: "48b7d184-bbf4-4fa2-a661-3a223dcb716a"

```` kotlin

data class CallbackResult(
val credentialId: String,
val accessToken: String,
val serial: String,
)

private fun getAuthentication() {
try {
VNPTSmartCA.getAuthentication { result ->
when (result.status) {
SmartCAResultCode.SUCCESS_CODE -> {
val obj: CallbackResult = Gson().fromJson(
result.data.toString(), CallbackResult::class.java
)
// SDK trả lại token, credential, serial của khách hàng
// Đối tác tạo transaction cho khách hàng để lấy transId, sau đó gọi getWaitingTransaction
val token = obj.accessToken
val credentialId = obj.credentialId
val serial = obj.serial
//...
}
else -> {
// Xử lý lỗi
// result.statusDesc
// result.data
}
}
}
} catch (ex: Exception) {
throw ex;
}
}
````

📦 Xác nhận / Huỷ giao dịch ký số

  • Sau khi lấy lấy được tranId từ phía backend đối tác gọi hàm này để người dùng Xác nhận / Huỷ giao dịch ký số.
  • Luôn phải gọi hàm getAuthentication trước
```` kotlin
// tạo giao dịch từ backend, lấy tranId từ hệ thống VNPT SmartCA trả về
private fun getWaitingTransaction(transId: String) {
try {
if (transId.isNullOrEmpty()) {
editTextTrans.setError("Vui lòng điền Id giao dịch");
return
}

VNPTSmartCA.getWaitingTransaction(transId) { result ->
when (result.status) {
SmartCAResultCode.SUCCESS_CODE -> {
// Xử lý khi thành công
}
else -> {
// Xử lý khi thất bại
// result.statusDesc
// result.data
}
}

}
} catch (ex: Exception) {
throw ex;
}
}
````

📦 Đăng xuất

  • Đăng xuất tài khoản đang đăng nhập vào SDK.
```` kotlin
private fun signOut() {
try {
VNPTSmartCA.signOut { result ->
when (result.status) {
SmartCAResultCode.SUCCESS_CODE -> {
// Xử lý khi thành công
}
else -> {
// Xử lý khi lỗi
// result.statusDesc
// result.data
}
}
}
} catch (ex: java.lang.Exception) {
throw ex;
}
}
````

📦 Tạo tài khoản/Kích hoạt tài khoản

  • Mở trực tiếp màn hình tới màn hình tạo tài khoản.

    ```` kotlin
    private fun createAccount() {
    try {
    VNPTSmartCA.createAccount { result ->
    when (result.status) {
    SmartCAResultCode.SUCCESS_CODE -> {
    // Xử lý khi thành công
    }
    else -> {
    // Xử lý khi thất bại
    // result.statusDesc
    // result.data
    }
    }
    }
    } catch (ex: java.lang.Exception) {
    throw ex;
    }
    }
    ````

📦 Hàm hủy kết nối với SDK

```` kotlin
override fun onDestroy() {
VNPTSmartCA.destroySDK()
super.onDestroy()
}
````