> ## 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.

# Guía de pruebas de Travel Rule en sandbox

> Prueba en sandbox la Travel Rule con el VASP de prueba de Didit: aceptar, rechazar, nombre distinto, inaccesible, timeout y wallet sin custodia.

Una aplicación de sandbox intercambia datos de Travel Rule con una sola contraparte: el **Didit Test VASP**, un VASP de prueba integrado en la plataforma. Responde a cada transferencia como tú le indiques, mediante el mismo código que gestiona una contraparte real, para que puedas observar cada estado, cada entrada de la cronología y cada webhook de un intercambio antes de pasar a producción.

Nada de lo que envías en sandbox sale de Didit. Nunca se establece contacto con ninguna red, destinatario de correo electrónico ni otro cliente de Didit, y no se cobra nada.

## Antes de empezar

1. Usa la clave de API de una aplicación de **sandbox**. Las aplicaciones de producción nunca se comunican con el VASP de prueba.
2. Activa Travel Rule con una razón social:

```bash theme={null}
curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_enabled": true, "legal_name": "Example CASP Sandbox"}'
```

3. Opcionalmente, suscribe un destino de webhook a `travel_rule.status.updated`. Sandbox lo entrega con la marca `"environment": "sandbox"`.

## El VASP de prueba de Didit

`GET /v1/sandbox/scenarios/` devuelve el perfil del VASP de prueba y todos los escenarios en su objeto `travel_rule`, para que tus pruebas lean los valores que activan cada escenario en lugar de incluirlos directamente en el código:

| Campo | Valor |
| - | - |
| `legal_name` | `Didit Test VASP` |
| `lei` | `DIDITESTVASP00000001`, con formato válido pero no registrado |
| `jurisdiction` | `GB` |
| `compliance_email` | Una dirección del dominio `didit.test`, a la que nunca se envía correo |
| `travel_address` | Una Travel Address de un host `.test`, a la que nunca se puede acceder |
| `network_codes` | Códigos de prueba que nunca se marcan |
| `default_scenario` | `accept` |
| `inbound_scenarios` | `["accept", "name_mismatch"]` |

Todos los valores son datos de prueba. El VASP de prueba no es miembro de ninguna red de Travel Rule, y ningún resultado en sandbox demuestra que se pueda llegar a una contraparte o red real.

## Escenarios salientes

Toda transacción `travelRule` saliente de una aplicación de sandbox que requiera un intercambio va al VASP de prueba. Elige el resultado con la dirección de la wallet del beneficiario (no distingue mayúsculas de minúsculas) o con un nombre de beneficiario de la forma `Didit Test VASP <suffix>`; si se indican ambos, prevalece la wallet. Si no se indica ninguno, o si el sufijo no figura en la tabla, la transferencia se completa (`accept`).

Una transferencia que no requiere intercambio nunca llega al VASP de prueba: una por debajo de tu `threshold_amount`, una a la propia wallet verificada de tu usuario y una cuya wallet de contraparte declaraste como wallet sin custodia. Un VASP de contraparte que tú o tu usuario final eligieron manualmente en el directorio se evalúa según las rutas que tendría una aplicación de producción: si su entrada tiene alguna (un endpoint `TRP` verificado, una red por la que envía tu aplicación o un contacto de cumplimiento), la transferencia va al VASP de prueba; si no tiene ninguna, la transferencia termina en `COUNTERPARTY_VASP_NOT_FOUND`, como ocurriría en una aplicación de producción.

