Hướng dẫn tích hợp eContract SDK vào Flutter
I.1. Yêu cầu hệ thống
| Thành phần | Phiên bản tối thiểu |
|---|---|
| Flutter | ≥ 1.17.0 |
| Dart SDK | ≥ 3.0.0 |
I.1.2. Các bước tích hợp
Bước 1: Giải nén file zip và lưu thư mục ec_sdk vào thư mục dự án.
Bước 2: Import SDK tại file pubspec.yaml và chạy lệnh flutter pub get:
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
econtract_sdk:
path: ../ec_sdk
Bước 3: Import SDK vào file .dart và sử dụng
import 'package:ec_sdk/ec_sdk.dart';
I.1.3. Các phương thức chính trong SDK
- Khởi tạo môi trường SDK
///
/// Tham số:
/// - `envType`: Loại môi trường (DEV, STAG, PROD).
/// - `sdkToken`: (Tùy chọn) Token của SDK.
/// - `locale`: (Tùy chọn) Ngôn ngữ của SDK.
///
/// Ví dụ:
///
/// Gọi đoạn mã này trong hàm `main()`, hàm Init hoặc hàm đổi ngôn ngữ của ứng dụng chủ thể.
/// ```dart
/// EContractInterface.initEnvironment(
/// envType: SdkEnvType.STAG,
/// sdkToken: "eyJhbGciOi"
/// locale: const Locale('en'),
/// );
- Điều hướng đến danh sách hợp đồng đến
/// Điều hướng đến màn hình danh sách hợp đồng đến.
///
/// Tham số:
/// - `context`: Bối cảnh của ứng dụng.
///
/// Ví dụ:
/// ```dart
/// EContractInterface.navigateToIncomingContractListScreen(context);
/// ```
- Điều hướng đến danh sách hợp đồng đi
/// Điều hướng đến màn hình danh sách hợp đồng đi.
///
/// Tham số:
/// - `context`: Bối cảnh của ứng dụng.
///
/// Ví dụ:
/// ```dart
/// EContractInterface.navigateToOutGoingContractListScreen(context);
/// ```
- Điều hướng đến màn hình thông tin chữ ký của file hợp đồng hoặc tài liệu, màn hình chi tiết hợp đồng hoặc màn hình xác thực
/// Tham số:
/// - `context`: Bối cảnh của ứng dụng.
/// - `contractId`: (Tùy chọn) ID của bộ hợp đồng. Nếu không có, sẽ điều hướng đến màn hình xác thực.
/// - `documentFileId`: (Tùy chọn) ID của file hợp đồng chính hoặc tài liệu đính kèm. Nếu không có, sẽ điều hướng đến màn hình chi tiết bộ hợp đồng.
/// - `isLoginNoAccount`: (Tùy chọn) Trạng thái đăng nhập không tài khoản.
///
/// Ví dụ:
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// contractId: '12345',
/// documentFileId: '67890',
/// isLoginNoAccount: 1,
/// );
/// ```
/// hoặc
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// contractId: '12345',
/// isLoginNoAccount: 1,
/// );
/// ```
/// hoặc
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// );
- Điều hướng đến màn hình thông tin bộ hợp đồng để xem, màn hình thông tin file hợp đồng hoặc tài liệu để xem hoặc màn hình xác thực
/// Tham số:
/// - `context`: Bối cảnh của ứng dụng.
/// - `contractId`: (Tùy chọn) ID của bộ hợp đồng. Nếu không có, sẽ điều hướng đến màn hình xác thực.
/// - `documentFileId`: (Tùy chọn) ID của file hợp đồng chính hoặc tài liệu đính kèm. Nếu không có, sẽ điều hướng đến màn hình chi tiết bộ hợp đồng.
/// - `isLoginNoAccount`: (Tùy chọn) Trạng thái đăng nhập không tài khoản.
///
/// Ví dụ:
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// contractId: '12345',
/// documentFileId: '67890',
/// isLoginNoAccount: 'true',
/// );
/// ```
/// hoặc
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// contractId: '12345',
/// isLoginNoAccount: 'true',
/// );
/// ```
/// hoặc
/// ```dart
/// EContractInterface.navigateToSignatureInfoOfFile(
/// context: context,
/// );
/// ```
- Điều hướng đến màn hình ký bộ hợp đồng, màn hình ký file hợp đồng hoặc tài liệu riêng lẻ, hoặc màn hình xác thực
/// Tham số:
/// - `context`: Bối cảnh của ứng dụng.
/// - `contractId`: ID của bộ hợp đồng, nếu không có sẽ điều hướng đến màn hình xác thực.
/// - `documentFileId`: (Tùy chọn) ID của file hợp đồng chính hoặc tài liệu đính kèm, nếu không có sẽ điều hướng đến màn hình thông tin bộ hợp đồng để ký.
/// - `isLoginNoAccount`: (Tùy chọn) Trạng thái đăng nhập không tài khoản.
///
/// Ví dụ:
/// ```dart
/// EContractInterface.navigateToSignContract(
/// context: context,
/// contractId: '12345',
/// documentFileId: '67890',
/// isLoginNoAccount: 'true',
/// );
/// ```
/// hoặc
/// ```dart
/// EContractInterface.navigateToSignContract(
/// context: context,
/// contractId: '12345',
/// isLoginNoAccount: 'true',
/// );
/// ```
Lưu ý
Một số lưu ý đối với luồng kýe KYC:
- Cần cấu hình thêm ở native giao tiếp qua Channel để tương tác được giữa eKYC và eContract Mẫu code tương tác native code giữa eKYC và eContract tham khảo mở mục II.2 (bỏ qua nếu không ký eKYC trên SDK)
II.2. Cấu hình Method Channel để tương tác eKYC ↔ eContract
a. Android (MainActivity.kt)
class MainActivity: FlutterActivity() {
private val CHANNELEKYC = "vn.vnptit.econtract/eKYC"
private var resultChannel: MethodChannel.Result? = null
private var typeEkyc: String? = "0"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNELEKYC)
.setMethodCallHandler { call, result ->
resultChannel = result
if (call.method == "eKYC") {
typeEkyc = call.argument<String>("type")
val language = call.argument<String>("language") ?: "vi"
doDinhDanhEkyc(typeEkyc, language)
}
}
}
private fun doDinhDanhEkyc(type: String?, language: String) {
AICamera.navigateToCameraAI(this, type, language)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode != RESULT_OK || data == null) return
if (requestCode == Constants.RequestCode.SELECT_EKYC_AI) {
val dataEkyc = JSONObject()
// ... xử lý lấy dữ liệu từ Intent (giữ nguyên logic như mẫu gốc)
// Cuối cùng:
resultChannel?.success(dataEkyc.toString())
}
}
}
b. iOS (AppDelegate.swift)
import UIKit
import Flutter
import ICSdkEKYC
@available(iOS 13.0, *)
@objc class AppDelegate: FlutterAppDelegate {
private let CHANNELEKYC = "vn.vnptit.econtract/eKYC"
var ekycResult: FlutterResult?
var typeEkyc: String = "0"
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: CHANNELEKYC, binaryMessenger: controller.binaryMessenger)
channel.setMethodCallHandler { [weak self] (call, result) in
self?.ekycResult = result
if call.method == "eKYC" {
if let args = call.arguments as? [String: String] {
self?.typeEkyc = args["type"] ?? "0"
let lang = args["language"] ?? "vi"
self?.openSDKeKYC(controller: controller, typeCode: self?.typeEkyc ?? "0", lang: lang)
}
}
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func openSDKeKYC(controller: UIViewController, typeCode: String, lang: String) {
let objCamera = ICEkycCameraRouter.createModule() as! ICEkycCameraViewController
objCamera.cameraDelegate = self
objCamera.languageSdk = lang
// ... cấu hình các tham số khác như mẫu gốc
controller.present(objCamera, animated: true)
}
}
@available(iOS 13.0, *)
extension AppDelegate: ICEkycCameraDelegate {
func icEkycGetResult() {
DispatchQueue.main.async {
self.ekycResult?(self.getInformationCard())
}
}
// Hàm getInformationCard() trả về JSON string như mẫu gốc
}