Postbacks de estado
Para: Lenders (equipo de integración)
Resumen
Sección titulada «Resumen»Cuando un consumidor solicita uno de tus productos a través de Prosperas, vos procesás esa solicitud de tu lado (la aprobás, desembolsás los fondos o la rechazás). Un postback es la forma en que le contás a Prosperas qué pasó, casi en tiempo real, para que podamos actualizar el estado del lead, conciliar el revenue y mantener sincronizada la experiencia del consumidor.
La integración es deliberadamente chica: un endpoint, una credencial, un formato de payload.
| Propiedad | Valor |
|---|---|
| Dirección | Vos → Prosperas (vos nos llamás) |
| Endpoint | POST {BASE_URL}/client_app/webhook/lender/loan-status |
| Autenticación | Header X-API-KEY (recomendado) o IP allowlist |
| Formato del body | JSON, snake_case |
| Eventos | application, approval, disbursement, rejected |
| Éxito | 200 OK con un acknowledgement en JSON |
| Reintentos | Vos reintentás ante 5xx / errores de red (nosotros no te reintentamos) |
Autenticación
Sección titulada «Autenticación»Todo postback tiene que autenticarse. Prosperas revisa primero la API key, y después la IP de origen. Si ninguna de las dos coincide con una credencial registrada, la solicitud se rechaza con 403.
API key (recomendado)
Sección titulada «API key (recomendado)»Enviá tu key en el header HTTP:
X-API-KEY: <tu-key>- El nombre del header no distingue mayúsculas/minúsculas (
X-API-KEY,x-api-key,X-Api-Keyfuncionan igual). - La key se valida por coincidencia exacta de string. Sin prefijo, sin
Bearer, sin encoding.
IP allowlist (alternativa)
Sección titulada «IP allowlist (alternativa)»Si te provisionaron por IP, no hace falta ningún header — leemos tu IP de origen desde X-Forwarded-For, después X-Real-IP, y por último el socket peer.
- La coincidencia es por string exacto contra la IP que registramos.
- No soportamos rangos CIDR / subnets. Cada IP de salida individual que uses tiene que estar registrada. Si tu infraestructura rota IPs, usá el método de API key en su lugar.
La regla del “el lead tiene que existir”
Sección titulada «La regla del “el lead tiene que existir”»La autenticación no depende solo de la credencial — también está atada a un lead real. Una solicitud es exitosa solo cuando se cumplen todas estas condiciones:
- Tu credencial (key o IP) coincide con un origen de lender registrado, y
- el
click_idde la solicitud resuelve a un lead, y - ese lead pertenece a un producto que es de tu cuenta de lender.
Si tu credencial es válida pero el click_id no resuelve a uno de tus leads, igual vas a recibir 403 (no 404). En la práctica esto significa: un click_id incorrecto, desconocido o ajeno devuelve 403.
El identificador de tracking (click_id)
Sección titulada «El identificador de tracking (click_id)»click_id es el identificador único que conecta el journey del consumidor entre Prosperas y tus sistemas.
- Prosperas lo genera y te lo entrega en el momento en que redirige al consumidor hacia vos (como identificador de tracking/click en la URL de handoff).
- Tenés que guardarlo y devolverlo exactamente igual en cada postback de esa solicitud.
- No contiene datos personales; es una referencia opaca.
Formatos aceptados:
| Formato | Ejemplo | Notas |
|---|---|---|
| UUID simple | 7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e |
|
orgname_UUID |
claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e |
Exactamente un guion bajo |
Más de un guion bajo, o un UUID que no se pueda parsear, devuelve 400.
Contrato de la solicitud
Sección titulada «Contrato de la solicitud»Método: POST (recomendado). Existe una variante GET con los mismos campos como query parameters, pero POST con body JSON es el método server-to-server soportado.
Headers:
Content-Type: application/jsonX-API-KEY: <tu-key>Body (JSON, snake_case):
{ "click_id": "claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e", "event": "approval", "occurred_at": "2026-07-01T12:34:56Z", "data": { "provider": "tu-marca", "client": { "email": "consumidor@example.com", "fullName": "Ana Gomez", "firstName": "Ana", "lastName": "Gomez", "idNumber": "1234567890", "phoneNumber": "3001234567", "returningCustomer": false } }}Referencia de campos
Sección titulada «Referencia de campos»| Campo | Tipo | Requerido | Notas |
|---|---|---|---|
click_id |
string | Sí | El identificador de tracking. Devolvelo exactamente igual. |
event |
string | Sí | Uno de application, approval, disbursement, rejected. Solo minúsculas — en mayúsculas se rechaza con 422. |
occurred_at |
string | — | Timestamp ISO-8601 de cuándo ocurrió el evento de tu lado (ej. 2026-07-01T12:34:56Z). |
data |
object | — | Blob de auditoría opcional. Claves reconocidas: provider (string) y client (object, ver abajo). |
data.client |
object | — | Datos opcionales del consumidor. Ver sección siguiente. |
El objeto data.client (opcional)
Sección titulada «El objeto data.client (opcional)»data.client te permite enriquecer el registro del consumidor. Todos los campos son opcionales.
| Campo | Tipo | Notas |
|---|---|---|
email |
string | |
firstName |
string | Se usa solo si fullName no está presente. |
lastName |
string | Se usa solo si fullName no está presente. |
fullName |
string | Tiene prioridad: primer token → nombre, resto → apellido. |
idNumber |
string | Número de documento / cédula. |
phoneNumber |
string | |
returningCustomer |
boolean | Por defecto es false si se omite. Ver la advertencia abajo. |
Eventos y ciclo de vida
Sección titulada «Eventos y ciclo de vida»Enviá un postback por cada transición de estado, usando el evento que corresponda a lo que pasó:
event |
Significado | ¿Requerido? |
|---|---|---|
application |
Se recibió / inició la solicitud del consumidor de tu lado. | Opcional |
approval |
La solicitud fue aprobada. | Sí |
disbursement |
Se desembolsaron los fondos. | Sí |
rejected |
La solicitud fue rechazada. | Sí |
application se acepta pero es opcional — enviálo si tenés un hito significativo de “solicitud recibida”; si no, los tres resultados terminales (approval, disbursement, rejected) son lo que más importa.
Enviá los eventos en el orden en que ocurren. Prosperas tolera eventos que llegan desordenados, pero la entrega en orden mantiene limpio el historial del lead.
Respuestas y códigos de estado
Sección titulada «Respuestas y códigos de estado»Body de éxito (200 OK):
{ "ok": true, "lead_id": 12345, "status": "APPROVAL", "user_id": 6789}ok— siempretrueen caso de éxito.lead_id— el lead de Prosperas contra el cual se registró el evento.status— el estado interno al que mapeó tu evento (APPLICATION/APPROVAL/DISBURSEMENT/REJECTED).user_id— el id del registro del consumidor, cuando está disponible.
Códigos de estado:
| Código | Significado | Qué hacer |
|---|---|---|
200 |
Evento registrado. | Listo. |
400 |
click_id mal formado (UUID inválido o demasiados guiones bajos). |
Corregí el click_id; no reintentes sin cambios. |
403 |
Falló la autenticación o el click_id no resuelve a uno de tus leads. |
Revisá tu key/IP y que estés devolviendo el click_id correcto. No reintentes a ciegas. |
404 |
Sesión no encontrada (caso raro, ocurre después de que la autenticación fue exitosa). | Verificá el click_id; contactá a Prosperas si persiste. |
422 |
Error de validación — ej. clickId en camelCase, evento en mayúsculas, tipos incorrectos. |
Corregí la forma del payload (ver sección de errores comunes). No reintentes sin cambios. |
5xx |
Error transitorio del lado de Prosperas. | Reintentá con backoff exponencial (ver sección de reintentos). |
Errores comunes (leé esto antes de integrar)
Sección titulada «Errores comunes (leé esto antes de integrar)»Estos cuatro errores explican casi todas las integraciones fallidas en su primer intento. Evitalos:
| ❌ No hagas esto | ✅ Hacé esto |
|---|---|
Usar clickId en camelCase en el body |
Usá snake_case click_id — camelCase → 422 |
Enviar event: "APPROVAL" (mayúsculas) |
Enviá minúsculas approval — mayúsculas → 422 |
| Asumir que el endpoint es público / sin auth | Enviá X-API-KEY (o llamá desde una IP en la allowlist) — si no, 403 |
| Poner la API key en un query string o esperar que un pixel se autentique | Enviá la key en el header X-API-KEY en un POST |
Reintentos y garantías de entrega
Sección titulada «Reintentos y garantías de entrega»- Los reintentos son tu responsabilidad. Prosperas no te reintenta. Ante un
5xxo un error de red, reintentá el postback con backoff exponencial (ej. 1s, 2s, 4s, 8s…), hasta un límite razonable. - No reintentes ante
4xx. Un400,403o422significa que la solicitud está mal — corregila y enviá una solicitud corregida en lugar de insistir con el mismo payload. - El endpoint no es idempotente. Cada postback aceptado registra un evento nuevo. Si reintentás después de una solicitud que en realidad tuvo éxito (pero cuya respuesta no recibiste), podés generar un evento duplicado. Mantené los reintentos acotados y priorizá reintentar solo ante fallas confirmadas.
- Cada solicitud queda registrada de nuestro lado (con tu API key enmascarada) para soporte y conciliación.
Ejemplos prácticos
Sección titulada «Ejemplos prácticos»Caso exitoso — aprobación (POST)
Sección titulada «Caso exitoso — aprobación (POST)»curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \ -H "Content-Type: application/json" \ -H "X-API-KEY: <tu-key>" \ -d '{ "click_id": "claro_7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e", "event": "approval", "occurred_at": "2026-07-01T12:34:56Z", "data": { "provider": "tu-marca" } }'Respuesta — 200 OK:
{ "ok": true, "lead_id": 12345, "status": "APPROVAL", "user_id": 6789 }Desembolso con enriquecimiento de datos del consumidor (POST)
Sección titulada «Desembolso con enriquecimiento de datos del consumidor (POST)»curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \ -H "Content-Type: application/json" \ -H "X-API-KEY: <tu-key>" \ -d '{ "click_id": "7e1c2f1f-9b4d-4c1d-9f6c-2f3c1a2b4d5e", "event": "disbursement", "occurred_at": "2026-07-01T15:00:00Z", "data": { "provider": "tu-marca", "client": { "fullName": "Ana Gomez", "idNumber": "1234567890" } } }'Error — campo en camelCase (422)
Sección titulada «Error — campo en camelCase (422)»# INCORRECTO: "clickId" (camelCase) en lugar de "click_id"curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \ -H "Content-Type: application/json" \ -H "X-API-KEY: <tu-key>" \ -d '{ "clickId": "7e1c2f1f-...", "event": "approval" }'# → 422 Unprocessable Entity (el campo "click_id" es requerido)Error — credencial faltante o incorrecta (403)
Sección titulada «Error — credencial faltante o incorrecta (403)»# Sin header X-API-KEY y con una IP que no está en la allowlist → 403curl -X POST "{BASE_URL}/client_app/webhook/lender/loan-status" \ -H "Content-Type: application/json" \ -d '{ "click_id": "7e1c2f1f-...", "event": "approval" }'# → 403 ForbiddenReferencia rápida
Sección titulada «Referencia rápida»| Endpoint | POST {BASE_URL}/client_app/webhook/lender/loan-status |
| Header de auth | X-API-KEY: <tu-key> (no distingue mayúsculas/minúsculas) |
| Campos requeridos del body | click_id (snake_case), event (minúsculas) |
| Eventos | application · approval · disbursement · rejected |
| Campos opcionales del body | occurred_at (ISO-8601), data, data.client |
| Éxito | 200 → { ok, lead_id, status, user_id } |
| Errores del cliente | 400 click_id inválido · 403 auth/lead · 404 sesión · 422 validación |
| Reintentar ante | Solo 5xx / red, con backoff exponencial |
| Firma | Ninguna (sin HMAC) — protegé la API key |
Notas importantes
Sección titulada «Notas importantes»Siguiente paso: con los postbacks funcionando, cerrá la integración con los Datos de producto.
Última verificación: 2026-07-01 · v1.1 · coincide con Lender-Postback-Integration-Guide.md