| Escenario | Sufijo del nombre | Wallet (ETH) | Termina en |
| - | - | - | - |
| `accept` | ninguno | `0xc00c4cd93ff83953ce3347b33656d68ab8f35cfb` | `COMPLETED` y luego `FINISHED` cuando informas `payment_txn_id` |
| `decline` | `Decline` | `0x7694c5b0213859ef409107853a36ff7c85835f18` | `COUNTERPARTY_VASP_GENERAL_DECLINE` |
| `name_mismatch` | `Name Mismatch` | `0x501b7a0886e31f516aaf54fa99107d2377bd2d3e` | `COUNTERPARTY_MISMATCHED_DATA`, según tu regla de nombre (con `NONE` se completa) |
| `not_reachable` | `Not Reachable` | `0xf0e986c1a1c3ae41629bf5cdcee0a67dd1eb0cce` | `COUNTERPARTY_VASP_NOT_REACHABLE` tras el calendario real de reintentos (30 segundos y luego 2, 10, 30 y 60 minutos, alrededor de una hora y 45 minutos en total); después se puede reenviar |
| `timeout` | `Timeout` | `0xb63a1b1d4bee82d109332187cbf5b657eb7da498` | `EXPIRED` en la primera comprobación de vencimiento tras su plazo de un minuto, por lo que tarda unos 15 minutos; después se aplica tu `timeout_outcome` |
| `self_hosted` | `Self Hosted` | `0x33dcc2a7e69cf965f7f4eaf6ba657bcb078a2b65` | `UNCONFIRMED_OWNERSHIP` y luego `COMPLETED` cuando se registra la prueba de propiedad de la wallet |

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "sbx-tr-accept-001",
    "transaction_category": "travelRule",
    "transaction_details": {
      "direction": "outbound",
      "action_type": "transfer",
      "amount": "0.25",
      "currency": "ETH",
      "currency_kind": "crypto"
    },
    "subject": { "entity_type": "individual", "vendor_data": "user-042", "full_name": "Jane Doe" },
    "travel_rule_details": {
      "status": "AWAITING_COUNTERPARTY",
      "beneficiary_data": {
        "wallet_address": "0xc00c4cd93ff83953ce3347b33656d68ab8f35cfb",
        "name": "Carlos Ruiz"
      }
    }
  }'
```

El `rail` de la transferencia es `TEST_VASP`, y la lista de transferencias muestra `Didit Test VASP` como su VASP beneficiario. Síguela en los webhooks `travel_rule.status.updated` o consulta `GET /v3/transactions/{transaction_id}/`.

* **`name_mismatch`** compara el nombre del beneficiario que enviaste con el nombre del titular que devuelve el VASP de prueba, según tu regla de nombre para el tipo de entidad del beneficiario (`matching_rules.individual.name` o `matching_rules.company.name`, que siguen a `name_matching_strictness` hasta que las configures). La transferencia y la entrada de la cronología que la decidió incluyen `name_match` (con `compared_with: "counterparty_vasp"`) y `data_match` con `mismatched_fields: ["name"]`.
* **`not_reachable`** mantiene la transferencia en `AWAITING_COUNTERPARTY` mientras se reintenta, con `delivery.status` `RETRYING` y `last_error` `test VASP is not answering`, y luego la pasa a `COUNTERPARTY_VASP_NOT_REACHABLE`. Envía `{"action": "resend"}` después para ejecutarla de nuevo.
* **`self_hosted`** hace que el VASP de prueba responda que la wallet es sin custodia. Registra la prueba con el [widget de propiedad de wallet](https://docs.didit.me/es/transaction-monitoring/wallet-ownership-widget.md) (que se genera para ti mientras `auto_wallet_verification` está activado) o con [`POST .../travel-rule/ownership/`](https://docs.didit.me/es/management-api/travel-rule/confirm-ownership) y `{"confirmed": true}`: la wallet se añade a tu libreta de direcciones con el nombre del beneficiario y la coincidencia de nombre decide la transferencia. Si hay coincidencia, se completa y la wallet se marca como verificada; `{"confirmed": false}` la rechaza.

## Transferencias entrantes desde el VASP de prueba

Para probar el lado receptor, haz que el VASP de prueba te envíe una transferencia con `POST /v3/travel-rule/test-vasp/inbound/`. Indica una de las wallets de la [libreta de direcciones](https://docs.didit.me/es/transaction-monitoring/travel-rule.md#libreta-de-direcciones-de-wallets) de tu propia aplicación: la transferencia se resuelve por la misma ruta entrante que una real, contra tu libreta de direcciones, tu modo de propiedad y tus reglas de nombre.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "beneficiary_wallet_address": "0xYourDepositWallet",
    "scenario": "accept",
    "reference": "sbx-inbound-001"
  }'
```

