This commit is contained in:
2026-06-29 11:25:32 +08:00
parent 2eec7e5bbe
commit 40b50a5a5c
4 changed files with 42 additions and 19 deletions

View File

@@ -171,6 +171,16 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
go s.asyncProcessDeduction(context.Background(), apiCall, validationResult) go s.asyncProcessDeduction(context.Background(), apiCall, validationResult)
return transactionId, "", ErrQueryEmpty return transactionId, "", ErrQueryEmpty
} }
if errors.Is(err, ErrSuccessNoBill) {
encryptedResponse, encErr := crypto.AesEncrypt([]byte(response), validationResult.GetSecretKey())
if encErr != nil {
s.logger.Error("加密响应失败", zap.Error(encErr))
go s.asyncRecordFailure(context.Background(), apiCall, encErr)
return "", "", ErrSystem
}
go s.asyncSaveApiCall(context.Background(), apiCall, validationResult, response, decimal.Zero)
return transactionId, string(encryptedResponse), nil
}
if err != nil { if err != nil {
// 异步记录失败状态 // 异步记录失败状态
go s.asyncRecordFailure(context.Background(), apiCall, err) go s.asyncRecordFailure(context.Background(), apiCall, err)
@@ -405,6 +415,11 @@ func (s *ApiApplicationServiceImpl) callExternalApi(ctx context.Context, cmd *co
callContext) callContext)
if err != nil { if err != nil {
var successNoBill *processors.SuccessNoBillError
if errors.As(err, &successNoBill) {
return string(successNoBill.Response), ErrSuccessNoBill
}
// 数据宝 10001/10006查空但计费由 CallApi 统一处理 // 数据宝 10001/10006查空但计费由 CallApi 统一处理
if errors.Is(err, shujubao.ErrQueryEmpty) { if errors.Is(err, shujubao.ErrQueryEmpty) {
return "", ErrQueryEmptyBillable return "", ErrQueryEmptyBillable
@@ -440,10 +455,13 @@ func (s *ApiApplicationServiceImpl) callExternalApi(ctx context.Context, cmd *co
return string(response), nil return string(response), nil
} }
// asyncSaveApiCall 异步保存API调用记录 // asyncSaveApiCall 异步保存API调用记录;可选 cost 覆盖扣费金额(如成功但不扣费场景传 decimal.Zero
func (s *ApiApplicationServiceImpl) asyncSaveApiCall(ctx context.Context, apiCall *entities.ApiCall, validation *dto.ApiCallValidationResult, response string) { func (s *ApiApplicationServiceImpl) asyncSaveApiCall(ctx context.Context, apiCall *entities.ApiCall, validation *dto.ApiCallValidationResult, response string, cost ...decimal.Decimal) {
// 标记为成功 chargeAmount := validation.GetAmount()
apiCall.MarkSuccess(validation.GetAmount()) if len(cost) > 0 {
chargeAmount = cost[0]
}
apiCall.MarkSuccess(chargeAmount)
// 检查TransactionID是否已存在避免重复创建 // 检查TransactionID是否已存在避免重复创建
existingCall, err := s.apiCallRepository.FindByTransactionId(ctx, apiCall.TransactionId) existingCall, err := s.apiCallRepository.FindByTransactionId(ctx, apiCall.TransactionId)

View File

@@ -7,6 +7,8 @@ var (
ErrQueryEmpty = errors.New("查询为空") ErrQueryEmpty = errors.New("查询为空")
// ErrQueryEmptyBillable 数据宝查空10001/10006对外返回查询为空但仍正常扣费 // ErrQueryEmptyBillable 数据宝查空10001/10006对外返回查询为空但仍正常扣费
ErrQueryEmptyBillable = errors.New("查询为空") ErrQueryEmptyBillable = errors.New("查询为空")
// ErrSuccessNoBill 对外返回正常业务响应,但不扣费
ErrSuccessNoBill = errors.New("成功不扣费")
ErrQueryFailed = errors.New("查询失败") ErrQueryFailed = errors.New("查询失败")
ErrSystem = errors.New("接口异常") ErrSystem = errors.New("接口异常")
ErrDecryptFail = errors.New("解密失败") ErrDecryptFail = errors.New("解密失败")

View File

@@ -10,3 +10,12 @@ var (
ErrNotFound = errors.New("查询为空") ErrNotFound = errors.New("查询为空")
ErrContactBusiness = errors.New("请联系商务咨询") ErrContactBusiness = errors.New("请联系商务咨询")
) )
// SuccessNoBillError 携带成功响应但不扣费(如活体检测 result=2
type SuccessNoBillError struct {
Response []byte
}
func (e *SuccessNoBillError) Error() string {
return "成功不扣费"
}

View File

@@ -8,9 +8,6 @@ import (
"tyapi-server/internal/domains/api/dto" "tyapi-server/internal/domains/api/dto"
"tyapi-server/internal/domains/api/services/processors" "tyapi-server/internal/domains/api/services/processors"
"tyapi-server/internal/infrastructure/external/shumai" "tyapi-server/internal/infrastructure/external/shumai"
"tyapi-server/internal/shared/logger"
"go.uber.org/zap"
) )
// ProcessIVYZX5Q2Request IVYZX5Q2 活体识别步骤二API处理方法 // ProcessIVYZX5Q2Request IVYZX5Q2 活体识别步骤二API处理方法
@@ -47,16 +44,13 @@ func ProcessIVYZX5Q2Request(ctx context.Context, params []byte, deps *processors
} }
} }
// result==2 时手动抛出错误(不通过/无记录,不返回正常响应 // result: 0-通过 1-不通过0/1 正常返回并扣费2-未找到结果(返回 codeDesc不扣费
var body struct { var body struct {
Result int `json:"result"` Result int `json:"result"`
CodeDesc string `json:"codeDesc"`
} }
if err := json.Unmarshal(respBytes, &body); err == nil && body.Result == 2 { if err := json.Unmarshal(respBytes, &body); err == nil && body.Result == 2 {
log := logger.GetGlobalLogger() return nil, &processors.SuccessNoBillError{Response: respBytes}
log.Warn("IVYZX5Q2 活体检测 result=2 无记录或不通过,返回错误",
zap.Int("result", body.Result),
zap.ByteString("response", respBytes))
return nil, errors.Join(processors.ErrNotFound, errors.New("活体检测 result=2 无记录或不通过"))
} }
return respBytes, nil return respBytes, nil