10 - Mapa de Integraciones Externas
Validated Corrections
- Slack debe tratarse como integracion configurada pero no activa en el codigo observable del proyecto. Ni
SLACK_BOT_USER_OAUTH_TOKENniLOG_SLACK_WEBHOOK_URLfiguran en.env.example, y el log stack por defecto (LOG_STACK=single) no incluye el canal Slack. - Legal Check es TransUnion, no Experian. El UML del modulo (
docs/DIAGRAMA_APROBAR_CUPO_UML.md) atribuye el legal check a Experian CrossCore. El codigo (app/Services/LegalCheckService.php:37y el macroHttp::transunion()enapp/Providers/AppServiceProvider.php:19-30) lo manda a TransUnion con Basic Auth. Este mapa refleja la realidad de runtime. - El gate de aprobacion del cupo (
AprobarCupoService::validarSiElClienteTieneSuCupoAprobado()) no es una cadena secuencial estricta: pide>= 5ProcessTypedistintos cuyo evento mas reciente del mes en curso seaFINISH_SUCCESS. Las dependencias “criticas” listadas en la seccion 6 son una lectura del flujo intencionado en el frontend, no una garantia del backend. GET /api/v1/datacredito/historialno es solo una comodidad tecnica: es un endpoint publico sensible y debe leerse con implicaciones de seguridad.- El webhook de Certicamara necesita una nota mas fuerte: hoy la documentacion no refleja suficientemente que el callback publico carece de una verificacion fuerte visible en el controlador.
DataCreditoServicemantiene unrequestUUIDfijo y una cache que no incorporaapellido; ambos detalles son relevantes y deben figurar como riesgos tecnicos del mapa.- Este documento es fuerte en inventario, pero debe endurecer su lectura de riesgo operativo y de exposicion.
1. Inventario de Integraciones
| # | Nombre del Servicio | Proveedor | Proposito | Metodo de Autenticacion | Variables de Entorno (principales) | Variable URL Base |
|---|---|---|---|---|---|---|
| 1 | TransUnion LegalCheck | TransUnion | Screening en listas legales/regulatorias, verificacion de estado del documento | HTTP Basic Auth (usuario/contrasena) | TRANSUNION_API_URL, TRANSUNION_API_USERNAME, TRANSUNION_API_PASSWORD | TRANSUNION_API_URL |
| 2 | Experian CrossCore (Evidente) | Experian (via Okta) | Validacion de identidad, generacion/verificacion de OTP, cuestionario basado en conocimiento | OAuth 2.0 (password grant via Okta) + headers de API key | EXPIRIAN_CROSS_CORE_AUTH_API_URL, EXPIRIAN_CROSS_CORE_API_URL, EXPIRIAN_CROSS_CORE_API_CLIENT_ID, EXPIRIAN_CROSS_CORE_API_CLIENT_SECRET, EXPIRIAN_CROSS_CORE_API_USERNAME, EXPIRIAN_CROSS_CORE_API_PASSWORD | EXPIRIAN_CROSS_CORE_API_URL |
| 3 | DataCredito (HDC Plus) | DataCredito / Experian Colombia | Reporte de historia crediticia (HDC Plus), credit scoring | OAuth 2.0 (endpoint de token personalizado) + headers de API key | DATACREDITO_API_URL, DATACREDITO_CLIENT_ID, DATACREDITO_CLIENT_SECRET, DATACREDITO_USERNAME, DATACREDITO_PASSWORD, DATACREDITO_USER, DATACREDITO_USER_PASSWORD | DATACREDITO_API_URL |
| 4 | Certicamara (ePagare) | Certicamara S.A. | Creacion de pagare digital, verificacion de firma | Token de API estatico (header x-sckey-token) | CERTICAMARA_CREATE_URL, CERTICAMARA_SEARCH_URL, CERTICAMARA_TOKEN, CERTICAMARA_TEMPLATE_ID | CERTICAMARA_CREATE_URL / CERTICAMARA_SEARCH_URL |
| 5 | Core Credito (SHIVAM) | Core bancario interno (on-premise) | Creacion de cliente en sistema crediticio, registro de compras, consultas de cupo crediticio | Headers personalizados (usuario/contrasena en headers HTTP) | CORE_CREDITO_ENDPOINT, CORE_CREDITO_REQ_USER_ID, CORE_CREDITO_REQ_PASSWD | CORE_CREDITO_ENDPOINT |
| 6 | EMCALI Membresias | EMCALI (servicio publico) | Validacion de contrato/membresia, chequeo de aprobacion de cupos | Ninguno (sin autenticacion) | EMCALI_MEMBRESIAS_API_URL | EMCALI_MEMBRESIAS_API_URL |
| 7 | Notificaciones Slack | Slack | Configurado pero inactivo — no se despachan notificaciones en el codigo observable; LOG_SLACK_WEBHOOK_URL no esta declarado en .env.example y las variables de entorno del bot token estan ausentes del archivo de ejemplo | Bot OAuth token (declarado en config/services.php) + URL de webhook (declarado en config/logging.php) | SLACK_BOT_USER_OAUTH_TOKEN, SLACK_BOT_USER_DEFAULT_CHANNEL, LOG_SLACK_WEBHOOK_URL | N/A (Driver Slack de Laravel) |
2. Detalles de Integraciones
2.1 TransUnion LegalCheck
Clase de servicio: App\Services\LegalCheckService
Macro de cliente HTTP: Http::transunion() (registrado en app/Providers/AppServiceProvider.php:19-30) — URL base desde services.transunion.endpoint + withBasicAuth() usando services.transunion.username/password + timeout de 300s + JSON accept.
El diagrama UML oficial de clases (
docs/DIAGRAMA_APROBAR_CUPO_UML.md) describeLegalCheckServiceintegrandose con Experian. El codigo real enLegalCheckService.php:37invocaHttp::transunion()->post('/ws/LegalcheckWSRest/legalcheck/consulta', ...). TransUnion es el proveedor real — el UML esta equivocado en este punto.
| Metodo | Endpoint | Proposito |
|---|---|---|
manejar(User) | POST /ws/LegalcheckWSRest/legalcheck/consulta | Hacer screening de una persona contra listas legales/regulatorias |
Datos enviados:
{ "codigoInformacion": "5766", "tipoIdentificacion": "<mapped_doc_type>", "numeroIdentificacion": "<dni>"}Datos recibidos: JSON con nombre, estadoDocumento, data (array de hallazgos en listas legales con booleanos list_id y finding).
Manejo de errores:
- Si el request HTTP falla: lanza
ValidationExceptioncon un mensaje visible al usuario. - Validacion de negocio: compara el nombre retornado contra el nombre del usuario usando
similar_text()con un umbral minimo configurable (TRANSUNION_PORCENTAJE_NOMBRE_MINIMO, por defecto 70%). - Verifica que
estadoDocumentosea “VIGENTE”. - Itera los IDs de listas restringidas (configurados en
services.transunion.lista_con_restricciones) para buscar hallazgos legales. - Retorna DTO
LegalCheckResult(patron success/error). - Emite eventos
ValidationLogpara la traza de auditoria.
Comportamiento ante fallo: Lanza ValidationException en fallos HTTP; retorna DTO de error en violaciones de reglas de negocio. Sin logica de reintento. Sin fallback.
2.2 Experian CrossCore (Evidente)
Clase de servicio: App\Services\IdentityValidationService
Macros de cliente HTTP:
Http::expirianCrossCoreAuth()— endpoint de auth Okta. El macroexpirianCrossCoreAuth()establece un header crudoAuthorizationdesde la variable de entornoEXPIRIAN_CROSS_CORE_AUTH(NO mediante el metodowithBasicAuth()de Laravel). Se espera que el valor del env contenga una cadena de auth pre-formateada (probablementeBasic base64(user:pass))Http::expirianCrossCore()— endpoint de API, JSON accept, timeout de 300s
| Metodo | Endpoint | Proposito |
|---|---|---|
generateToken() | POST /oauth2/aus8jhfmnuDjZO8Q11t7/v1/token (en URL base de auth) | Obtener token de acceso OAuth 2.0 via password grant |
validarIdentidad(User) | POST /op/evidentemaster/v1/identificacion/validar | Validacion inicial de identidad |
generarOTP(User) | POST /da/evidente/v3/otp/initialize | Inicializar transaccion OTP |
| (continua) | POST /da/evidente/v3/otp/evaluation | Evaluar riesgo y enviar OTP a email/telefono |
verificarOTP(User, code) | POST /da/evidente/v3/otp/verify | Verificar codigo OTP (hash SHA-256) |
generarCuestionario(User) | POST /op/evidentemaster/v1/identificacion/preguntas | Generar preguntas de autenticacion basadas en conocimiento |
verificarCuestionario(User, answers) | POST /op/evidentemaster/v1/identificacion/verificar | Verificar respuestas del cuestionario |
Flujo de autenticacion: Cada llamada de API obtiene un token OAuth fresco desde Okta (password grant con scope expco_evidente_master). El token se pasa como header access_token junto con headers client_secret y client_id.
Datos enviados: Documentos de identidad (tipo/numero), nombres, fechas de expedicion del documento, codigos OTP (hash SHA-256), respuestas del cuestionario.
Datos recibidos: Resultados de validacion (codigos resultado), IDs de transaccion OTP, preguntas/respuestas del cuestionario, flags de aprobacion, scores.
Manejo de errores:
- Generacion de token: lanza excepciones especificas para
unsupported_grant_type,invalid_grant,invalid_scope. - Cada metodo retorna DTOs tipados:
IdentityValidationResult,GenerateOTPResult,VerifyOTPResult,GenerateQuestionnarieResult,VerifyQuestionnarieResult. - La generacion del cuestionario maneja codigos:
00(inactivo),02(ya generado),07(preguntas insuficientes),10/11/12(limites de intento diario/mensual/anual agotados). - Estado cacheado en Redis/cache:
{userId}.validacion(60 min),{userId}.transaccion_otp_id(30 min),{userId}.requiere_cuestionario(30 min),{userId}.cuestionario_id(30 min),{userId}.registro_cuestionario(30 min). - Emite eventos
ValidationLogpara cada paso.
Comportamiento ante fallo: Retorna DTOs de error con mensajes visibles al usuario. Sin reintento automatico. Token fresco por llamada (sin caching de token). Estado de validacion previo faltante resulta en retorno temprano con error.
2.3 DataCredito (HDC Plus)
Clase de servicio: App\Services\DataCreditoService
Macro de cliente HTTP: Http::datacredito() — URL base + JSON accept + timeout de 60s
| Metodo | Endpoint | Proposito |
|---|---|---|
generarToken() | POST /spla/oauth2/v1/token | Generar token de acceso OAuth |
revocarToken(token?) | POST /spla/oauth2/v1/revokeToken | Revocar token de acceso |
consultarHistorialCredito(...) | POST /cs/credit-history/v1/hdcplus | Consultar reporte completo de historia crediticia |
consultarHistorialPorTipoDocumento(...) | (delega al anterior) | Wrapper de conveniencia con mapeo de tipo de documento |
Flujo de autenticacion: Token OAuth 2.0 obtenido via headers Client_id + Client_secret y body username/password. Token cacheado por 590 segundos (justo bajo el vencimiento de 10 min). Pasado como Bearer token en llamadas subsiguientes.
Datos enviados:
{ "user": "<user>", "password": "<user_password>", "identifyingTrx": { "requestUUID": "...", "dateTime": "...", "originatorChannelName": "...", "originatorChannelType": "..." }, "identifyingUser": { "person": { "personId": { "personIdNumber": "...", "personIdType": 1 }, "personLastName": "..." } }, "parameters": [{ "type": "0", "nameParameter": "codigos", "valueParameter": "TOM-001" }]}Datos recibidos: Objeto ReportHDCplus que contiene productResult.responseCode, models[].scoreValue, y la data completa de historia crediticia.
Manejo de errores:
- Refresh de token al recibir 401: limpia cache, genera nuevo token, reintenta el request una vez.
- Las respuestas exitosas se cachean por 24 horas (
datacredito.historial.{doc}.{type}). - Las respuestas fallidas limpian la entrada de cache y registran el error.
- Entorno local: pasa por proxy a traves de
https://test.miplante.com/api/v1/datacredito/historialpara data mock. - Excepciones registradas y re-lanzadas.
Comportamiento ante fallo: Un solo reintento automatico ante 401 (expiracion de token). Sin otros reintentos. Las excepciones se propagan al caller. Cache usado para evitar llamadas redundantes dentro de 24h.
Puntos de riesgo observables en este servicio:
requestUUIDhard-coded enDataCreditoService.php:185— cada llamada no-local envia'3fa85f64-5717-4562-b3fc-2c963f66afa6'comoidentifyingTrx.requestUUID. La linea comentada arriba muestra que la intencion eraStr::uuid()->toString(). Esto rompe el contrato de auditoria/correlacion que DataCredito espera y hace que la trazabilidad de requests del lado servidor sea imposible de desambiguar.- La clave de cache omite
apellidoenDataCreditoService.php:141—"datacredito.historial.{$personIdNumber}.{$personIdType}"solo usa documento como clave. Si se hacen dos consultas para el mismo DNI conpersonLastNamedistinto, la segunda retorna el body cacheado de la primera. El TTL de 24h amplifica el impacto. - Bypass mock del entorno local en
DataCreditoService.php:153-178— cuandoapp()->environment('local'), el servicio no llama a DataCredito en absoluto; emite un HTTP GET ahttps://test.miplante.com/api/v1/datacredito/historialy reconstruye unResponsefalso. El mock local es por lo tanto una llamada de red a un hostname compartido con produccion, no a un fixture local.
Consumido por:
HDCValidationService— valida la historia crediticia durante el flujo de aprobacion del creditoExtenderCupoService— lee el score crediticio para decisiones de extension de cupo
2.4 Certicamara (ePagare)
Clase de servicio: App\Services\CerticamaraService
Macro de cliente HTTP: Http::certicamara() — header x-sckey-token + JSON + timeout de 60s
| Metodo | Endpoint | Proposito |
|---|---|---|
crearPagare(datos) | POST {CERTICAMARA_CREATE_URL} (default: https://services.eworkflow.co/core/ws/rest/create) | Crear pagare digital para firmar |
verificarPagare(uuid) | GET {CERTICAMARA_SEARCH_URL} (default: https://services.epagare.co/.../search) | Verificar estado de firma de un pagare |
Datos enviados (crear): Payload basado en template con firma secuencial, datos del firmante (nombre, email, documento, movil), validacion biometrica (E_BIOMETRICS), expiracion de 15 minutos.
Datos recibidos: JSON con UUID del documento, estado, informacion del firmante.
Manejo de errores: Registra exito/error. Retorna data de respuesta como array (array vacio en respuesta null). No se lanzan excepciones ante errores de API — el caller debe verificar el contenido de la respuesta.
Comportamiento ante fallo: Sin logica de reintento. Sin fallback. Solo logging.
2.5 Core Credito (SHIVAM Banking Core)
Clase de servicio: App\Services\CoreCreditoService
Cliente HTTP: Llamadas directas Http::withHeaders(...) (sin macro) — SOAP/XML sobre HTTP, verificacion SSL deshabilitada, timeout de 60s
| Metodo | Accion SOAP (Req_Mthd) | Proposito |
|---|---|---|
crearCliente(datos) | modSolicitud | Crear/registrar cliente en el sistema crediticio, obtener numero VCARD |
registrarCompra(datos) | pstPurchase | Registrar una transaccion de compra contra el credito del cliente |
consultarCupo(datos) | qryLimit | Consultar cupo crediticio disponible, dias en mora, monto en mora |
Protocolo: XML SOAP sobre HTTP POST a un endpoint on-premise (default: https://10.241.88.102:8443/...).
Autenticacion: Headers personalizados por request: Req_UserID, Req_PassWD, Req_PrcCode, Req_MsgCode, Req_Type, Res_MsgCode, Log_Channel.
Datos enviados: Envelopes XML SOAP con elementos en namespace IFX que contienen los datos del cliente, detalles de compra o parametros de consulta.
Datos recibidos: Respuestas XML SOAP parseadas a arrays. Campos clave: ErrorID (exito = S0000), ErrorSDesc, ApplNo (numero VCARD), CreditLimitApp, CreditLimitAvl, DaysinArrears, ArrearAmt, TrxnRefNo.
Manejo de errores:
- Parseo XML con manejo interno de errores de
libxml. - Normalizacion de encoding de caracteres (eliminacion de BOM, deteccion/conversion de encoding).
- Excepciones registradas con contexto y re-lanzadas.
- Exito determinado por
ErrorID === 'S0000'.
Comportamiento ante fallo: Sin logica de reintento. Las excepciones se propagan. La verificacion SSL se deshabilita explicitamente para el endpoint IP interno.
Consumido por:
CreditoService— orquesta creacion de cliente, registro de compra, consultas de creditoExtenderCupoService— sincroniza los cupos crediticios actualizados despues de la extension
2.6 EMCALI Membresias
Clase de servicio: App\Services\EmcaliMembresiaService
Cliente HTTP: Directo Http::timeout(30)->contentType('application/json') — sin macro, sin auth
| Metodo | Endpoint | Proposito |
|---|---|---|
consultarMembresia(numero_contrato) | GET {EMCALI_MEMBRESIAS_API_URL} (con body JSON) | Validar contrato de membresia, obtener cupos aprobados |
Datos enviados: {"contrato": <numero_contrato>} como body JSON en request GET.
Datos recibidos: Datos de membresia con niveles de cupo aprobados (claves como {amount}_{installments} con valor "Si"/"No"), o mensajes de error.
Manejo de errores:
- Configuracion de endpoint faltante: lanza
EmcaliMembresiaException. - Errores de cliente (4xx): parseados para detectar errores de negocio (contrato requerido, contrato no encontrado) y cacheados por 1 dia.
- Errores de servidor (5xx): registrados con contexto completo, no cacheados.
- Excepciones: capturadas, registradas, retorna
ConsultarMembresiaResult::unexpectedError(). - Retorna DTO
ConsultarMembresiaResultcon contextos de error tipados (enumEmcaliServiceErrorType).
Comportamiento ante fallo: Sin logica de reintento. Las respuestas exitosas y de error de cliente se cachean por 24h. Los errores de servidor y excepciones no se cachean (permite reintento inmediato). Degradacion elegante via patron DTO.
Consumido por:
CreditoService::clientePresentaMora()— verifica morosidadExtenderCupoService::extender()— determina elegibilidad de extension crediticia
2.7 Notificaciones Slack (configurado, inactivo)
Configuracion: Existen dos configuraciones Slack en paralelo pero ninguna esta conectada a rutas de codigo activas en el repositorio observable:
config/services.php:31-35defineslack.notifications.bot_user_oauth_tokenyslack.notifications.channel— destinados al canal de Notification de Laravel. Las claves envSLACK_BOT_USER_OAUTH_TOKENySLACK_BOT_USER_DEFAULT_CHANNELNO estan presentes en.env.example.config/logging.php:90-95define un canal de logslackcon claveLOG_SLACK_WEBHOOK_URL. Esa clave env tampoco esta en.env.example, yLOG_STACK=singleen el ejemplo significa que el log stack no incluye Slack.
Autenticacion: Token OAuth de Bot User (services.php) o URL de webhook entrante (logging.php). Ninguno esta configurado por defecto. Ninguna ruta de codigo actualmente despacha una notificacion Slack o publica al canal de log Slack.
| Variable Env | Definida en | Conectada a codigo activo? |
|---|---|---|
SLACK_BOT_USER_OAUTH_TOKEN | config/services.php (no en .env.example) | No |
SLACK_BOT_USER_DEFAULT_CHANNEL | config/services.php (no en .env.example) | No |
LOG_SLACK_WEBHOOK_URL | config/logging.php (no en .env.example) | No (no esta en LOG_STACK=single) |
3. Diagrama de Conexion de Servicios Externos
graph TB
subgraph "Aplicacion MiPlante"
LSC[LegalCheckService]
IVS[IdentityValidationService]
DCS[DataCreditoService]
CS[CerticamaraService]
CCS[CoreCreditoService]
EMS[EmcaliMembresiaService]
HDCVS[HDCValidationService]
CRDS[CreditoService]
EXTS[ExtenderCupoService]
WH_CERT[Webhook: CerticamaraController]
API_DC[API: DataCreditoController]
SLACK[Notificaciones Slack]
end
subgraph "Servicios Externos"
TU[TransUnion<br/>API LegalCheck]
EXP_AUTH[Experian Okta<br/>Servidor de Auth]
EXP_API[Experian CrossCore<br/>API Evidente]
DC[DataCredito<br/>API HDC Plus]
CERT[Certicamara<br/>API ePagare]
CORE[Core Credito<br/>SHIVAM Banking]
EMC[EMCALI<br/>API Membresias]
SLK[API Slack]
end
%% Conexiones de servicios
LSC -->|"POST /consulta<br/>Basic Auth"| TU
IVS -->|"POST /token<br/>OAuth Password Grant"| EXP_AUTH
IVS -->|"POST /validar, /otp/*, /preguntas, /verificar<br/>OAuth Token + API Key"| EXP_API
DCS -->|"POST /token, /hdcplus<br/>OAuth Token + API Key"| DC
CS -->|"POST /create, GET /search<br/>API Token"| CERT
CCS -->|"POST SOAP XML<br/>Headers Personalizados"| CORE
EMS -->|"GET (body JSON)<br/>Sin Auth"| EMC
SLACK -->|"Bot OAuth Token"| SLK
%% Delegacion interna
HDCVS -.->|delega| DCS
CRDS -.->|delega| CCS
CRDS -.->|delega| EMS
EXTS -.->|delega| EMS
EXTS -.->|delega| DCS
EXTS -.->|delega| CRDS
%% Webhook entrante
CERT -->|"POST /api/v1/webhooks/certicamara<br/>Callback de evento de firma"| WH_CERT
%% Proxy de API
API_DC -.->|delega| DCS
style TU fill:#f9d71c,stroke:#333
style EXP_AUTH fill:#f9d71c,stroke:#333
style EXP_API fill:#f9d71c,stroke:#333
style DC fill:#f9d71c,stroke:#333
style CERT fill:#f9d71c,stroke:#333
style CORE fill:#e74c3c,stroke:#333,color:#fff
style EMC fill:#f9d71c,stroke:#333
style SLK fill:#4a154b,stroke:#333,color:#fff
4. Endpoints de Webhook
| Ruta | Metodo | Controlador | Llamador Externo | Proposito | Autenticacion |
|---|---|---|---|---|---|
/api/v1/webhooks/certicamara | POST | Webhooks\CerticamaraController | Certicamara ePagare | Recibe notificaciones de estado de firma para pagares digitales | Ninguna. Ruta publica de API solamente bajo el middleware api. El controlador (app/Http/Controllers/Webhooks/CerticamaraController.php) no verifica un header de firma, HMAC, token de shared-secret, o IP de origen. La unica verificacion de autorizacion es Cliente::where('certicamara_uuid', $uuid)->first() — cualquiera que pueda adivinar u obtener un UUID valido puede manejar el pipeline de jobs. |
Flujo del webhook:
- Certicamara envia POST con
uuidy payload de evento cuando ocurre un evento de firma de pagare. - El controlador busca el
Clienteporcerticamara_uuid. - Si lo encuentra, despacha el job
ValidarPagareDigitalen la colacreditoscon$clientey$request->all()como payload. - Retorna 200 con JSON de exito, o 404 si no se encontro el cliente.
Riesgo: El controlador del webhook trata cualquier POST con un certicamara_uuid conocido como autentico. Un callback falsificado que incluya el uuid correcto y un valor state puede disparar cambios de estado de pagare (firmado/bloqueado/expirado), que a su vez manejan ProcesarPagareDigital y GenerarCreditoDeVenta, ambos los cuales mutan estado de Venta y OrdenCompra y llaman a SHIVAM. Se debe agregar mitigacion antes de que esta superficie sea considerada segura.
Endpoints de Proxy de API:
| Ruta | Metodo | Controlador | Proposito |
|---|---|---|---|
GET /api/v1/datacredito/historial | GET | Api\DataCreditoController | Proxy publico de DataCredito. Usado por la rama mock de entorno local de DataCreditoService::consultarHistorialCredito(), pero la ruta misma es publicamente alcanzable en cualquier host que la sirva. Sensibilidad: retorna la historia crediticia completa HDC Plus incluyendo el score. Debe tratarse como un endpoint privilegiado y restringirse. |
5. Resumen de Metodos de Autenticacion
| Integracion | Metodo de Auth | Ciclo de Vida del Token | Headers/Mecanismo |
|---|---|---|---|
| TransUnion | HTTP Basic Auth | Persistente (credenciales de config) | Authorization: Basic base64(user:pass) via withBasicAuth() |
| Experian CrossCore Auth | Header Authorization crudo (pre-formateado desde env) | Por request, sin timeout explicito (usa default de Guzzle/Laravel) | Authorization: {EXPIRIAN_CROSS_CORE_AUTH} a Okta (se espera que el valor env contenga la cadena de auth completa, ej. Basic base64(user:pass)) |
| Experian CrossCore API | OAuth 2.0 Bearer + API Keys | Token fresco por llamada (sin caching) | access_token, client_secret, client_id como headers personalizados |
| DataCredito | OAuth 2.0 Bearer + API Keys | Token cacheado 590s (~10 min) | Authorization: Bearer {token} + headers Client_id, Client_secret, ProductId, serverIpAddress |
| Certicamara | Token de API Estatico | Persistente (config) | Header x-sckey-token: {CERTICAMARA_TOKEN} |
| Core Credito | Auth por Header Personalizado | Por request (credenciales de config) | Req_UserID, Req_PassWD en headers HTTP |
| EMCALI | Ninguna | N/A | Request HTTP sin autenticacion |
| Slack | Bot OAuth Token | Persistente (config) | Driver estandar de notificacion Slack de Laravel |
6. Manejo de Fallos y Comportamiento de Fallback
| Integracion | Logica de Reintento | Estrategia de Caching | Comportamiento de Fallback | Timeout |
|---|---|---|---|---|
| TransUnion | Ninguno | Ninguno | Se lanza ValidationException; bloquea el flujo de aprobacion crediticia | 300s |
| Experian CrossCore | Ninguno (el token fresco por llamada evita problemas de token vencido) | Estado de validacion cacheado 30-60 min en cache de la app | DTO de error retornado; el usuario ve mensaje; puede reintentar manualmente | 300s (llamadas API) / default (llamadas de auth) |
| DataCredito | Un reintento ante 401 (refresh de token) | Token cacheado 590s; respuestas exitosas cacheadas 24h | Excepcion propagada; validacion HDC retorna false; ExtenderCupo retorna sin-extension | 60s |
| Certicamara | Ninguno | Ninguno | Array vacio retornado; el caller debe manejarlo | 60s |
| Core Credito | Ninguno | Ninguno | String de mensaje de error retornado desde CreditoService; bloquea creacion de cliente o compra | 60s |
| EMCALI | Ninguno (pero errores de servidor no cacheados, permitiendo recall inmediato) | Exito y errores de cliente cacheados 24h; errores de servidor NO cacheados | ConsultarMembresiaResult::unexpectedError() retornado; en clientePresentaMora() la excepcion se captura y retorna false | 30s |
| Slack | N/A — ninguna ruta de codigo despacha Slack hoy | N/A | Sin ruta de codigo observable. Las variables env requeridas estan ausentes de .env.example; LOG_STACK=single excluye el canal de log Slack. | Default (si alguna vez se invoca) |
Dependencias de la Ruta Critica
El flujo de aprobacion crediticia no es un pipeline secuencial estricto. El frontend en ModalValidate.vue lleva al usuario por las fases en orden, pero el gate del backend (AprobarCupoService::validarSiElClienteTieneSuCupoAprobado() en app/Services/AprobarCupoService.php:17-38) solo requiere que al menos 5 valores distintos de ProcessType tengan su evento mas reciente del mes calendario actual como FINISH_SUCCESS. El orden no importa; solo importa “el ultimo intento por process_type este mes fue exitoso”.
Las integraciones consumidas por el flujo:
- Legal Check (TransUnion
LegalCheckService) —ProcessType::LEGAL_CHECK. El fallo HTTP lanzaValidationException; los fallos de regla de negocio retornan un DTO de error y registranFINISH_UNSUCCESS. El contador de intentos diarios usa como clave los eventosLEGAL_CHECK / START. - Validacion de Identidad (Experian CrossCore
IdentityValidationService::validarIdentidad) —ProcessType::IDENTITY_VALIDATION. Pobla el cache{userId}.validacion(60 min) del que dependen las llamadas posteriores a Experian. - Generacion + Verificacion de OTP (Experian CrossCore) —
ProcessType::IV_OTP_GENERATIONyIV_OTP_VERIFICATION. Ambas fases son requeridas para contar, pero el backend no valida que la verificacion OTP fuera exitosa antes de que el endpoint del cuestionario sea alcanzable — la unica precondicion es el cache{userId}.validacionde la Fase 2. - Cuestionario (Experian CrossCore, condicional) —
IV_QUESTION_GENERATIONyIV_QUESTION_VERIFICATION. Solo requerido cuandorequiere_cuestionariose establecio durante la generacion del OTP; esa flag vive solamente en cache y no se aplica como precondicion del backend. - Validacion HDC (DataCredito via
HDCValidationService) —ProcessType::HDC_VALIDATION. El servicio retornabool;responseCode === 13desde DataCredito es la unica condicion de exito. Aqui no se exige un score minimo (el mapeo score-a-porcentaje enExtenderCupoServicees post-aprobacion). - Aprobacion del Credito (Fase 7) — no es un
ProcessTypeni esta limitado porCheckIntentosLimiteDiarios./usuario/cupo/aprobarcorre el gate>= 5, establececupo_vence_en, luego intenta extender el cupo viaExtenderCupoService(EMCALI + score de DataCredito) y empuja el resultado al Core Credito SHIVAM viaCreditoService::crearClienteEnCredito(force=true). - Pagare (Certicamara) — creado en checkout, no durante la aprobacion. El callback asincrono del webhook es la senal de finalizacion.
No hay fallbacks entre servicios (no hay buro de credito alternativo si DataCredito se cae). Las llamadas a HDC, EMCALI y SHIVAM fallan cerradas de formas distintas: HDC retorna false ante cualquier excepcion, EMCALI retorna unexpectedError() y es capturado por clientePresentaMora() (falla abierta), las excepciones de SHIVAM se propagan.
Comportamiento Especifico por Entorno
| Entorno | Comportamiento de DataCredito |
|---|---|
local | Hace proxy de consultas de historia crediticia a https://test.miplante.com/api/v1/datacredito/historial para data mock |
staging/production | Llamadas directas a la API de DataCredito |
Apendice: Referencia Completa de Variables ENV Por Integracion
TransUnion (4 vars)
TRANSUNION_API_URLTRANSUNION_API_USERNAMETRANSUNION_API_PASSWORDTRANSUNION_PORCENTAJE_NOMBRE_MINIMO(default: 70)
Experian CrossCore (13 vars)
EXPIRIAN_CROSS_CORE_AUTH_API_URLEXPIRIAN_CROSS_CORE_AUTHEXPIRIAN_CROSS_CORE_API_URLEXPIRIAN_CROSS_CORE_API_CLIENT_SECRETEXPIRIAN_CROSS_CORE_API_CLIENT_IDEXPIRIAN_CROSS_CORE_API_USERNAMEEXPIRIAN_CROSS_CORE_API_PASSWORDEXPIRIAN_CROSS_CORE_ID_USUARIO_ENTIDADEXPIRIAN_CROSS_CORE_COD_PRODUCTOEXPIRIAN_CROSS_CORE_COD_PARAMETRO_PRODUCTOEXPIRIAN_CROSS_CORE_NIT_ENTIDADEXPIRIAN_CROSS_CORE_CANAL_ENTIDADEXPIRIAN_CROSS_CORE_API_QUESTIONNAIRE_MIN_SCORE(default: 100)
DataCredito (12 vars)
DATACREDITO_API_URLDATACREDITO_CLIENT_IDDATACREDITO_CLIENT_SECRETDATACREDITO_USERNAMEDATACREDITO_PASSWORDDATACREDITO_USERDATACREDITO_USER_PASSWORDDATACREDITO_SERVER_IPDATACREDITO_PRODUCT_IDDATACREDITO_INFO_ACCOUNT_TYPE(default: 1)DATACREDITO_ORIGINATOR_CHANNEL_NAMEDATACREDITO_ORIGINATOR_CHANNEL_TYPE
Certicamara (5 vars)
CERTICAMARA_CREATE_URL(default:https://services.eworkflow.co/core/ws/rest/create)CERTICAMARA_SEARCH_URL(default:https://services.epagare.co/.../search)CERTICAMARA_TOKENCERTICAMARA_TEMPLATE_ID(default:Pagare_v12025.pdf)CERTICAMARA_OWNER_EMAIL(default:gerenciaadministrativa@miplante.com)
Core Credito (8 vars)
CORE_CREDITO_ENDPOINT(default:https://10.241.88.102:8443/...)CORE_CREDITO_REQ_PRC_CODE(default:038000)CORE_CREDITO_LOG_CHANNEL(default:MP)CORE_CREDITO_REQ_USER_IDCORE_CREDITO_REQ_PASSWDCORE_CREDITO_REQ_MSG_CODE(default:0340)CORE_CREDITO_REQ_TYPE(default:038000)CORE_CREDITO_RES_MSG_CODE(default:0370)
EMCALI (1 var)
EMCALI_MEMBRESIAS_API_URL
Slack (3 vars, ninguna en .env.example)
SLACK_BOT_USER_OAUTH_TOKEN— referenciada desdeconfig/services.phpSLACK_BOT_USER_DEFAULT_CHANNEL— referenciada desdeconfig/services.phpLOG_SLACK_WEBHOOK_URL— referenciada desdeconfig/logging.php(canal de log Slack; no esta enLOG_STACK=single)