/** * React Native port of EkycNativeAndroid EKYCErrorResult.kt * Định nghĩa mã lỗi và message (vi/en) thống nhất với SDK Android. */ export type EKYCErrorResultLanguage = 'vi' | 'en'; export interface EKYCErrorResultLike { code: string; viMessage: string; enMessage: string; } function def(code: string, viMessage: string, enMessage: string): EKYCErrorResultLike { return { code, viMessage, enMessage }; } function defSame(code: string, message: string): EKYCErrorResultLike { return { code, viMessage: message, enMessage: message }; } // ======================================== // SDK GENERAL ERRORS (-1 -> 000) // ======================================== export const SDK_START_FLOW_ERROR = def('-1', 'Flow không được trùng hoặc rỗng!', 'Flow must not be duplicated or empty!'); export const SDK_START_ERROR = def('0', 'Lỗi mở SDK. Kiểm tra lại key!', 'Failed to start SDK. Please check your key!'); export const ERROR_UNKNOWN = def('000', 'Lỗi không xác định', 'Unknown error'); export const SDK_MISS_KEY = def('0000', 'Lỗi thiếu key', 'Missing SDK key'); // ======================================== // OCR ERRORS (001 -> 100) // ======================================== export const OCR_UNRECOGNIZED_ID_CARD = def('001', 'Không nhận diện được CCCD/CMND', 'Unable to recognize ID card'); export const OCR_WRONG_ID_CARD_SIDE = def('002', 'Chụp sai mặt CMND/CCCD', 'Captured wrong side of ID card'); export const OCR_CANNOT_GET_ID_NUMBER = def('011', 'Không lấy được số định danh', 'Unable to extract ID number'); export const OCR_CANNOT_GET_NAME = def('012', 'Không lấy được Họ tên', 'Unable to extract full name'); export const OCR_CANNOT_GET_BIRTH_YEAR = def('014', 'Không lấy được năm sinh', 'Unable to extract year of birth'); export const OCR_CANNOT_GET_EXPIRY_DATE = def('015', 'Không lấy được ngày hết hạn', 'Unable to extract expiry date'); export const OCR_CANNOT_GET_ISSUE_DATE = def('016', 'Không lấy được ngày phát hành', 'Unable to extract issue date'); export const OCR_CANNOT_GET_RESIDENCE = def('017', 'Không lấy được nơi cư trú', 'Unable to extract place of residence'); export const OCR_CANNOT_GET_HOMETOWN = def('018', 'Không lấy được Quê quán/nơi sinh', 'Unable to extract hometown/place of birth'); export const OCR_CANNOT_GET_GENDER = def('019', 'Không lấy được giới tính', 'Unable to extract gender'); export const OCR_CANNOT_GET_ISSUE_PLACE = def('020', 'Không lấy được nơi phát hành', 'Unable to extract place of issue'); export const OCR_MISSING_ID_CARD_PART = def('043', 'Một phần của CCCD/CMND không có', 'Part of the ID card is missing'); export const OCR_NOT_ORIGINAL_ID_CARD = def('044', 'Vui lòng chỉ chụp CCCD/CMND gốc', 'Please capture only the original ID card'); export const OCR_ID_CARD_FROM_OTHER_DEVICE = def('045', 'CCCD/CMND chụp từ thiết bị khác', 'ID card photo taken from another device'); export const OCR_CANNOT_RECOGNIZE_PORTRAIT = def('046', 'Không nhận diện được ảnh chân dung trên CCCD/CMND', 'Unable to recognize the portrait on the ID card'); export const OCR_CUT_CORNER_ID_CARD = def('047', 'CCCD/CMND đã bị cắt góc', 'The ID card has a cut corner'); export const OCR_BLURRY_ID_CARD = def('048', 'CCCD/CMND bị mờ', 'The ID card is blurry'); export const OCR_GLARE_ID_CARD = def('049', 'CCCD/CMND bị chói sáng', 'The ID card has glare'); export const OCR_INVALID_ID_CARD = def('061', 'CCCD/CMND không hợp lệ', 'Invalid ID card'); export const OCR_INVALID_GENDER_CODE = def('063', 'Mã giới tính không hợp lệ', 'Invalid gender code'); export const OCR_FAKE_MRZ = def('071', 'MRZ giả mạo', 'Fake MRZ detected'); export const OCR_USE_NEW_ID_DOCUMENT_1 = def('076', 'Vui lòng sử dụng giấy tờ tùy thân mới', 'Please use a new ID document'); export const OCR_USE_NEW_ID_DOCUMENT_2 = def('077', 'Vui lòng sử dụng giấy tờ tùy thân mới', 'Please use a new ID document'); export const OCR_FAKE_CHARACTERS_DETECTED_CMND = def('081', 'Phát hiện kí tự giả mạo (CMND)', 'Fake characters detected (ID card)'); export const OCR_FAKE_PORTRAIT_DETECTED_CMND = def('082', 'Phát hiện hình chân dung giả mạo (CMND)', 'Fake portrait detected (ID card)'); export const OCR_FAKE_BIRTH_DATE_DETECTED_CMND = def('083', 'Phát hiện ngày sinh giả mạo (CMND)', 'Fake date of birth detected (ID card)'); export const OCR_MODIFIED_SYMBOL_DETECTED_CMND = def('084', 'Phát hiện biểu tượng sửa đổi (CMND)', 'Modified symbols detected (ID card)'); export const OCR_MODIFIED_BIRTH_DATE_DETECTED_CMND = def('085', 'Phát hiện ngày sinh bị sửa đổi (CMND)', 'Modified date of birth detected (ID card)'); export const OCR_UNKNOWN_ID_NUMBER_LENGTH = def('086', 'Độ dài chuỗi số định danh không xác định', 'Unknown ID number length'); export const OCR_FAKE_CHARACTERS_DETECTED_1 = def('088', 'Phát hiện kí tự giả mạo', 'Fake characters detected'); export const OCR_FAKE_CHARACTERS_DETECTED_2 = def('089', 'Phát hiện kí tự giả mạo', 'Fake characters detected'); export const OCR_FAKE_PORTRAIT_DETECTED = def('090', 'Phát hiện hình chân dung giả mạo', 'Fake portrait detected'); export const OCR_PHOTOCOPY_ID_CARD = def('091', 'CMND/CCCD ảnh photo', 'Photocopied ID card'); export const OCR_FONT_BACK_NOT_MATCH = def('092', 'CCCD không trùng khớp', 'ID card fonts or back side do not match'); export const OCR_ERROR = def('100', 'Lỗi OCR', 'OCR error'); // ======================================== // FACE & LIVENESS ERRORS (102 -> 132) // ======================================== export const FACE_HAT_ERROR = def('102', 'Phát hiện đang đội nón', 'Hat detected'); export const FACE_ERROR = def('109', 'Lỗi Face compare. Hình ảnh không khớp', 'Face comparison failed. Images do not match'); export const LIVENESS_ERROR = def('110', 'Lỗi Liveness', 'Liveness error'); export const LIVENESS_FAIL = def('111', 'Hình chụp không đúng', 'Captured image is invalid'); export const MULTIPLE_FACES_IN_SELFIE = def('112', 'Nhiều khuôn mặt trong ảnh selfie', 'Multiple faces detected in selfie'); export const EYES_CLOSED_IN_SELFIE = def('113', 'Mắt nhắm trong ảnh selfie', 'Eyes closed in selfie'); export const MASK_PRESENT_IN_SELFIE = def('114', 'Đeo mặt nạ trong ảnh selfie', 'Mask detected in selfie'); export const FACE_IS_BLURRED = def('115', 'Khuôn mặt bị mờ', 'Face is blurry'); export const FACE_OCCLUDED_IN_SELFIE = def('126', 'Khuôn mặt bị che khuất trong ảnh selfie', 'Face is occluded in selfie'); export const EYEWEAR_DETECTED_IN_SELFIE = def('127', 'Phát hiện đeo kính trong ảnh selfie', 'Eyewear detected in selfie'); export const READING_GLASSES_DETECTED_IN_SELFIE = def('129', 'Phát hiện kính đọc sách trong ảnh selfie', 'Reading glasses detected in selfie'); export const NUDITY_DETECTED_IN_SELFIE = def('131', 'Phát hiện ảnh khỏa thân trong selfie', 'Nudity detected in selfie'); export const HEAD_IS_TURNED_IN_SELFIE = def('132', 'Đầu nghiêng trong ảnh selfie', 'Head is turned in selfie'); // ======================================== // NFC & C06 ERRORS (200 -> 210) // ======================================== export const SCAN_NFC_ERROR = def('200', 'Đọc NFC không thành công. Vui lòng thử lại hoặc dùng thiết bị khác.', 'Failed to read NFC. Please try again or use another device.'); export const SCAN_NFC_CHECK = def('201', 'Lỗi check NFC', 'NFC check error'); export const SCAN_NFC_ENABLE = def('202', 'Vui lòng bật NFC để tiếp tục', 'Please enable NFC to continue'); export const C06_ERROR = def('203', 'Lỗi check C06', 'C06 verification error'); export const NFC_MUTUAL_AUTH_FAILED = def('204', 'Dữ liệu NFC không hợp lệ', 'Invalid NFC data'); export const NFC_CONNECTION_LOST = def('205', 'Mất kết nối NFC', 'NFC connection lost'); export const NFC_INVALID_MRZ_KEY = def('206', 'Khóa MRZ không hợp lệ', 'Invalid MRZ key'); export const NFC_IO_ERROR = def('207', 'Lỗi đọc dữ liệu NFC', 'Error reading NFC data'); export const NFC_UNKNOWN_ERROR = def('208', 'Lỗi NFC không xác định', 'Unknown NFC error'); export const NFC_USER_CANCEL = def('209', 'User hủy', 'User cancelled'); export const NFC_CHIP_AUTH_FAILED = def('210', 'ChipAuthenticationFailed', 'Chip authentication failed'); // ======================================== // SMS OTP ERRORS (300 -> 310) // ======================================== export const SMS_OTP_ERROR = def('300', 'Lỗi SMS OTP', 'SMS OTP error'); export const SMS_OTP_INVALID_PHONE = def('301', 'Số điện thoại không hợp lệ', 'Invalid phone number'); export const SMS_OTP_MAX_ATTEMPTS = def('302', 'Đã nhập sai OTP quá số lần cho phép', 'OTP entered incorrectly too many times'); export const SMS_OTP_NOT_FOUND = def('303', 'OTP không tồn tại hoặc đã hết hạn', 'OTP does not exist or has expired'); export const SMS_OTP_RATE_LIMIT = def('304', 'Vượt quá giới hạn request', 'Request rate limit exceeded'); // ======================================== // USER CANCEL (999) // ======================================== export const USER_CANCEL = def('999', 'Người dùng đã hủy', 'User cancelled'); // ======================================== // OTHER ERRORS (400+) // ======================================== export const QRCODE_ERROR = def('4xx', 'Lỗi quest QRCode', 'QRCode processing error'); export const FETCH_HISTORY_ERROR = def('500', 'Lỗi không lấy được detail', 'Failed to fetch details'); // ======================================== // EASYCA / ESIGN ERRORS // ======================================== export const ESIGN_SESSION_INVALID = def('1001', 'Chưa có session hợp lệ', 'No valid session'); export const ESIGN_DEVICE_ALREADY_INIT = def('4010', 'Thiết bị đã được init', 'Device has already been initialized'); export const ESIGN_INVALID_LICENSE = def('4011', 'License không hợp lệ', 'Invalid license'); export const ESIGN_INVALID_LICENSE_CONTENT = def('4012', 'Nội dung trong license không hợp lệ', 'Invalid license content'); export const ESIGN_DEVICE_NOT_INIT = def('4030', 'Thiết bị chưa được khởi tạo', 'Device has not been initialized'); export const ESIGN_APP_LIMITED = def('4031', 'Ứng dụng đang bị giới hạn từ phía EasyCA', 'Application is restricted by EasyCA'); export const ESIGN_INVALID_USER_ACCOUNT = def('4032', 'Tài khoản user không đúng', 'Invalid user account'); export const ESIGN_SESSION_INVALID_REGISTER = def('4050', 'Chưa có session hợp lệ (cần gọi openSessionId trước)', 'No valid session (openSessionId must be called first)'); export const ESIGN_INVALID_RECOVERY_OR_PIN = def('4051', 'Mã recovery hoặc PIN không đúng cấu trúc', 'Recovery code or PIN has invalid format'); export const ESIGN_SESSION_INVALID_LIST_CERT = def('4100', 'Chưa có session hợp lệ', 'No valid session'); export const ESIGN_AUTH_EXISTS = def('4120', 'Ủy quyền đã tồn tại', 'Authorization already exists'); export const ESIGN_INVALID_SIGN_COUNT_OR_TIME = def('4121', 'Số lần ký hoặc thời gian hết hạn không hợp lệ', 'Invalid signing count or expiration time'); export const ESIGN_INVALID_CERT_FOR_AUTH = def('4122', 'Chứng thư số không hợp lệ để ủy quyền', 'Certificate is not valid for authorization'); export const ESIGN_AUTH_REQUEST_EXISTS = def('4123', 'Đã tồn tại yêu cầu ủy quyền cho chứng thư', 'An authorization request already exists for this certificate'); export const ESIGN_ERROR_UNKNOWN = def('600', 'Lỗi eSign không xác định', 'Unknown eSign error'); export const ESIGN_MISSING_TOKEN = def('601', 'Thiếu finos_token. Vui lòng gọi fetchAccessToken trước.', 'finos_token is required. Please call fetchAccessToken first.'); export const ESIGN_MISSING_CCCD = def('602', 'Thiếu thông tin CCCD', 'CCCD is required'); export const ESIGN_MISSING_REQUEST_JSON = def('603', 'Request JSON không được để trống', 'Request JSON cannot be empty'); export const ESIGN_MISSING_CONFIRMATION_DOC = def('604', 'Confirmation Doc/PDF không được để trống', 'Confirmation Doc/PDF cannot be empty'); export const ESIGN_NO_SESSION_ID = def('605', 'Không tìm thấy sessionId trong phản hồi đăng ký', 'Cannot find sessionId in register response'); export const ESIGN_MISSING_ACCESS_TOKEN = def('606', 'Thiếu Access Token', 'Access Token is required'); export const ESIGN_MISSING_IDENTITY = def('607', 'Identity không được để trống', 'Identity cannot be empty'); export const ESIGN_MISSING_SERIAL = def('608', 'Thiếu serial chứng thư số', 'Certificate serial is required'); export const ESIGN_MISSING_REQUEST_ID = def('609', 'Thiếu Sign Request ID', 'Sign Request ID is required'); export const ESIGN_INVALID_CONTEXT = def('610', 'Context không hợp lệ hoặc thiếu', 'Invalid or missing context'); export const ESIGN_INVALID_LICENSE_CODE = def('611', 'Mã license không được để trống', 'License code cannot be empty'); export const ESIGN_INVALID_RECOVERY_CODE = def('612', 'Mã recovery không được để trống (8 chữ số)', 'Recovery code cannot be empty (8 digits required)'); export const ESIGN_INVALID_PIN_CODE = def('613', 'Mã PIN không được để trống (6 chữ số)', 'PIN code cannot be empty (6 digits required)'); // ======================================== // ESIGN VALIDATION ERRORS (614 -> 649) // ======================================== export const ESIGN_MISSING_NAME = def('614', 'Thiếu tên người dùng', 'User name is required'); export const ESIGN_MISSING_DEVICE_ID = def('615', 'Thiếu Device ID', 'Device ID is required'); export const ESIGN_INVALID_REQUEST_JSON = def('616', 'Request JSON không hợp lệ (không parse được)', 'Request JSON is invalid (cannot parse)'); export const ESIGN_MISSING_PIN_CODE = def('617', 'Thiếu mã PIN', 'PIN code is required'); export const ESIGN_MISSING_USER_PIN = def('618', 'Thiếu mã PIN người dùng', 'User PIN is required'); export const ESIGN_INVALID_PAGE_PARAMS = def('619', 'pageNumber và pageSize phải lớn hơn 0', 'pageNumber and pageSize must be greater than 0'); export const ESIGN_INVALID_QUANTITY = def('620', 'Số lượng (quantity) phải lớn hơn 0', 'Quantity must be greater than 0'); export const ESIGN_INVALID_TIME = def('621', 'Thời gian (time) phải lớn hơn 0', 'Time must be greater than 0'); export const ESIGN_INVALID_PIN_FORMAT = def('622', 'Mã PIN phải đúng 6 chữ số', 'PIN code must be exactly 6 digits'); export const ESIGN_INVALID_RECOVERY_FORMAT = def('623', 'Mã recovery phải đúng 8 chữ số', 'Recovery code must be exactly 8 digits'); export const ESIGN_MISSING_USER_INFO = def('624', 'Thiếu object userInfo trong request JSON', 'userInfo object is required in request JSON'); export const ESIGN_MISSING_FIELD_IDENTITY = def('625', 'Thiếu userInfo.identity trong request JSON', 'userInfo.identity is required in request JSON'); export const ESIGN_MISSING_FIELD_SOD = def('626', 'Thiếu userInfo.sod trong request JSON', 'userInfo.sod is required in request JSON'); export const ESIGN_MISSING_FIELD_REGISTER_DATE = def('627', 'Thiếu userInfo.registerDate trong request JSON', 'userInfo.registerDate is required in request JSON'); export const ESIGN_MISSING_FIELD_EXPIRED_DATE = def('628', 'Thiếu userInfo.expiredDate trong request JSON', 'userInfo.expiredDate is required in request JSON'); export const ESIGN_MISSING_SIGNING_CONTENTS = def('629', 'Thiếu signingRequestContents trong request JSON', 'signingRequestContents is required in request JSON'); export const ESIGN_MISSING_FIELD_DATA = def('630', 'Thiếu data (PDF base64) trong signingRequestContents', 'data (PDF base64) is required in signingRequestContents'); export const ESIGN_MISSING_TOKEN_INFO = def('631', 'Thiếu tokenInfo trong request JSON', 'tokenInfo object is required in request JSON'); export const ESIGN_MISSING_FIELD_USERNAME = def('632', 'Thiếu tokenInfo.username trong request JSON', 'tokenInfo.username is required in request JSON'); export const ESIGN_MISSING_FIELD_SERIAL_TOKEN = def('633', 'Thiếu tokenInfo.serial trong request JSON', 'tokenInfo.serial is required in request JSON'); export const ESIGN_MISSING_FIELD_SESSION_ID = def('634', 'Thiếu sessionId trong request JSON', 'sessionId is required in request JSON'); export const ESIGN_MISSING_FIELD_NAME = def('635', 'Thiếu userInfo.name trong request JSON', 'userInfo.name is required in request JSON'); export const ESIGN_MISSING_FIELD_ADDRESS = def('636', 'Thiếu userInfo.address trong request JSON', 'userInfo.address is required in request JSON'); export const ESIGN_MISSING_FIELD_SIGNATURE = def('637', 'Thiếu userInfo.signature trong request JSON', 'userInfo.signature is required in request JSON'); export const ESIGN_MISSING_EMAIL_OR_PHONE = def('638', 'Phải có ít nhất email hoặc phone trong request JSON', 'At least email or phone is required in request JSON'); export const ESIGN_MISSING_POLICY_AGREEMENT = def('639', 'Thiếu policyAgreement trong request JSON', 'policyAgreement object is required in request JSON'); export const ESIGN_MISSING_FIELD_POLICY_STATUS = def('640', 'Thiếu policyAgreement.policyStatus trong request JSON', 'policyAgreement.policyStatus is required in request JSON'); export const ESIGN_MISSING_FIELD_ACCEPT_TIME = def('641', 'Thiếu policyAgreement.acceptTime trong request JSON', 'policyAgreement.acceptTime is required in request JSON'); export const ESIGN_MISSING_FIELD_DEVICE = def('642', 'Thiếu policyAgreement.device trong request JSON', 'policyAgreement.device is required in request JSON'); export const ESIGN_MISSING_SIGN_POSITIONS = def('645', 'Thiếu signPositions trong signingRequestContents (API multiple positions)', 'signPositions array is required in signingRequestContents'); export const ESIGN_MISSING_SIGN_POSITION_LOCATION = def('646', 'Thiếu location trong signPositions', 'location object is required in each signPosition'); export const ESIGN_MISSING_FIELD_DOCUMENT_NAME = def('647', 'Thiếu documentName trong signingRequestContents', 'documentName is required in signingRequestContents'); export const ESIGN_INVALID_REGISTER_DATE_FORMAT = def('648', 'userInfo.registerDate phải đúng định dạng dd/MM/yyyy', 'userInfo.registerDate must be in dd/MM/yyyy format'); export const ESIGN_INVALID_EXPIRED_DATE_FORMAT = def('649', 'userInfo.expiredDate phải đúng định dạng dd/MM/yyyy', 'userInfo.expiredDate must be in dd/MM/yyyy format'); // ======================================== // Predefined list & code map (companion object) // ======================================== const PREDEFINED_ERRORS: EKYCErrorResultLike[] = [ SDK_START_FLOW_ERROR, SDK_START_ERROR, ERROR_UNKNOWN, SDK_MISS_KEY, OCR_UNRECOGNIZED_ID_CARD, OCR_WRONG_ID_CARD_SIDE, OCR_CANNOT_GET_ID_NUMBER, OCR_CANNOT_GET_NAME, OCR_CANNOT_GET_BIRTH_YEAR, OCR_CANNOT_GET_EXPIRY_DATE, OCR_CANNOT_GET_ISSUE_DATE, OCR_CANNOT_GET_RESIDENCE, OCR_CANNOT_GET_HOMETOWN, OCR_CANNOT_GET_GENDER, OCR_CANNOT_GET_ISSUE_PLACE, OCR_MISSING_ID_CARD_PART, OCR_NOT_ORIGINAL_ID_CARD, OCR_ID_CARD_FROM_OTHER_DEVICE, OCR_CANNOT_RECOGNIZE_PORTRAIT, OCR_CUT_CORNER_ID_CARD, OCR_BLURRY_ID_CARD, OCR_GLARE_ID_CARD, OCR_INVALID_ID_CARD, OCR_INVALID_GENDER_CODE, OCR_FAKE_MRZ, OCR_USE_NEW_ID_DOCUMENT_1, OCR_USE_NEW_ID_DOCUMENT_2, OCR_FAKE_CHARACTERS_DETECTED_CMND, OCR_FAKE_PORTRAIT_DETECTED_CMND, OCR_FAKE_BIRTH_DATE_DETECTED_CMND, OCR_MODIFIED_SYMBOL_DETECTED_CMND, OCR_MODIFIED_BIRTH_DATE_DETECTED_CMND, OCR_UNKNOWN_ID_NUMBER_LENGTH, OCR_FAKE_CHARACTERS_DETECTED_1, OCR_FAKE_CHARACTERS_DETECTED_2, OCR_FAKE_PORTRAIT_DETECTED, OCR_PHOTOCOPY_ID_CARD, OCR_FONT_BACK_NOT_MATCH, OCR_ERROR, FACE_HAT_ERROR, FACE_ERROR, LIVENESS_ERROR, LIVENESS_FAIL, MULTIPLE_FACES_IN_SELFIE, EYES_CLOSED_IN_SELFIE, MASK_PRESENT_IN_SELFIE, FACE_IS_BLURRED, FACE_OCCLUDED_IN_SELFIE, EYEWEAR_DETECTED_IN_SELFIE, READING_GLASSES_DETECTED_IN_SELFIE, NUDITY_DETECTED_IN_SELFIE, HEAD_IS_TURNED_IN_SELFIE, SCAN_NFC_ERROR, SCAN_NFC_CHECK, SCAN_NFC_ENABLE, C06_ERROR, NFC_MUTUAL_AUTH_FAILED, NFC_CONNECTION_LOST, NFC_INVALID_MRZ_KEY, NFC_IO_ERROR, NFC_UNKNOWN_ERROR, NFC_USER_CANCEL, NFC_CHIP_AUTH_FAILED, SMS_OTP_ERROR, SMS_OTP_INVALID_PHONE, SMS_OTP_MAX_ATTEMPTS, SMS_OTP_NOT_FOUND, SMS_OTP_RATE_LIMIT, QRCODE_ERROR, FETCH_HISTORY_ERROR, ESIGN_ERROR_UNKNOWN, ESIGN_MISSING_TOKEN, ESIGN_MISSING_CCCD, ESIGN_MISSING_REQUEST_JSON, ESIGN_MISSING_CONFIRMATION_DOC, ESIGN_NO_SESSION_ID, ESIGN_MISSING_ACCESS_TOKEN, ESIGN_MISSING_IDENTITY, ESIGN_MISSING_SERIAL, ESIGN_MISSING_REQUEST_ID, ESIGN_INVALID_CONTEXT, ESIGN_INVALID_LICENSE_CODE, ESIGN_INVALID_RECOVERY_CODE, ESIGN_INVALID_PIN_CODE, ESIGN_SESSION_INVALID, ESIGN_DEVICE_ALREADY_INIT, ESIGN_INVALID_LICENSE, ESIGN_INVALID_LICENSE_CONTENT, ESIGN_DEVICE_NOT_INIT, ESIGN_APP_LIMITED, ESIGN_INVALID_USER_ACCOUNT, ESIGN_SESSION_INVALID_REGISTER, ESIGN_INVALID_RECOVERY_OR_PIN, ESIGN_SESSION_INVALID_LIST_CERT, ESIGN_AUTH_EXISTS, ESIGN_INVALID_SIGN_COUNT_OR_TIME, ESIGN_INVALID_CERT_FOR_AUTH, ESIGN_AUTH_REQUEST_EXISTS, ESIGN_MISSING_NAME, ESIGN_MISSING_DEVICE_ID, ESIGN_INVALID_REQUEST_JSON, ESIGN_MISSING_PIN_CODE, ESIGN_MISSING_USER_PIN, ESIGN_INVALID_PAGE_PARAMS, ESIGN_INVALID_QUANTITY, ESIGN_INVALID_TIME, ESIGN_INVALID_PIN_FORMAT, ESIGN_INVALID_RECOVERY_FORMAT, ESIGN_MISSING_USER_INFO, ESIGN_MISSING_FIELD_IDENTITY, ESIGN_MISSING_FIELD_SOD, ESIGN_MISSING_FIELD_REGISTER_DATE, ESIGN_MISSING_FIELD_EXPIRED_DATE, ESIGN_MISSING_SIGNING_CONTENTS, ESIGN_MISSING_FIELD_DATA, ESIGN_MISSING_TOKEN_INFO, ESIGN_MISSING_FIELD_USERNAME, ESIGN_MISSING_FIELD_SERIAL_TOKEN, ESIGN_MISSING_FIELD_SESSION_ID, ESIGN_MISSING_FIELD_NAME, ESIGN_MISSING_FIELD_ADDRESS, ESIGN_MISSING_FIELD_SIGNATURE, ESIGN_MISSING_EMAIL_OR_PHONE, ESIGN_MISSING_POLICY_AGREEMENT, ESIGN_MISSING_FIELD_POLICY_STATUS, ESIGN_MISSING_FIELD_ACCEPT_TIME, ESIGN_MISSING_FIELD_DEVICE, ESIGN_MISSING_SIGN_POSITIONS, ESIGN_MISSING_SIGN_POSITION_LOCATION, ESIGN_MISSING_FIELD_DOCUMENT_NAME, ESIGN_INVALID_REGISTER_DATE_FORMAT, ESIGN_INVALID_EXPIRED_DATE_FORMAT, USER_CANCEL, ]; const CODE_MAP: Record = {}; PREDEFINED_ERRORS.forEach((e) => { CODE_MAP[e.code] = e; }); /** * Lấy message đã localize theo ngôn ngữ (giống Kotlin getLocalizedMessage). */ export function getLocalizedMessage( result: EKYCErrorResultLike, language?: EKYCErrorResultLanguage | null ): string { const lang = (language ?? '').toLowerCase(); if (lang === 'en') { return (result.enMessage || result.viMessage).trim(); } return (result.viMessage || result.enMessage).trim(); } /** * Tìm EKYCErrorResult theo code (giống Kotlin fromCode). */ export function fromCode(code: string): EKYCErrorResultLike | null { return CODE_MAP[code] ?? null; } /** * Tạo lỗi tùy biến (giống Kotlin createCustom / CustomError). */ export function createCustom(code: string, message: string): EKYCErrorResultLike { return defSame(code, message); } /** * Lấy error từ danh sách details (giống Kotlin getErrorResultFromDetails). * Chi tiết có thể có .code hoặc .getCode(). */ export function getErrorResultFromDetails( details: Array<{ code?: string; getCode?: () => string } | null> | null ): EKYCErrorResultLike { if (!details || details.length === 0) return ERROR_UNKNOWN; for (const detail of details) { if (detail == null) continue; const code = typeof detail.code === 'string' ? detail.code : typeof detail.getCode === 'function' ? detail.getCode() : null; if (code) { const predefined = fromCode(code); if (predefined) return predefined; } } return ERROR_UNKNOWN; } /** * Trả về message theo ngôn ngữ cho một result (alias tiện). */ export function getMessage(result: EKYCErrorResultLike, lang?: EKYCErrorResultLanguage | null): string { return getLocalizedMessage(result, lang); }