| Campo | Descripción |
| - | - |
| `beneficiary_wallet_address` | Obligatorio, hasta 128 caracteres. Usa una de las wallets de tu propia libreta de direcciones: cualquier otra wallet se registra como `ON_HOLD`. |
| `scenario` | `accept` (predeterminado): el VASP de prueba indica al propio titular de la wallet. `name_mismatch`: indica a alguien cuyo nombre no coincide con el de ningún titular. |
| `chain`, `amount`, `currency` | Opcionales. Valores predeterminados: `ETH`, `1` y `ETH`. |
| `reference` | Opcional, hasta 128 caracteres. Si vuelves a enviar la misma `reference`, se devuelve la primera respuesta (`201`) y no se registra nada nuevo. |

La respuesta `201` incluye `transaction_id`, `txn_id`, `scenario`, `travel_rule_status`, `detail`, `test_vasp: true` y la transferencia `travel_rule`. Una aplicación en producción recibe `400` (`"The Didit Test VASP is only available on sandbox applications."`), cualquier otro `scenario` recibe `400` y una aplicación con Travel Rule desactivada recibe `409`.

| Tu registro de wallet | `accept` | `name_mismatch` |
| - | - | - |
| Ninguna en esa cadena | `ON_HOLD` | `ON_HOLD` |
| Propiedad no demostrada para tu [modo de propiedad](https://docs.didit.me/es/transaction-monitoring/travel-rule.md#modos-de-validación-de-la-propiedad) | `UNCONFIRMED_OWNERSHIP` | `UNCONFIRMED_OWNERSHIP` |
| Verificada | `COMPLETED` mientras `inbound_auto_accept` esté activado; de lo contrario, `ON_HOLD` | `COUNTERPARTY_MISMATCHED_DATA` (con la regla de nombre `NONE`, igual que `accept`) |

Resuelve una transferencia en espera con [`POST .../travel-rule/ownership/`](https://docs.didit.me/es/management-api/travel-rule/confirm-ownership), como harías con una real: `{"confirmed": true}` la completa y `{"confirmed": false}` la rechaza.

Un depósito que tú mismo informas con `POST /v3/transactions/` no es uno enviado por el VASP de prueba: permanece en `AWAITING_COUNTERPARTY` a la espera de su VASP de origen, y en su cronología se menciona el endpoint anterior. No dispara ningún webhook hasta que expira tras `confirmation_timeout_hours`. [`POST /v3/travel-rule/inbound/`](https://docs.didit.me/es/management-api/travel-rule/register-inbound) sigue resolviendo un registro posterior al depósito contra tu libreta de direcciones, igual que en una aplicación en producción.

## Webhooks en sandbox

`travel_rule.status.updated` se dispara para las aplicaciones de sandbox en cada cambio de estado, con `"environment": "sandbox"`. Una transferencia a la que respondió el VASP de prueba incluye además `rail: "TEST_VASP"`, `test_vasp: true` y `test_vasp_scenario`. El resto del sandbox se sigue comportando como se describe en [Monitorización de transacciones en sandbox](https://docs.didit.me/es/integration/sandbox-testing.md#monitorización-de-transacciones-en-sandbox): las reglas no se evalúan, `transaction.created` y `transaction.status.updated` no se envían y no se factura nada.

## Lo que el sandbox no demuestra

* Que una contraparte real, una membresía de red o el host TRP público de Didit funcionen. No se contacta con ninguno de ellos.
* Que tus credenciales de red sean válidas. Una membresía conectada se demuestra con su primer intercambio en producción.
* Las rutas del [directorio](https://docs.didit.me/es/transaction-monitoring/travel-rule.md#directorio) de VASP reales: en una aplicación de sandbox, todas las rutas indican `unavailable` con `reason: sandbox_application`, y todas las filas, `reachable: false`.

Consulta [Redes de Travel Rule](https://docs.didit.me/es/transaction-monitoring/travel-rule-networks.md) para ver a qué llega cada red en producción actualmente.


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