> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Solución de problemas de KYT: errores y soluciones

> Resuelve errores de KYT en Didit: colisiones de txn_id, reglas que no se activan, timeouts de AML, firmas de webhook inválidas y divisas.

Referencia de los problemas habituales de Monitorización de transacciones, con su síntoma, su causa y su solución.

## Error de `txn_id` duplicado

**Síntoma.** Al enviar una transacción se devuelve `400` con `A transaction with this transaction_id already exists.` en el campo `transaction_id`, o `409` cuando dos solicitudes idénticas compiten entre sí.

**Causa.** `txn_id` (el `transaction_id` que envías) es único por aplicación.
Didit rechaza una segunda transacción con el mismo `transaction_id` y no devuelve el registro existente.

**Solución.**

* Genera `txn_id` de forma determinista en tu sistema (por ejemplo, usa el ID de la transacción en tu propia base de datos).
* Si recibes un `400` o un `409` por un `transaction_id` duplicado durante un reintento, consulta la transacción existente en lugar de volver a enviarla: léela con [`GET /v3/transactions/{uuid}/`](https://docs.didit.me/es/management-api/transactions/get) usando el `uuid` de la primera respuesta, o usa el `transaction_id` (el uuid de Didit) que el webhook `transaction.created` incluye junto a tu `txn_id`.
* Si la solicitud no era un reintento, asigna a la nueva transacción su propio `transaction_id`.

## La regla no se dispara

**Síntoma.** Creaste una regla que debería coincidir, pero ninguna transacción la muestra en `rule_runs[]` con `matched: true`.

**Causas y soluciones.**

* **La aplicación está en modo sandbox**: una aplicación en sandbox omite la evaluación de reglas, el análisis AML, la facturación y los webhooks `transaction.created` y `transaction.status.updated`. Los intercambios de Travel Rule siguen ejecutándose cuando están habilitados, contra el [VASP de prueba de Didit](https://docs.didit.me/es/transaction-monitoring/travel-rule-sandbox.md), y entregan webhooks `travel_rule.status.updated` marcados con `environment: sandbox`. `rule_runs` se devuelve vacío y la puntuación se queda en `0`, sea cual sea el modo de tus reglas, y la transacción permanece en `APPROVED` salvo que una transferencia de Travel Rule que expira aplique tu `timeout_outcome`. Revisa `environment` en la respuesta de la transacción: `"sandbox"` significa que nunca se evaluó. Consulta [Monitorización de transacciones en sandbox](https://docs.didit.me/es/integration/sandbox-testing.md#monitorización-de-transacciones-en-sandbox) para saber cómo validar una regla antes de que pase a producción.
* **El modo de la regla es `DISABLED` o `TEST`**: revisa *Rules → \[regla] → Mode*. Solo las reglas `ACTIVE` contribuyen a la puntuación; las reglas `TEST` se evalúan, pero no afectan al estado.
* **El filtro de alcance excluye la transacción**: por ejemplo, un alcance configurado como `transaction_type = finance` no coincidirá con transacciones `travelRule`.
* **La ventana de agregación es más corta de lo necesario**: una regla de "20 transacciones en 30 días" no coincidirá después de solo 15 transacciones.
* **El campo de la condición es nulo**: por ejemplo, tu regla comprueba `counterparty.country_code`, pero no enviaste una contraparte.
* **Conversión de divisas**: los umbrales de la regla se aplican sobre `amount_in_default_currency`; si la divisa predeterminada de tu aplicación es distinta de la divisa de la transacción, el importe convertido puede quedar por debajo del umbral.

Usa la función *Rules → \[regla] → Backtest* para volver a ejecutar una transacción pasada y ver por qué la regla se disparó o no.

## La regla se dispara con todo

**Síntoma.** Una regla se dispara en el 90%+ de las transacciones y tu cola de revisión se satura.

**Causa.** Las condiciones son demasiado amplias o los umbrales demasiado bajos.

**Solución.**

* Añade filtros de `scope` para acotar su aplicación (por ejemplo, solo salientes o solo ciertos tipos de transacción).
* Sube los umbrales (importes, recuentos de transacciones en un periodo determinado).
* Pon la regla en modo `TEST` durante una semana: analiza los `rule_runs` para ver la tasa de coincidencia y ajusta las condiciones antes de volver a habilitarla.

## Se agotó el tiempo del análisis cripto

**Síntoma.** La transacción se completó con `status: APPROVED`, pero el array `provider_results[]` muestra `status: FAILED` para una wallet, un hash de transacción o un proveedor de análisis cripto.

**Causas.**

* La API del proveedor no estuvo disponible temporalmente.
* La consulta superó el tiempo de espera (normalmente \~10 s).

**Solución.**

* Las transacciones nunca fallan por problemas de un proveedor: el enriquecimiento se hace en la medida de lo posible.
* Si un proveedor concreto falla repetidamente, revisa su página de estado o abre un ticket de soporte.
* Considera configurar las preferencias de proveedores en *Settings → Transaction Monitoring → Providers* para redirigir a proveedores alternativos.

## Falta el enriquecimiento de IP

**Síntoma.** El `applicant.ip_enrichment` de una transacción no aparece o está incompleto.

**Causas.**

* No hay `applicant.device.ip` en el envío.
* La IP es privada o reservada (no enrutable).
* Todos los proveedores de enriquecimiento no estuvieron disponibles temporalmente.

**Solución.**

* Captura la IP de quien envía en tu cliente o servidor y pásala en cada transacción.
* Usa solo IP enrutables: Didit omite sin avisar los rangos privados.
* Revisa *Settings → Status* en la consola para ver el estado de los proveedores.

## La firma del webhook no coincide

**Síntoma.** Tu endpoint rechaza los eventos porque la firma no coincide.

**Causas.**

* Se modificó el cuerpo sin procesar (el JSON se volvió a serializar con otros espacios en blanco).
* El secreto es incorrecto.
* Hay varios destinos con la misma URL: las firmas son distintas para cada destino.

**Solución.**

* **Calcula la firma sobre el cuerpo sin procesar de la solicitud**, no sobre el JSON ya interpretado. Muchos frameworks ofrecen un middleware para el cuerpo sin procesar.
* Rota el secreto si se ha visto comprometido: *Webhook destinations → \[destino] → Rotate secret*.
* Mantén un solo destino por URL para no confundir los secretos.

## El webhook no llega

**Síntoma.** Se están creando transacciones, pero los webhooks nunca llegan.

**Causas.**

* El campo `enabled` del destino es `false`.
* La URL no es accesible públicamente.
* El destino se deshabilitó automáticamente tras fallos repetidos.
* El evento no está en `subscribed_events`.

**Solución.**

* Envía un evento de prueba: *Webhook destinations → \[destino] → Send test*.
* Revisa las entregas recientes: *Webhooks → \[destino] → Deliveries*. Ahí verás las respuestas 4xx/5xx con su cuerpo y sus encabezados.
* Vuelve a habilitar los destinos deshabilitados.

## La conversión de divisas parece incorrecta

**Síntoma.** `amount_in_default_currency` no coincide con el tipo de cambio que esperas.

**Causas.**

* El tipo de cambio es el tipo medio de mercado en `txn_date`.
* Las transacciones con fecha retroactiva usan el tipo histórico de esa fecha.
* Algunas divisas (divisas exóticas) tienen intervalos de actualización más largos.

**Solución.**

* Usa `amount` y `currency` (nativos) para mostrar los importes.
* Usa `amount_in_default_currency` solo para los umbrales internos de las reglas.
* Para auditoría, el registro de la transacción fija el tipo de conversión utilizado en el momento de la evaluación.

## La contraparte no coincide con mi lista de bloqueo

**Síntoma.** Añadiste una empresa a la lista de bloqueo por `vendor_data`, pero una transacción con esa contraparte se procesó igualmente.

**Causas.**

* La contraparte del payload de la transacción no incluye `vendor_data`, así que se almacena como una instantánea externa.
* Las mayúsculas y minúsculas de `vendor_data` no coinciden.

**Solución.**

* Pasa siempre `counterparty.vendor_data` cuando la contraparte sea una entidad de tu plataforma.
* Usa las mismas mayúsculas y minúsculas en todas partes: `vendor_data` distingue entre mayúsculas y minúsculas.

## Transacciones AWAITING\_USER bloqueadas

**Síntoma.** Hay transacciones bloqueadas en `AWAITING_USER` porque el usuario nunca completa la sesión de remediación.

**Causas.**

* El usuario no abrió la URL de la sesión de remediación.
* La sesión de remediación expiró.
* La transacción es una transferencia de Travel Rule que una regla de la biblioteca, como `travel-rule-pending-action`, movió a `AWAITING_USER`: Didit no crea su sesión de remediación predeterminada para una transacción de Travel Rule, así que, a menos que la regla indique su propio flujo de remediación, no hay ningún enlace que entregar.

**Solución.**

* El `remediation_session_url` de la respuesta de la transacción es el enlace que debes entregar. Vuelve a enviárselo al usuario.
* En una transacción de Travel Rule, resuelve la transferencia desde su pestaña **Travel rule** y después cambia tú mismo el estado de la transacción, porque resolver la transferencia no saca por sí solo la transacción de `AWAITING_USER`.
* Las sesiones de remediación siguen el mismo patrón que la [guía de inicio rápido de KYC](https://docs.didit.me/es/getting-started/quick-start.md): suscríbete a los webhooks de finalización.
* Configura un tiempo de espera en tu propio sistema para que las transacciones obsoletas expiren si la remediación nunca se completa.

## Límite de solicitudes al crear

**Síntoma.** `429 Too Many Requests` durante picos de alto volumen.

**Solución.**

* Respeta el encabezado `Retry-After`.
* Limita la velocidad de las solicitudes desde el cliente para el tráfico en ráfagas.
* Contacta con soporte para obtener límites más altos si tienes un volumen de producción demostrado.

Consulta [límites de solicitudes](https://docs.didit.me/es/integration/rate-limiting.md).

## Próximos pasos

> [card] [Guía de integración](https://docs.didit.me/es/transaction-monitoring/integration-guide.md)
>
> Patrones de integración completos.

> [card] [Reglas](https://docs.didit.me/es/transaction-monitoring/rules.md)
>
> Cómo funciona la evaluación de reglas.

> [card] [Webhooks](https://docs.didit.me/es/transaction-monitoring/webhooks.md)
>
> Funcionamiento de los webhooks.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.