Webhook de API de verificación de identidad: persiste el estado antes de esperar
Tu servicio de alta crea una sesión de verificación alojada y espera un webhook. Mientras espera pueden fallar dos cosas: el proceso se reinicia o la llamada de retorno nunca llega. Si el estado pendiente solo vive en memoria, un reinicio lo pierde. Si nada impone un plazo, una llamada ausente deja al usuario bloqueado, o alguien se siente tentado a interpretar el silencio como éxito. Este artículo recorre las ramas comprobadas de reinicio local y de llamada ausente del ejemplo sintético verification_delivery, muestra las salidas exactas del fixture y te ayuda a decidir si una integración de sandbox encaja con tu tarea. El fixture solo acepta llamadas sintéticas y expira sesiones localmente; nunca consulta a un proveedor.
curl https://gridzen.ai/console/api/quickstart/trial \
-H 'Content-Type: application/json' \
-d '{"task": "identity_onboarding", "scenario": "success"}'El problema y la decisión
Un webhook de una API de verificación de identidad es una promesa asíncrona: el proveedor comunicará el resultado más tarde. Tu aplicación es responsable de todo lo que ocurre antes. La decisión es concreta: dónde vive el estado pendiente, qué plazo se aplica y qué ocurre cuando vence sin llamada. La regla de la guía es breve. Persiste el estado pendiente y un plazo. Recupera con reintentos acotados, una actualización de estado autorizada o revisión humana. Nunca conviertas una llamada ausente en aprobación. El ejemplo descargable demuestra la persistencia y la expiración local de esa regla. No demuestra la validación de firmas del proveedor ni la conciliación de estado, que una implementación de producción necesita por separado.
Qué implementa realmente el fixture
El ejemplo guarda las sesiones en SQLite. Llamar a create escribe una fila con estado pending y un deadline igual a now más timeout; con los valores por defecto es 0 más 60, es decir, deadline 60. Los identificadores deben empezar por fixture-, y el hosted_link devuelto apunta a un dominio de ejemplo inválido con link_executable false. El método event solo acepta mode synthetic_fixture y source fixture_callback; cualquier otro valor lanza PRODUCTION_SIGNATURE_VERIFIER_NOT_IMPLEMENTED. El método recover marca la sesión como expired cuando su deadline es menor o igual al tiempo indicado y su estado sigue siendo pending, review o unknown. Devuelve provider_polled false: la recuperación es una comparación de reloj local, no una consulta al proveedor. Cualquier permiso registrado aquí es una marca local del fixture; live_permission_changed siempre es false, y un permiso sintético nunca es un permiso de negocio real.
Escenario hipotético: reinicio y después silencio
Hipotéticamente, un vendedor inicia el alta en el tiempo 0. Tu servicio llama a create, obtiene la sesión fixture-session y la guarda como pending con deadline 60. En el tiempo 20 el proceso se reinicia. Como el estado está en SQLite, el proceso reiniciado abre el mismo archivo de base de datos y llama a read. La salida esperada sigue mostrando status pending, deadline 60, permission_granted false y grant_count 0; no hace falta una sesión nueva, y volver a crear fixture-session fallaría por la clave primaria, lo cual indica que debes reanudar en lugar de duplicar. No llega ninguna llamada. En el tiempo 61 un trabajo programado llama a recover. Salida esperada del fixture: mode synthetic_fixture, session fixture-session, status expired, deadline 60, permission_granted false, grant_count 0, live_permission_changed false, policy_version 1, allow_action true, next review_or_authorized_provider_refresh, provider_polled false. allow_action true solo describe la configuración de política de la sesión; no concede nada. Si después de la expiración llega un evento sintético Approved tardío, la sesión sigue expired.
Manejo de fallos que sigue siendo tuyo
El fixture devuelve una acción siguiente; no la ejecuta. Tras la expiración, tu diseño propuesto debe elegir entre revisión humana y una actualización de estado autorizada contra el proveedor real, con intentos acotados y un resultado registrado. Mantén separados estos fallos. Un evento para una sesión cuyo tenant y subject no coinciden lanza BINDING_MISMATCH; trátalo como un problema de enrutamiento o seguridad, no como un rechazo. Una lectura de una sesión desconocida lanza SESSION_NOT_FOUND; no la recrees en silencio. Un evento duplicado devuelve el estado actual sin conceder de nuevo. Nunca interpretes expired como rechazo de la persona, ni como aprobación. En producción, la validación de firmas, la conciliación con el proveedor y las reglas de permisos del cliente siguen siendo trabajo aparte; este ejemplo no las establece, y un recorrido alojado real completo de una persona nueva sigue sin probarse.
Cómo ejecutar las ramas comprobadas
Descarga el ejemplo, extráelo y entra en el directorio verification_delivery. Requiere Python 3.10 o superior, sin credenciales ni red. La guía nombra dos pruebas concretas, test_restart y test_timeout_recovery en test_delivery.DeliveryTests, además de la suite completa test_delivery, que cubre transiciones simuladas, vinculaciones, llamadas duplicadas, reinicio y plazos vencidos. La guía también muestra una petición local a recover contra una dirección de loopback; esa prueba HTTP anónima separada no es lo mismo que las ramas descargables, y ninguna consulta a un proveedor. Que las pruebas pasen demuestra que el código local maneja estos estados. No demuestra éxito en producción ni adopción, y la disponibilidad de rutas reales requiere confirmación aparte.
Lista de aceptación
Antes de decidir que una integración de sandbox encaja con tu tarea, confirma cada punto. Las sesiones pendientes se escriben en almacenamiento duradero con un plazo antes de enviar cualquier enlace. Un proceso reiniciado reanuda la misma sesión desde la misma base de datos en lugar de crear un duplicado. Un trabajo de recuperación programado compara el deadline con la hora actual y pasa a expired las sesiones pending, review o unknown vencidas. La salida expirada lleva provider_polled false en el fixture, y tu ruta real de actualización está autorizada y acotada. Una llamada ausente nunca produce permission_granted true. Los eventos tardíos, duplicados o sin coincidencia se manejan sin nuevas concesiones. La validación de firmas y la conciliación con el proveedor figuran como trabajo de producción pendiente. Si estos puntos encajan con tus necesidades, ejecuta primero las pruebas sintéticas y después considera guardar una solicitud opcional de sandbox.
Ejecutar el ejemplo sintético comprobado
Descargue y extraiga https://gridzen.ai/downloads/verification-delivery.zip, entre en verification_delivery y ejecute con Python 3.10+. El ejemplo local no hace llamadas de red. Use una base nueva para otra prueba de identidad.
python3 delivery.py identity --db /tmp/gridzen-article-fixture.sqliteFuentes y alcance
https://gridzen.ai/guides/missing-verification-webhook/ https://gridzen.ai/guides/current-capabilities/ Basado en las fuentes comprobadas y el ejemplo local; las reglas propuestas son recomendaciones de diseño, no comportamiento de producción demostrado. Redacción asistida por IA con revisión independiente.
Probar por separado tres resultados del sandbox Crear una cuenta para continuar la integración
Una descarga no demuestra una ejecución correcta. Los ejemplos locales y el sandbox en línea se prueban por separado.