openapi: 3.0.3 info: title: ADO Tech - Risk Validation Webhooks API version: "3.0.0.0" description: | Documentación del webhook expuesto por los clientes para recibir las respuestas y resultados de los **procesos de validación de riesgo**. Estos procesos pueden estar compuestos por diferentes etapas (por ejemplo: interacciones de Liveness, captura de documentos CardCapture, o detección de Spoofing). El webhook consolidará o reportará los eventos, etapas y estados generados durante su ejecución. ## Autenticación (OIDC Client Credentials) Este webhook y sus endpoints deben estar asegurados requiriendo un token de acceso a través del flujo **OAuth 2.0 / OIDC Client Credentials** para comunicación Server-to-Server. 1. **Solicitud del Token:** ADO Tech actuará como un cliente, enviando sus credenciales (`client_id` y `client_secret`) al Authorization Server del cliente (o Identity Provider acordado) para obtener un *Access Token*. 2. **Envío del Token:** ADO enviará el token obtenido en la cabecera `Authorization` como un **Bearer Token** en todas las peticiones HTTP **POST** enviadas hacia el webhook del cliente. ### Formato del Token El token esperado será un **JWT (JSON Web Token)** firmado. El servidor que expone el webhook (el cliente) debe validar correctamente la firma, expiración (`exp`) y audiencia (`aud`) del JWT para asegurar que la petición proviene de ADO Tech y no ha sido alterada. servers: - url: https://api.customer-domain.com/v3 description: URL base del webhook del cliente (Customer Webhook URL) - La versión principal de la API debe corresponder al MAJOR version del documento. paths: /risk-validation-event: post: summary: Recibe la actualización de estado de procesos de validación de riesgo. description: | Al finalizar un proceso de validación de riesgo, o al originarse alertas críticas por etapas del proceso (ej. Spoofing), ADO invoca este webhook para notificar al cliente del resultado final y enviar la evidencia respectiva. operationId: receiveRiskValidationResponse security: - oidcClientCredentials: - webhook:receive parameters: - name: Authorization in: header description: | Cabecera de seguridad obligatoria que debe contener el token de acceso OIDC. ADO Technology enviará el Access Token con el prefijo Bearer. **Ejemplo:** `Bearer eyJhbGciOiJSUzI1NiIsInR5c...` required: true schema: type: string pattern: "^Bearer .+$" requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RiskValidationPayload' responses: '200': description: Evento de validación de riesgo recibido y procesado correctamente. '400': description: Petición inválida o payload malformado. '401': description: No autorizado (Falta la cabecera Authorization o el token JWT es inválido, expirado o manipulado). components: securitySchemes: oidcClientCredentials: type: oauth2 description: | Flujo de seguridad OIDC Client Credentials para autenticación Server-to-Server. ADO Technology solicita este token al Authorization Server del cliente antes de enviar notificaciones. flows: clientCredentials: tokenUrl: https://auth.customer-domain.com/oauth/token scopes: webhook:receive: Permiso para recibir notificaciones de eventos de validación de riesgo. schemas: # ─── Root Payload ──────────────────────────────────────────────────────────── RiskValidationPayload: type: object required: - transactionId - processId - transactionStatus - stages properties: transactionId: type: string example: "10743" description: Identificador de la transacción general de riesgo. processId: type: string example: "3f2b9c1e-7a4d-4f2a-9c0c-6c4c2e9b8d12" description: Identificador único del proceso general (GUID/UUID). transactionStatus: type: string enum: [APPROVED, REJECTED, FAILED] example: REJECTED description: Estado global de la transacción. stages: type: array description: | Listado de etapas que componen el proceso de validación de riesgo. Cada etapa varía su estructura según el valor de `processType`: - **LIVENESS**: objeto plano con campos propios del chequeo de vida (status, reason, uidDevice, etc.). - **CARDCAPTURE**: contiene un objeto `detail` anidado con el resultado de la captura del documento. items: oneOf: - $ref: '#/components/schemas/LivenessStage' - $ref: '#/components/schemas/CardCaptureStage' discriminator: propertyName: processType mapping: LIVENESS: '#/components/schemas/LivenessStage' CARDCAPTURE: '#/components/schemas/CardCaptureStage' # ─── Polymorphic Stages ────────────────────────────────────────────────────── LivenessStage: type: object description: | Etapa de tipo LIVENESS. El resultado se entrega como campos planos en el objeto raíz de la etapa, sin un sub-objeto `detail`. Este tipo de etapa puede contener evidencia de detección de Spoofing, PAD, etc. required: - processType - processId - uidDevice - status properties: processType: type: string enum: [LIVENESS] description: Discriminador de tipo de etapa. status: type: string enum: [APPROVED, REJECTED, FAILED] example: REJECTED description: Estado del resultado de la etapa de liveness. reason: $ref: '#/components/schemas/LivenessReason' uidDevice: type: string example: "1da62007d8974a9fa71e18cba76f6fc1" description: Identificador único del dispositivo del usuario final. keyProcessLiveness: type: string example: "69c265aeca9d4863b61b1fc6a8099f52" description: Identificador único del proceso de liveness. processId: type: string example: "3f2b9c1e-7a4d-4f2a-9c0c-6c4c2e9b8d12" description: Identificador único de esta etapa (GUID/UUID). CardCaptureStage: type: object description: | Etapa de tipo CARDCAPTURE. El resultado se entrega dentro de un objeto `detail` anidado. Incluye información de la cara del documento capturada (`side`) y el resultado del procesamiento. required: - processType - side - statusCode - detail properties: processType: type: string enum: [CARDCAPTURE] description: Discriminador de tipo de etapa. side: type: string enum: [FRONT, BACK] example: FRONT description: Lado del documento capturado. statusCode: type: integer enum: [1, 2, 3] example: 3 description: | Código numérico del resultado de la etapa de captura. - 1 = APPROVED - 2 = REJECTED - 3 = FAILED (ej. cancelado por el usuario, pérdida de foco) detail: $ref: '#/components/schemas/CardCaptureDetail' # ─── Nested Detail (CardCapture) ───────────────────────────────────────────── CardCaptureDetail: type: object required: - status - reason - uidDevice - processId properties: status: type: string enum: [APPROVED, REJECTED, FAILED] example: FAILED description: Estado textual del resultado de la etapa. reason: $ref: '#/components/schemas/CardCaptureReason' uidDevice: type: string example: "1da62007d8974a9fa71e18cba76f6fc1" description: Identificador único del dispositivo del usuario final. processId: type: string example: "3f2b9c1e-7a4d-4f2a-9c0c-6c4c2e9b8d12" description: Identificador único de esta etapa (GUID/UUID). image: $ref: '#/components/schemas/ImageEvidence' # ─── Reason Schemas ────────────────────────────────────────────────────────────── LivenessReason: type: object description: Razón del resultado de una etapa de tipo LIVENESS. required: - name - description properties: name: type: string description: | Código UPPERCASE que identifica la razón del resultado de la etapa LIVENESS. **APPROVED (statusCode: 1)** - `NOT_ALERT`: La transacción fue aprobada sin alertas detectadas. **REJECTED (statusCode: 2)** - `NOT_ALIVE`: El chequeo de liveness indica que el sujeto no está vivo. - `CLOSED_EYES`: Se detectaron ojos cerrados durante la captura. - `SPOOFING`: Se detectó un intento de suplantación (spoofing). - `PAD`: Se detectó un ataque de presentación (Presentation Attack Detection). **FAILED (statusCode: 3)** - `PERMISSION_DENIED`: El acceso a la cámara fue denegado. - `CAMERA_NOT_FOUND`: No se detectó ninguna cámara en el dispositivo. - `FACE_NOT_DETECTED`: No se detectó ningún rostro en el encuadre. - `NETWORK_ERROR`: Un problema de red impidió completar el proceso. - `SDK_ERROR`: Error interno del SDK durante el proceso. - `USER_CANCELED`: El usuario canceló el proceso antes de completarlo. enum: - NOT_ALERT - NOT_ALIVE - CLOSED_EYES - SPOOFING - PAD - PERMISSION_DENIED - CAMERA_NOT_FOUND - FACE_NOT_DETECTED - NETWORK_ERROR - SDK_ERROR - USER_CANCELED example: SPOOFING description: type: string example: "A potential spoofing attempt was detected during the liveness process." description: Explicación detallada y legible del motivo del resultado. code: type: string description: Código interno adicional de la razón (si aplica). CardCaptureReason: type: object description: Razón del resultado de una etapa de tipo CARDCAPTURE. required: - name - description properties: name: type: string description: | Código UPPERCASE que identifica la razón del resultado de la etapa CARDCAPTURE. **APPROVED (statusCode: 1)** - `NOT_ALERT`: La transacción fue aprobada sin alertas detectadas. **FAILED (statusCode: 3)** - `PERMISSION_DENIED`: El acceso a la cámara fue denegado. - `CAMERA_NOT_FOUND`: No se detectó ninguna cámara en el dispositivo. - `CAMERA_IN_USE`: La cámara está siendo usada por otra aplicación. - `NOT_SUPPORTED`: El dispositivo no cumple los requisitos para el proceso de captura. - `DOCUMENT_NOT_DETECTED`: No se detectó ningún documento en el encuadre. - `NETWORK_ERROR`: Un problema de red impidió completar el proceso. - `SDK_ERROR`: Error interno del SDK durante el proceso. - `USER_CANCELED`: El usuario canceló el proceso antes de completarlo. - `FOCUS_LOST`: El proceso fue interrumpido porque la app perdió el foco. enum: - NOT_ALERT - PERMISSION_DENIED - CAMERA_NOT_FOUND - CAMERA_IN_USE - NOT_SUPPORTED - DOCUMENT_NOT_DETECTED - NETWORK_ERROR - SDK_ERROR - USER_CANCELED - FOCUS_LOST example: USER_CANCELED description: type: string example: "The user canceled the process before completion." description: Explicación detallada y legible del motivo del resultado. code: type: string description: Código interno adicional de la razón (si aplica). ImageEvidence: type: object required: - encoding - mimeType - data properties: encoding: type: string enum: [base64] example: base64 description: Formato de codificación de la evidencia. mimeType: type: string example: image/jpeg description: Tipo MIME de la imagen (ej. image/jpeg, image/png). data: type: string description: Contenido de la imagen en Base64, sin el prefijo `data:image/...;base64,`.