Tích hợp Web SDK
Thiết lập, khởi tạo và scan cho eKYC Web SDK. Thực thi bundle.js sẽ tạo object toàn cục window.ekyc.
Điều kiện tiên quyết
| Thông tin | Mô tả |
|---|---|
| Thư mục assets | Một nơi để serve thư mục assets /ekyc. |
| HTTPS | Bắt buộc để truy cập camera. |
| Quyền WebView | Trên WebView của iOS, bật chế độ phát media inline — allowsInlineMediaPlayback trong cả Flutter và React Native. |
jsQR | Bắt buộc cho chức năng mã QR. Tải nó trước bundle của SDK. |
Thiết lập HTML
Phần tử container với id cake-ekyc-sdk-container là bắt buộc và phải tồn tại trước khi khởi tạo.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>eKYC Integration</title>
<style>
#cake-ekyc-sdk-container {
width: 100%;
height: 100vh;
position: relative;
}
</style>
</head>
<body>
<!-- Bắt buộc: phần tử container của SDK với ID cụ thể -->
<div class="overlay" id="cake-ekyc-sdk-container"></div>
<!-- Bắt buộc: bundle eKYC SDK -->
<script src="/ekyc/bundle.js"></script>
<script>
// Code khởi tạo SDK đặt tại đây
</script>
</body>
</html>Khởi tạo
type SDKConfigParams = {
resourcePath?: string // Tùy chọn: đường dẫn đến tài nguyên SDK
baseUrl: string // Bắt buộc: Base URL cho các request API
token: string // Bắt buộc: Authentication token
headers?: Record<string, string> // Tùy chọn: Header HTTP bổ sung
}Tham số:
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
baseUrl | string | Có | — | Base URL cho các request API. |
token | string | Có | — | Authentication token. |
resourcePath | string | Không | — | Đường dẫn đến tài nguyên SDK. |
headers | Record<string, string> | Không | — | Header HTTP bổ sung. |
const sdk = await window.ekyc.initialize('cake-ekyc-sdk-container', {
baseUrl: '<BASE_URL>',
token: '<SDK_TOKEN>',
resourcePath: '/path/to/resources',
headers: {
'Custom-Header': 'value'
}
})Kèm xử lý lỗi
async function initializeSDK() {
try {
const container = document.getElementById('cake-ekyc-sdk-container');
if (!container) {
throw new Error('SDK container element not found');
}
if (!window.ekyc) {
throw new Error('eKYC SDK not loaded. Ensure bundle.js is included.');
}
const sdk = await window.ekyc.initialize('cake-ekyc-sdk-container', {
baseUrl: '<BASE_URL>',
token: await fetch('/your-backend/ekyc-token').then((r) => r.text()), // lấy lúc chạy, không đóng gói vào bundle
resourcePath: '/ekyc/resources',
headers: {
'X-Client-Version': '1.0.0',
'X-Platform': 'web',
'X-User-Agent': navigator.userAgent
}
});
return sdk;
} catch (error) {
console.error('SDK initialization failed:', error);
throw error;
}
}WARNING
Lấy token từ backend của bạn tại thời điểm chạy — không bao giờ hardcode nó trong trang hay commit vào source. Token này ủy quyền cho các lệnh gọi trên tenant của bạn.
Scan
scanStart(
types: ('face' | 'front' | 'back' | 'qrcode')[],
opts?: ScanOptions
): Promise<{
nid?: { front?: NIDScanResult, back?: NIDScanResult }
face?: FaceScanResult
qrcode?: QRCodeScanResult
}>Tham số:
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
types | string[] | Có | — | Những lượt scan cần chạy: face, front, back, qrcode. Thứ tự được tôn trọng. |
opts | ScanOptions | Không | — | Tùy chọn, chủ yếu cho xác thực khuôn mặt. |
ScanOptions
| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
frontImageId | string | Không | — | Image ID từ lượt scan mặt trước, dùng khi scan mặt sau. |
faceauthClientId | string | Không | — | Client ID cho xác thực khuôn mặt. |
faceauthRefId | string | Không | — | Reference ID cho xác thực khuôn mặt. |
isNTB | boolean | Không | — | Cờ khách hàng New-to-Bank. |
currentZoom | number | Không | — | Mức zoom hiện tại. |
timeoutDuration | number | Không | — | Thời gian timeout tính bằng mili-giây. |
// Scan mặt trước và mặt sau của thẻ NID
const result1 = await window.ekyc.scanStart(['front', 'back'])
// Scan khuôn mặt cho khách hàng NTB
const result2 = await window.ekyc.scanStart(['face'], {
isNTB: true,
faceauthClientId: 'client-123',
faceauthRefId: 'ref-456'
})
// Scan mã QR
const result3 = await window.ekyc.scanStart(['qrcode'])
// Scan kết hợp
const result4 = await window.ekyc.scanStart(['front', 'back', 'face', 'qrcode'], {
isNTB: false,
faceauthClientId: 'client-123',
faceauthRefId: 'ref-456'
})Chỉ những loại scan được yêu cầu mới xuất hiện trong response; mọi thứ khác là undefined.
Trạng thái scan
interface Status {
frontCompleted: boolean
backCompleted: boolean
faceCompleted: boolean
qrcodeCompleted: boolean
timestamp?: string
frontData?: any
backData?: any
faceData?: any
qrcodeData?: any
}const status = window.ekyc.getScanStatus()
console.log('Front scan completed:', status.frontCompleted)Cấu trúc response
NIDScanResult
| Trường | Kiểu | Mô tả |
|---|---|---|
frontSideImage | object | Ảnh mặt trước: id, label, bitmap, response. |
backSideImage | object | Ảnh mặt sau, cùng cấu trúc. |
sanityResult | object | Verdict sanity của thẻ, điểm số và bounding box thẻ được phát hiện. |
cardInfo | object | Trích xuất OCR, MRZ và QR cùng điểm độ tin cậy. |
sanityResult.data.card_sanity mang theo verdict, score và info. cardInfo.data.card_information là một mảng CardInformation.
CardInformation
| Trường | Kiểu | Mô tả |
|---|---|---|
field | string | Tên trường. |
value | string | Giá trị đã trích xuất. |
confidence_score | number | Độ tin cậy tổng thể. |
confidence_verdict | string | Kết luận dạng văn bản. |
digit_confidence_scores | number[] | Độ tin cậy theo từng ký tự. |
FaceScanResult
| Trường | Kiểu | Mô tả |
|---|---|---|
faces | FaceData[] | Các khuôn mặt đã chụp, mỗi khuôn mặt có image và gesture (left, right, portrait). |
sanityResult | SanityResult[] | Verdict sanity của ảnh chân dung và điểm số cho từng ảnh. |
livenessResult | LivenessResult | is_live, score, kết quả theo từng ảnh và main_image_id. |
QRCodeScanResult
| Trường | Kiểu | Mô tả |
|---|---|---|
raw | string | Dữ liệu QR thô. |
image | object | Ảnh đã xử lý: id, label, bitmap, response. |
Chuyển đổi bitmap
bitmap là một object ImageData đi kèm hai hàm hỗ trợ:
const blob = await bitmap.toBlob('image/jpeg')
const base64 = bitmap.toBase64('image/jpeg')Xử lý lỗi
Response scan giữ nguyên cấu trúc khi thất bại và đặt chi tiết trong mảng error. Response cũng có thể mang theo sdkError:
sdkError?: { code: string; message: string } | {}
// {} -> không có lỗi phía SDK
// {code,message} -> SDK phát hiện một lỗi bạn cần xử lýsdkError xuất hiện trên ImageResponse, SanityResult và LivenessResult của khuôn mặt, sanityResult và cardInfo của NID, và image.response của QR.
WARNING
Một response trông có vẻ thành công vẫn có thể chứa cảnh báo trong mảng error, và một sdkError có giá trị nghĩa là chính SDK đã từ chối kết quả. Hãy kiểm tra cả hai — đừng coi một promise được resolve là đã đạt.
Mã lỗi của SDK
| Trường | Kiểu | Mô tả |
|---|---|---|
60000 | NID_SANITY_FAILED | Kiểm tra sanity của NID thất bại. |
60001 | NID_TAMPERING_FAILED | Phát hiện giả mạo của NID thất bại. |
60002 | FACE_SANITY_FAILED | Kiểm tra sanity khuôn mặt thất bại. |
60003 | FACE_LIVENESS_FAILED | Kiểm tra liveness khuôn mặt thất bại. |
Mã lỗi mã QR
| Trường | Kiểu | Mô tả |
|---|---|---|
DOP-675_001 | Scan timeout | "Hết thời gian quét mã. Vui lòng thử lại." |
DOP-675_002 | Scan error | "Không thể quét được mã QR, vui lòng thử lại!" |
Các mã lỗi động cũng đến từ API trong mảng error — xem Mã lỗi.
Các vấn đề thường gặp
| Thông tin | Mô tả |
|---|---|
| SDK không tải được | Kiểm tra đường dẫn script và đảm bảo nó tải trước khi sử dụng. |
| Truy cập camera | Đảm bảo dùng HTTPS và quyền camera đã được cấp. |
| Không tìm thấy container | Xác nhận phần tử container tồn tại trong DOM. |
| Vấn đề mạng | Kiểm tra kết nối internet và các endpoint API. |
if (typeof window.ekyc === 'undefined') {
console.error('eKYC SDK not loaded');
}
navigator.mediaDevices.getUserMedia({ video: true })
.then(stream => {
console.log('Camera access granted');
stream.getTracks().forEach(track => track.stop());
})
.catch(error => {
console.error('Camera access denied:', error);
});Thực hành tốt nhất
- Khởi tạo một lần và tái sử dụng instance.
- Dùng
getScanStatus()để theo dõi tiến trình. - Với thẻ NID, scan mặt trước trước, sau đó scan mặt sau bằng
frontImageId. - Bọc mọi lượt scan trong try/catch.
- Gọi
terminate()khi xong để giải phóng camera và dọn dẹp.
Bước tiếp theo
- Tài liệu tham chiếu Web SDK — object toàn cục và toàn bộ interface TypeScript
- Kiến trúc Web SDK — các layer, module và class chính