From c2e81a6f4e12b01d9c4215d5a31e171c744e9ced Mon Sep 17 00:00:00 2001 From: hailin Date: Thu, 25 Dec 2025 00:05:03 -0800 Subject: [PATCH] =?UTF-8?q?fix(kyc):=20=E4=BD=BF=E7=94=A8=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=9A=84=E9=98=BF=E9=87=8C=E4=BA=91=E6=89=8B=E6=9C=BA?= =?UTF-8?q?=E5=8F=B7=E4=B8=89=E8=A6=81=E7=B4=A0=E6=A0=B8=E9=AA=8CAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 从 VerifyMaterial (身份三要素,需要人脸照片) 改为 Mobile3MetaSimpleVerify (手机号三要素) - 手机号三要素验证:姓名 + 身份证号 + 手机号 - 添加 mapMobile3MetaErrorCode 方法映射错误码 文档: https://help.aliyun.com/zh/id-verification/information-verification/developer-reference/esf1ff158mxowkk6 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../external/kyc/aliyun-kyc.provider.ts | 67 +++++++++++++++---- 1 file changed, 53 insertions(+), 14 deletions(-) diff --git a/backend/services/identity-service/src/infrastructure/external/kyc/aliyun-kyc.provider.ts b/backend/services/identity-service/src/infrastructure/external/kyc/aliyun-kyc.provider.ts index fffa180c..b4150024 100644 --- a/backend/services/identity-service/src/infrastructure/external/kyc/aliyun-kyc.provider.ts +++ b/backend/services/identity-service/src/infrastructure/external/kyc/aliyun-kyc.provider.ts @@ -83,9 +83,11 @@ export class AliyunKycProvider { /** * ======================================== - * 层级1: 实名认证 - 三要素验证 + * 层级1: 实名认证 - 手机号三要素验证 * ======================================== * 验证姓名、身份证号和手机号是否匹配 + * 使用阿里云 Mobile3MetaSimpleVerify API (手机号三要素核验简版) + * 文档: https://help.aliyun.com/zh/id-verification/information-verification/developer-reference/esf1ff158mxowkk6 */ async verifyIdCard( realName: string, @@ -93,7 +95,7 @@ export class AliyunKycProvider { phoneNumber: string, requestId: string, ): Promise { - this.logger.log(`[AliyunKYC] [Level1] Starting ID card verification (3-factor), requestId: ${requestId}`); + this.logger.log(`[AliyunKYC] [Level1] Starting mobile 3-factor verification, requestId: ${requestId}`); // 开发/测试环境:模拟验证 if (!this.enabled) { @@ -102,27 +104,48 @@ export class AliyunKycProvider { } try { - // 调用阿里云身份三要素核验 API + // 调用阿里云手机号三要素核验简版 API (Mobile3MetaSimpleVerify) + // 参数说明: + // - ParamType: 加密方式 (normal=明文, md5=MD5加密, sm2=SM2加密) + // - UserName: 姓名 + // - IdentifyNum: 身份证号 + // - Mobile: 手机号 const params = { - Action: 'VerifyMaterial', + Action: 'Mobile3MetaSimpleVerify', Version: '2019-03-07', Format: 'JSON', - BizType: 'ID_CARD_THREE', - Name: realName, - IdCardNumber: idCardNumber, - PhoneNumber: phoneNumber, + ParamType: 'normal', // 使用明文传输 + UserName: realName, + IdentifyNum: idCardNumber, + Mobile: phoneNumber, }; const response = await this.callAliyunApi(params); + // Mobile3MetaSimpleVerify 返回结果: + // - Code: OK 表示请求成功 + // - ResultObject.BizCode: 0 表示验证通过, 其他值表示验证失败 if (response.Code === 'OK' || response.Code === '200') { - this.logger.log(`[AliyunKYC] [Level1] Verification SUCCESS for requestId: ${requestId}`); - return { - success: true, - rawResponse: response, - }; + const bizCode = response.ResultObject?.BizCode; + const isMatch = response.ResultObject?.IsConsistent === '1' || bizCode === '0'; + + if (isMatch) { + this.logger.log(`[AliyunKYC] [Level1] Verification SUCCESS for requestId: ${requestId}`); + return { + success: true, + rawResponse: response, + }; + } else { + const errorMsg = this.mapMobile3MetaErrorCode(bizCode); + this.logger.warn(`[AliyunKYC] [Level1] Verification FAILED: ${errorMsg} (BizCode: ${bizCode})`); + return { + success: false, + errorMessage: errorMsg, + rawResponse: response, + }; + } } else { - this.logger.warn(`[AliyunKYC] [Level1] Verification FAILED: ${response.Message}`); + this.logger.warn(`[AliyunKYC] [Level1] API call FAILED: ${response.Message}`); return { success: false, errorMessage: this.mapErrorMessage(response.Code, response.Message), @@ -139,6 +162,22 @@ export class AliyunKycProvider { } } + /** + * 映射手机号三要素核验错误码 + */ + private mapMobile3MetaErrorCode(bizCode: string): string { + const errorMap: Record = { + '1': '姓名与身份证号不匹配', + '2': '身份证号与手机号不匹配', + '3': '姓名与手机号不匹配', + '4': '三要素信息均不匹配', + '5': '无法查询到该手机号信息', + '6': '手机号已注销或停机', + '7': '查询失败,请稍后重试', + }; + return errorMap[bizCode] || `验证失败 (错误码: ${bizCode})`; + } + /** * ======================================== * 层级2: 实人认证 - 初始化人脸活体检测