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

# Dati di test sandbox: scenari, valori magici e documenti

> Testa Didit in sandbox: scenari, valori magici, endpoint arm, documenti di esempio e codici OTP per esiti deterministici, senza PII né fatturazione.

La **sandbox** di Didit è l'equivalente delle carte di test di Stripe o dei modelli di documenti di Sumsub: consente di riprodurre in modo deterministico qualsiasi esito della verifica, senza interagire con provider reali, dati personali reali o il saldo.

> [!NOTE]
>
> La fonte di riferimento per questi dati è `serialize_catalog()` nel servizio di verifica, disponibile in tempo reale all'indirizzo `GET /v1/sandbox/scenarios/`. Una copia verificata tramite test di drift viene generata in `docs/sandbox/SANDBOX_REFERENCE.md` nel repository `service-didit-verification` con `pipenv run python scripts/generate_sandbox_reference.py`. Questa pagina riflette tale riferimento: se qualcosa qui sembra obsoleto, fai sempre riferimento all'endpoint del catalogo in tempo reale. L'endpoint del catalogo richiede autenticazione: invia la tua chiave API (`x-api-key`) come faresti per qualsiasi altra chiamata, oppure un token di sessione se lo leggi dall'interno di una sessione in esecuzione.

## Modello dell'ambiente

La **sandbox** è una **modalità per applicazione** (`ApplicationDetail.mode == SANDBOX`), la stessa logica della modalità test di Stripe. Mentre una sessione è in esecuzione con un'applicazione sandbox:

* Ogni provider esterno (OCR, AML, confronto facciale, liveness, NFC, telefono, email, IP, POA, validazione su database, document AI) è **simulato**: nessuna terza parte viene mai chiamata.
* **La liveness funziona esattamente come in produzione.** Un workflow di liveness attiva esegue la vera acquisizione attiva anche in sandbox, sia nel flusso ospitato sia nel passaggio web degli SDK nativi, così puoi testare l'esperienza che avranno i tuoi utenti. Viene simulato solo il *risultato* della liveness, tramite lo scenario o il valore magico, e il report registra il metodo configurato nel tuo workflow.
* **I domini personalizzati sono disponibili solo in produzione.** Un'applicazione sandbox non può aggiungere un [dominio personalizzato](https://docs.didit.me/it/console/custom-domain.md); le sessioni sandbox usano sempre il dominio predefinito della verifica ospitata.
* Le sessioni **non vengono mai fatturate** e il controllo del saldo viene saltato.
* Per ogni applicazione è applicato un limite di **500 creazioni di sessione / 24h**.
* I webhook contengono `"environment": "sandbox"` (le sessioni in produzione contengono `"environment": "live"`).
* Il flusso ospitato espone l'ambiente della sessione, così l'interfaccia può avvisare gli utenti di non caricare dati personali reali.
* **Gli esiti non dipendono mai dai pixel**: i dati estratti e gli stati provengono dallo scenario o dal valore magico. I media acquisiti (documenti, selfie, video, file POA) vengono comunque salvati davvero, esattamente come in una sessione di produzione.

## Monitoraggio delle transazioni nella sandbox

La sandbox è **modellata sulla sessione**: simula i provider che una sessione di verifica chiamerebbe. Il Monitoraggio delle transazioni non ha un provider da simulare, quindi un'applicazione sandbox segue l'altra strada: la transazione viene salvata, ma **nulla di ciò che decide, esegue lo screening, notifica o addebita viene eseguito su di essa**.

Una transazione creata su un'applicazione sandbox viene salvata e restituita come di consueto, e non accade nulla di quanto segue:

* **Nessuna valutazione delle regole.** `rule_runs` è vuoto, qualunque sia la modalità delle tue regole. Una regola `ACTIVE` su un'applicazione sandbox non si attiva mai, quindi la transazione resta `APPROVED` con punteggio `0` e non viene aperto alcun alert o caso.
* **Nessuno screening AML / wallet.** `provider_results` è vuoto anche per le transazioni in crypto su un'applicazione con il monitoraggio abilitato.
* **Nessun webhook.** Né `transaction.created` né `transaction.status.updated` vengono consegnati per una transazione sandbox.
* **Nessuna fatturazione.** Viene registrato un evento di utilizzo al prezzo `0.0000` e il tuo saldo non cambia.

Ogni risposta di transazione contiene un campo `environment` (`"live"` o `"sandbox"`), così un `rule_runs` vuoto non è mai ambiguo: `"sandbox"` significa che le regole non sono state valutate, non che nessuna di esse ha corrisposto. La Business Console dice lo stesso nella scheda *Risk & decision* della transazione, invece di un semplice "No rules evaluated".

> [!NOTE]
>
> **La Travel Rule è l'unica eccezione a "nulla viene eseguito".** Su un'applicazione con la Travel Rule abilitata, una transazione `travelRule` in sandbox esegue comunque il motore di scambio: il record del trasferimento viene creato e passa attraverso i suoi stati.
> Ciò che la sandbox non fa mai è comunicare con qualcuno al di fuori di Didit.
> L'unica controparte è il [Didit Test VASP](https://docs.didit.me/it/transaction-monitoring/travel-rule-sandbox.md), integrato nella piattaforma: nessun messaggio di compliance raggiunge una VASP controparte reale su nessun canale (`TRP`, un'appartenenza alla rete che hai collegato, email o `INTERNAL`), il controllo di attribuzione della VASP controparte viene saltato e un annullamento non invia nulla a una controparte.
> I webhook `travel_rule.status.updated` vengono consegnati, contrassegnati con `"environment": "sandbox"`.
>
> **In uscita** - una transazione `travelRule` che invii.
> Il controllo `threshold_amount` viene eseguito per primo, e in sandbox si applica solo quando invii `transaction_details.amount_in_default_currency`, perché la sandbox non converte le valute; senza questo campo ogni trasferimento sandbox risulta sopra la soglia.
> Un trasferimento senza risposta scade dopo `confirmation_timeout_hours`, e il tuo `timeout_outcome` si applica poi alla transazione.
> Sopra la soglia, il controllo sul wallet in autocustodia si applica normalmente: un trasferimento verso un [wallet in autocustodia dichiarato](https://docs.didit.me/it/transaction-monitoring/travel-rule.md#wallet-in-autocustodia-dichiarati) passa a `UNCONFIRMED_OWNERSHIP` senza alcun invio, e puoi completarlo in sandbox tramite il [widget di verifica della proprietà del wallet](https://docs.didit.me/it/transaction-monitoring/wallet-ownership-widget.md), oppure tramite [confermare la proprietà](https://docs.didit.me/it/management-api/travel-rule/confirm-ownership.md) quando il wallet di destinazione è già nella tua rubrica degli indirizzi.
> Ogni altro trasferimento sopra la soglia va al Didit Test VASP sul rail `TEST_VASP`, che gli risponde all'interno di Didit con lo scenario che scegli tramite wallet o nome del beneficiario: viene completato, rifiutato, non corrisponde, diventa `COUNTERPARTY_VASP_NOT_REACHABLE`, scade (il tuo `timeout_outcome` si applica poi alla transazione) oppure attende la proprietà del wallet.
> Vedi [Test della Travel Rule in sandbox](https://docs.didit.me/it/transaction-monitoring/travel-rule-sandbox.md) per tutti gli scenari.
>
> **In entrata** - `POST /v3/travel-rule/inbound/`. La registrazione non viene mai inviata tramite un rail, quindi non viene simulato nulla: la sandbox confronta il deposito con la tua rubrica degli indirizzi e lo regola in modo sincrono, esattamente come fa l'ambiente di produzione. Il risultato è un esito reale e non `AWAITING_COUNTERPARTY`: `ON_HOLD` (nessuna corrispondenza in rubrica), `UNCONFIRMED_OWNERSHIP` (la voce corrispondente non ha la proprietà verificata), `COUNTERPARTY_MISMATCHED_DATA` (il nome del beneficiario non corrisponde al titolare del wallet), oppure `COMPLETED` e poi `FINISHED` (corrispondenza con una voce verificata).
> Per ricevere un trasferimento dal Didit Test VASP, usa invece [Trigger Test VASP Inbound Transfer](https://docs.didit.me/it/management-api/travel-rule/trigger-test-vasp-inbound.md) con uno dei tuoi wallet in rubrica.

### Scenari Travel Rule Test VASP

Il catalogo `travel_rule.scenarios` elenca questi scenari in uscita. Imposta il nome del beneficiario indicato di seguito su una transazione `travelRule` in uscita dopo aver abilitato la Travel Rule sulla tua applicazione sandbox. I controlli sulla soglia e sul wallet in autocustodia dichiarato descritti sopra vengono eseguiti per primi.

| Scenario | Nome del beneficiario | Esito |
| - | - | - |
| `accept` | `Didit Test VASP` | `COMPLETED` |
| `decline` | `Didit Test VASP Decline` | `COUNTERPARTY_VASP_GENERAL_DECLINE` |
| `name_mismatch` | `Didit Test VASP Name Mismatch` | `COUNTERPARTY_MISMATCHED_DATA` |
| `not_reachable` | `Didit Test VASP Not Reachable` | `COUNTERPARTY_VASP_NOT_REACHABLE` dopo i tentativi di consegna |
| `timeout` | `Didit Test VASP Timeout` | `EXPIRED` quando il controllo di scadenza viene eseguito dopo la scadenza di un minuto |
| `self_hosted` | `Didit Test VASP Self Hosted` | `UNCONFIRMED_OWNERSHIP` |

Puoi anche scegliere uno scenario con l'indirizzo del wallet del beneficiario invece del nome (il wallet prevale quando sono impostati entrambi), e un trasferimento che non indica nessuno dei due viene completato come `accept`. [Test della Travel Rule in sandbox](https://docs.didit.me/it/transaction-monitoring/travel-rule-sandbox.md) elenca il wallet di ciascuno scenario e il suo esito esatto.

Il [trigger inbound del Test VASP](https://docs.didit.me/it/management-api/travel-rule/trigger-test-vasp-inbound.md) accetta solo `accept` e `name_mismatch` nel suo campo `scenario`.

> [!NOTE]
>
> **Come esercitare una regola prima che vada in produzione.** Usa [Backtest](https://docs.didit.me/it/transaction-monitoring/rules-api.md#creare-testare-con-backtest-attivare): riesegue la regola sulla cronologia reale delle tue transazioni e riporta `evaluated` / `matched` / `affected_entities` senza modificare lo stato di nessuna transazione. Abbinalo alla modalità `TEST` sull'applicazione in produzione: una regola `TEST` valuta ogni nuova transazione reale e registra ciò che avrebbe considerato corrispondente, senza cambiare punteggio o stato. Passa a `ACTIVE` quando la selettività ti sembra corretta.

## Come passare tra live e sandbox

Live e sandbox sono **applicazioni separate**, quindi il traffico di test e i dati di produzione non si mescolano mai. Ogni applicazione ha un `mode` pari a `live` o `sandbox`:

* Usa la chiave API di un'applicazione in modalità **sandbox** per ottenere sessioni fittizie, non fatturate e simulabili.
* Usa la chiave API di un'applicazione in modalità **live** per le verifiche reali.

Il campo `sandbox_scenario` (alla creazione della sessione e nell'API AML autonoma) e gli endpoint di simulazione sono accettati solo sulle applicazioni sandbox; vengono rifiutati sulle applicazioni live.

## Sandbox nel flusso di verifica ospitato

Le sessioni create in un'applicazione sandbox mostrano un'interfaccia aggiuntiva nel flusso di verifica ospitato (l'`url` restituito da `POST /v3/session/`):

* **Banner sandbox nella card.** Ogni schermata mostra un banner all'interno della card, con il testo "Solo dati di test - nessuna chiamata reale", così è sempre chiaro che la sessione non chiama mai provider reali e non tocca mai il tuo saldo. I contenuti acquisiti vengono memorizzati come per qualsiasi sessione, quindi usa i documenti di esempio e i dati di test anziché documenti d'identità reali o dati personali.
* **Selettore di scenario prima del flusso.** Prima che inizi l'acquisizione, un selettore nella card guida l'utente nella scelta di un esito di test: scegli un risultato, poi un trigger per quel risultato. La conferma chiama `POST /v3/session/{session_id}/sandbox/arm/` (vedi [Attivare (o riattivare) la sessione prima dell'avvio del flusso](#3-armare-o-riarmare-la-sessione-prima-dell’avvio-del-flusso) più sotto), poi prosegue nel flusso con i valori magici di quello scenario già applicati.
* **Striscia dei documenti di esempio.** Una riga di documenti di esempio della sandbox (fino a 3) si trova subito sotto il componente di caricamento o acquisizione dei documenti. Toccane uno per usarlo al posto di un caricamento reale.

Le sessioni sandbox memorizzano i **contenuti reali** acquisiti: documenti, selfie, video di rilevamento della vitalità e file di prova di residenza vengono caricati e conservati esattamente come per una sessione live. I dati *estratti* (campi di verifica dell'identità, punteggi di confronto facciale, risultati del rilevamento della vitalità e simili) e l'esito stesso della sessione (Approvata / In revisione / Rifiutata) sono simulati dallo scenario o dal valore magico, e non sono mai derivati dai contenuti acquisiti. La Business Console contrassegna le sezioni dei dati estratti di una sessione sandbox con un chip **Dati simulati**, così i revisori possono capire a colpo d'occhio quali parti della sessione sono l'acquisizione reale e quali sono guidate dallo scenario.

## Scenari

Ogni scenario è un insieme denominato di valori magici. Passa il suo slug come `sandbox_scenario` alla creazione della sessione (o all'endpoint di simulazione) per riprodurre l'esito.

| Slug | Titolo | Stato predefinito | Descrizione |
| - | - | - | - |
| `approve` | Percorso ideale: tutte le funzionalità danno esito positivo | Approvata | Comportamento predefinito della sandbox: ogni funzionalità simulata restituisce il suo esito APPROVED senza anomalie. La sessione termina con stato APPROVED. |
| `decline_aml_hit` | AML: persona politicamente esposta | Rifiutata | La simulazione AML restituisce un riscontro e la sessione viene rifiutata sulla funzionalità AML. Il riscontro usa lo stesso [schema Hit](https://docs.didit.me/it/core-technology/aml-screening/report-aml-screening.md#campi-per-singolo-riscontro) dei provider AML reali: `url`, `match_score`, `risk_score`, `review_status`, `properties`, `pep_matches[]` e `score_breakdown` sono tutti valorizzati, e viene scritto un Log di avviso POSSIBLE\_MATCH\_FOUND. |
| `decline_document_expired` | Verifica dell'identità: documento scaduto | Rifiutata | La simulazione della verifica dell'identità restituisce un passaporto la cui data di scadenza è nel passato. La sessione viene rifiutata sulla verifica dell'identità, con un Log di avviso DOCUMENT\_EXPIRED. |
| `decline_minimum_age` | Verifica dell'identità: sotto l'età minima prevista dalla politica | Rifiutata | La simulazione della verifica dell'identità restituisce una data di nascita che rende l'utente di circa 10 anni. Il controllo dell'età in produzione emette MINIMUM\_AGE\_NOT\_MET e il workflow rifiuta la sessione. |
| `decline_mrz_validation` | Verifica dell'identità: errore di checksum dell'MRZ | Rifiutata | La simulazione della verifica dell'identità restituisce un passaporto con un checksum MRZ danneggiato. Il validatore MRZ in produzione emette MRZ\_VALIDATION\_FAILED e la sessione viene rifiutata. |
| `decline_could_not_recognize_document` | Verifica dell'identità: documento illeggibile | Rifiutata | La simulazione della verifica dell'identità restituisce una risposta vuota. In produzione viene sollevato COULD\_NOT\_RECOGNIZE\_DOCUMENT, che viene mostrato all'SDK. |
| `decline_face_match_low_similarity` | Confronto facciale: somiglianza sotto la soglia di rifiuto | Rifiutata | La simulazione del confronto facciale restituisce un punteggio basso. In produzione viene emesso LOW\_FACE\_MATCH\_SIMILARITY e la mappatura dell'azione del nodo del workflow determina il rifiuto. |
| `decline_database_no_match` | Validazione su database: nessuna corrispondenza in tutti i servizi | Rifiutata | Ogni servizio di database selezionato restituisce NO\_MATCH. In produzione viene emesso DATABASE\_VALIDATION\_NO\_MATCH e il workflow rifiuta la sessione. |
| `decline_phone_high_risk` | Telefono: numero di test ad alto rischio riservato | Rifiutata | La simulazione della verifica telefonica blocca la verifica (intervallo di test riservato). La verifica telefonica termina come BLOCKED ed emette HIGH\_RISK\_PHONE\_NUMBER. |
| `decline_email_breach` | Email: riscontro in un database di violazioni | Rifiutata | La simulazione della violazione email restituisce un riscontro di violazione per l'indirizzo. La verifica email emette BREACHED\_EMAIL\_DETECTED. |
| `decline_ip_blocklist` | Analisi IP: indirizzo IP in blocklist | Rifiutata | La simulazione dell'analisi IP rifiuta la posizione con IP\_ADDRESS\_IN\_BLOCKLIST. La sessione viene rifiutata sull'analisi IP. |
| `decline_poa_address_mismatch` | POA: indirizzo non corrispondente a quello fornito | Rifiutata | La simulazione della POA rifiuta la prova di residenza con ADDRESS\_MISMATCH\_WITH\_PROVIDED. La sessione viene rifiutata sulla POA. |
| `decline_liveness_attack` | Rilevamento della vitalità: attacco al volto rilevato | Rifiutata | La simulazione del rilevamento passivo della vitalità rileva un segnale di attacco al volto ed emette LIVENESS\_FACE\_ATTACK. La sessione viene rifiutata sul rilevamento della vitalità. |
| `decline_nfc_chip_not_verified` | NFC: chip ePassport non verificato | Rifiutata | La simulazione dell'ePassport restituisce un chip la cui firma SOD/DG non supera il controllo di integrità. In produzione viene emesso NFC\_CHIP\_NOT\_VERIFIED e la sessione viene rifiutata sull'NFC quando il workflow rifiuta i chip non verificati. |
| `decline_nfc_trust_anchor_missing` | NFC: ancora di fiducia dell'emittente non disponibile | Rifiutata | La simulazione dell'ePassport restituisce un chip firmato da un DSC la cui CSCA emittente è assente dall'archivio delle ancore di fiducia. In produzione viene emesso NFC\_TRUST\_ANCHOR\_MISSING e la sessione viene rifiutata quando il workflow rifiuta i chip non verificati. |
| `decline_document_ai_unreadable` | Document AI: documento illeggibile | Rifiutata | La simulazione di Document AI non restituisce campi leggibili. In produzione viene emesso DOCUMENT\_AI\_UNREADABLE\_DOCUMENT e il documento risulta rifiutato una volta esaurito il numero di nuovi tentativi consentiti. |
| `review_aml_possible_match` | AML: possibile corrispondenza da verificare | In revisione | La simulazione AML restituisce un riscontro con un livello di affidabilità inferiore. La sessione passa In revisione con un Log di avviso POSSIBLE\_MATCH\_FOUND, da risolvere a cura di un analista. |
| `review_face_match_borderline` | Confronto facciale: somiglianza al limite | In revisione | La simulazione del confronto facciale restituisce un punteggio compreso tra la soglia di revisione e quella di rifiuto. La sessione passa In revisione sul confronto facciale. |
| `review_document_borderline_age` | Verifica dell'identità: minorenne inviato a revisione | In revisione | La simulazione della verifica dell'identità restituisce una data di nascita che indica un'età inferiore all'età minima configurata nel workflow. L'impostazione minimum\_age\_action del workflow è REVIEW anziché DECLINE, quindi la sessione passa In revisione sulla verifica dell'identità invece di essere rifiutata. |
| `review_poa_partial_match` | POA: corrispondenza parziale dell'indirizzo | In revisione | La simulazione della POA restituisce un indirizzo che corrisponde solo in parte a quello fornito. La sessione passa In revisione sulla prova di residenza. |
| `review_database_partial_match` | Validazione su database: corrispondenza parziale | In revisione | I servizi di database restituiscono corrispondenze parziali su nome e data di nascita. La sessione passa In revisione sulla validazione su database. |
| `decline_kyb_registry_mismatch` | KYB: dati del registro non corrispondenti | Rifiutata | La simulazione del registro restituisce un'azienda i cui dati di registrazione non corrispondono ai dettagli attesi. La sessione aziendale viene rifiutata sul controllo del registro. |
| `review_kyb_registry_partial` | KYB: dati del registro corrispondenti solo in parte | In revisione | La simulazione del registro restituisce un'azienda il cui nome corrisponde solo in parte. La sessione aziendale passa In revisione sul controllo del registro. |

Gli scenari `review_*` esistono perché tu possa testare l'esperienza della revisione manuale (la coda di revisione della console, i webhook `In Review`, le azioni di approvazione e rifiuto del revisore) senza bisogno di un input che porti a un rifiuto. I due scenari `kyb_*` sopra impostano `expected_details.registration_number` invece di `expected_details.first_name`: si applicano solo alle sessioni di Verifica aziendale (KYB).

## Valori magici

Un valore magico è un input specifico che fa emettere a una funzionalità simulata un rischio specifico. Imposta il campo di input sul valore magico (direttamente o tramite uno scenario) per attivarlo.

| Funzionalità | Campo di input | Valore magico | Rischio | Descrizione |
| - | - | - | - | - |
| AML | `user_email` | `sandbox+aml_hit@didit.test` | `POSSIBLE_MATCH_FOUND` | AML: persona politicamente esposta; il mock AML restituisce un riscontro e la sessione viene rifiutata per AML. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_EXPIRED` | `DOCUMENT_EXPIRED` | OCR: documento scaduto; la sessione viene rifiutata nella verifica dell'identità. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MINIMUM_AGE_NOT_MET` | `MINIMUM_AGE_NOT_MET` | OCR: la data di nascita fa sì che l'età dell'utente sia inferiore all'età minima configurata; la sessione viene rifiutata. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MAXIMUM_AGE_EXCEEDED` | `MAXIMUM_AGE_EXCEEDED` | OCR: l'età risultante dalla data di nascita estratta supera il limite massimo configurato. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NUMBER_FORMAT_MISMATCH` | `DOCUMENT_NUMBER_FORMAT_MISMATCH` | OCR: il numero del documento estratto non corrisponde all'espressione regolare del formato atteso per il documento, come definita nel registro dei documenti. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_PERSONAL_NUMBER_FORMAT_MISMATCH` | `PERSONAL_NUMBER_FORMAT_MISMATCH` | OCR: il numero personale estratto non supera il controllo di formato del registro dei documenti. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` | `DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` | OCR: il tipo di documento estratto non rientra nella policy `documents_allowed` dell'applicazione. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_FULL_NAME_MISMATCH_WITH_PROVIDED` | `FULL_NAME_MISMATCH_WITH_PROVIDED` | OCR: il nome sul documento non corrisponde a quello precompilato dal cliente in `expected_details`, con una differenza superiore alla soglia di corrispondenza del nome. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_GENDER_MISMATCH_WITH_PROVIDED` | `GENDER_MISMATCH_WITH_PROVIDED` | OCR: il genere estratto non coincide con `expected_details.gender`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOB_MISMATCH_WITH_PROVIDED` | `DOB_MISMATCH_WITH_PROVIDED` | OCR: la data di nascita estratta non coincide con `expected_details.date_of_birth`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COUNTRY_MISMATCH_WITH_PROVIDED` | `COUNTRY_MISMATCH_WITH_PROVIDED` | OCR: il paese di emissione non coincide con `expected_details.country` (o `id_country`). |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_NATIONALITY_MISMATCH_WITH_PROVIDED` | `NATIONALITY_MISMATCH_WITH_PROVIDED` | OCR: la nazionalità estratta non coincide con `expected_details.nationality`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_IDENTIFICATION_NUMBER_MISMATCH_WITH_PROVIDED` | `IDENTIFICATION_NUMBER_MISMATCH_WITH_PROVIDED` | OCR: il numero del documento, il numero personale o l'identificativo fiscale estratto non coincide con `expected_details.identification_number`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COULD_NOT_RECOGNIZE_DOCUMENT` | `COULD_NOT_RECOGNIZE_DOCUMENT` | La pipeline OCR restituisce un risultato vuoto o non riconoscibile; in produzione viene generato COULD\_NOT\_RECOGNIZE\_DOCUMENT. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_NOT_DETECTED` | `MRZ_NOT_DETECTED` | OCR: il documento prevede una MRZ, ma la pipeline non è riuscita a individuarla. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_VALIDATION_FAILED` | `MRZ_VALIDATION_FAILED` | OCR: la MRZ è stata trovata, ma non ha superato la validazione del checksum o del formato. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` | `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` | OCR: i campi identitari della MRZ non coincidono con quelli estratti dalla VIZ. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BARCODE_NOT_DETECTED` | `BARCODE_NOT_DETECTED` | OCR: il documento prevede un codice a barre, ma non ne è stato trovato nessuno. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BARCODE_VALIDATION_FAILED` | `BARCODE_VALIDATION_FAILED` | OCR: il codice a barre è stato decodificato, ma non ha superato la validazione incrociata tra campi. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_QR_NOT_DETECTED` | `QR_NOT_DETECTED` | OCR: il documento prevede un codice QR, ma non ne è stato trovato nessuno. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_QR_VALIDATION_FAILED` | `QR_VALIDATION_FAILED` | OCR: il codice QR è stato decodificato, ma non ha superato la validazione incrociata tra campi. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DATA_INCONSISTENT` | `DATA_INCONSISTENT` | OCR: i controlli di coerenza interna sui campi VIZ danno esito discordante. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_SIDES_MISMATCH` | `DOCUMENT_SIDES_MISMATCH` | OCR: fronte e retro di document\_name non risultano appartenere allo stesso documento. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_NAME_NOT_DETECTED` | `NAME_NOT_DETECTED` | OCR: non è stato possibile estrarre dal documento né il nome né il cognome. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DATE_OF_BIRTH_NOT_DETECTED` | `DATE_OF_BIRTH_NOT_DETECTED` | OCR: la classe di documento prevede una data di nascita, ma l'estrazione non ne ha restituita alcuna. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_EXPIRATION_DATE_NOT_DETECTED` | `EXPIRATION_DATE_NOT_DETECTED` | OCR: la classe di documento prevede una data di scadenza, ma l'estrazione non ne ha restituita alcuna. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NUMBER_NOT_DETECTED` | `DOCUMENT_NUMBER_NOT_DETECTED` | OCR: non è stato possibile estrarre né il numero del documento né il numero personale. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COULD_NOT_DETECT_DOCUMENT_TYPE` | `COULD_NOT_DETECT_DOCUMENT_TYPE` | OCR: il classificatore non è riuscito a ricondurre l'acquisizione a un tipo di documento supportato. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_PORTRAIT_IMAGE_NOT_DETECTED` | `PORTRAIT_IMAGE_NOT_DETECTED` | OCR: la pipeline non è riuscita a isolare un'area con il ritratto sul documento. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_UNPARSED_ADDRESS` | `UNPARSED_ADDRESS` | OCR: il documento contiene un campo indirizzo, ma la geocodifica o il parsing non ha restituito nulla di utilizzabile. |
| DATABASE\_VALIDATION | `expected_details.first_name` | `SANDBOX_DB_NO_MATCH` | `DATABASE_VALIDATION_NO_MATCH` | Validazione su database: ogni servizio governativo o di registro restituisce NO\_MATCH; la sessione viene rifiutata in base alla validazione su database. |
| FACEMATCH | `expected_details.first_name` | `SANDBOX_FACE_LOW_MATCH` | `LOW_FACE_MATCH_SIMILARITY` | Confronto facciale: punteggio di somiglianza sotto la soglia di rifiuto; la sessione viene rifiutata in base al confronto facciale. |
| PHONE | `phone_number` | `+15005550009` | `HIGH_RISK_PHONE_NUMBER` | Telefono: numero di test riservato, non recapitabile o ad alto rischio; il mock della verifica telefonica restituisce un errore. |
| EMAIL | `user_email` | `sandbox+breach@didit.test` | `BREACHED_EMAIL_DETECTED` | Email: il database delle violazioni restituisce un riscontro per questo indirizzo. |
| LOCATION | `expected_details.first_name` | `SANDBOX_IP_BLOCKLIST` | `IP_ADDRESS_IN_BLOCKLIST` | Analisi IP: l'IP del chiamante compare nella blocklist dell'applicazione; la sessione viene rifiutata in base all'analisi IP. |
| PROOF\_OF\_ADDRESS | `expected_details.first_name` | `SANDBOX_POA_ADDRESS_MISMATCH` | `ADDRESS_MISMATCH_WITH_PROVIDED` | POA: l'indirizzo sul documento caricato non corrisponde all'indirizzo precompilato dal cliente in `expected_details`; la sessione viene rifiutata in base alla POA. |
| LIVENESS | `expected_details.first_name` | `SANDBOX_LIVENESS_ATTACK` | `LIVENESS_FACE_ATTACK` | Rilevamento della vitalità: il mock del rilevamento passivo della vitalità rileva un segnale di attacco al volto; la sessione viene rifiutata in base al rilevamento della vitalità. |
| NFC | `expected_details.first_name` | `SANDBOX_NFC_CHIP_NOT_VERIFIED` | `NFC_CHIP_NOT_VERIFIED` | NFC: il mock del passaporto elettronico restituisce un chip la cui firma SOD/DG non supera il controllo di integrità; in produzione viene emesso NFC\_CHIP\_NOT\_VERIFIED e la sessione viene rifiutata quando il workflow rifiuta i chip non verificati. |
| NFC | `expected_details.first_name` | `SANDBOX_NFC_TRUST_ANCHOR_MISSING` | `NFC_TRUST_ANCHOR_MISSING` | NFC: il DSC risale a un CSCA assente dal trust store; in produzione viene emesso NFC\_TRUST\_ANCHOR\_MISSING e viene applicata l'azione configurata per i chip non verificati. |
| DOCUMENT\_AI | `expected_details.first_name` | `SANDBOX_DOCUMENT_AI_UNREADABLE` | `DOCUMENT_AI_UNREADABLE_DOCUMENT` | Document AI: l'estrazione non restituisce campi leggibili; in produzione viene emesso DOCUMENT\_AI\_UNREADABLE\_DOCUMENT e il documento risulta rifiutato una volta esaurito il numero di tentativi previsto. |
| AML | `user_email` | `sandbox+aml_review@didit.test` | `POSSIBLE_MATCH_FOUND` | AML: possibile corrispondenza che richiede una risoluzione manuale; la sessione passa allo stato In revisione. |
| FACEMATCH | `expected_details.first_name` | `SANDBOX_FACE_BORDERLINE_MATCH` | `LOW_FACE_MATCH_SIMILARITY` | Confronto facciale: somiglianza al limite tra la soglia di revisione e quella di rifiuto; la sessione passa allo stato In revisione. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BORDERLINE_AGE` | `MINIMUM_AGE_NOT_MET` | OCR: la data di nascita è inferiore all'età minima, ma il workflow sottopone a revisione invece di rifiutare i casi di età minima non raggiunta; la sessione passa allo stato In revisione. |
| DATABASE\_VALIDATION | `expected_details.first_name` | `SANDBOX_DB_PARTIAL_MATCH` | `DATABASE_VALIDATION_PARTIAL_MATCH` | Validazione su database: i dati identificativi corrispondono, ma nome e data di nascita corrispondono solo parzialmente; la sessione passa allo stato In revisione. |
| PROOF\_OF\_ADDRESS | `expected_details.first_name` | `SANDBOX_POA_PARTIAL_MATCH` | `ADDRESS_MISMATCH_WITH_PROVIDED` | POA: l'indirizzo sul documento caricato corrisponde solo parzialmente all'indirizzo fornito; la sessione passa allo stato In revisione. |
| KYB\_REGISTRY | `expected_details.registration_number` | `SANDBOX-KYB-MISMATCH` | `KYB_REGISTRY_DATA_MISMATCH_WITH_EXPECTED` | KYB - i dati dell'azienda nel registro non corrispondono ai dati attesi; la sessione viene rifiutata. |
| KYB\_REGISTRY | `expected_details.registration_number` | `SANDBOX-KYB-REVIEW` | `KYB_REGISTRY_DATA_PARTIAL_MATCH_WITH_EXPECTED` | KYB - i dati dell'azienda nel registro corrispondono solo parzialmente; la sessione passa allo stato In revisione. |

## Ricerca senza documento e wallet di identità

Le applicazioni sandbox possono abilitare ogni wallet di identità presente nel catalogo dei paesi, inclusi i wallet non disponibili nelle applicazioni in produzione.
Lo scenario predefinito `approve` simula un'identità verificata senza accedere a un wallet esterno.
Il risultato viene salvato nella sessione e segue il passaggio successivo normale del workflow.
La sandbox non convalida una credenziale wallet reale e non addebita i tentativi simulati.

Le richieste di ricerca convalidano comunque i campi inseriti e usano il limite di tentativi configurato, che per impostazione predefinita è uno.
Usa i seguenti scenari per testare i nuovi tentativi e le regole di fallback:

| Scenario | Risultato simulato |
| - | - |
| `lookup_partial_match` | Corrispondenza parziale nel registro; conta ai fini del limite di tentativi. |
| `lookup_no_match` | Il registro risponde senza corrispondenza; conta ai fini del limite di tentativi. |
| `lookup_provider_error` | Il registro non risponde; all'utente viene chiesto di riprovare e, dopo tre tentativi senza risposta, si applica il fallback per errore del provider. |
| `wallet_cancelled` | L'utente annulla l'accesso al wallet. |
| `wallet_timeout` | L'accesso al wallet scade. |
| `wallet_provider_error` | Il wallet non riesce a completare l'accesso. |

In caso di errori del wallet si segue l'impostazione del paese: fallback all'acquisizione del documento oppure rifiuto.
I tentativi di ricerca completati vengono registrati separatamente, quindi due tentativi consentiti producono due risultati prima del fallback.
Anche l'uso della sandbox resta gratuito.

## Verifica del conto bancario

Un passaggio di Verifica bancaria in sandbox offre [entrambi i metodi](https://docs.didit.me/it/core-technology/bank-verification/verification-methods.md) in ogni paese, nell'ordine impostato dal passaggio, su un servizio simulato senza banca e senza costi.
Con l'ordine predefinito la persona inizia dall'accesso bancario e seleziona **Inserisci i dati del tuo conto** per eseguire la [verifica del conto](https://docs.didit.me/it/core-technology/bank-verification/account-check.md); imposta `bank_method_order` su `["account_lookup", "open_banking"]` per iniziare da lì.
Gli ultimi quattro caratteri del conto digitato determinano la risposta; consulta [Prova in sandbox](https://docs.didit.me/it/core-technology/bank-verification/account-check.md#test-in-sandbox) per ogni terminazione e un conto valido per ciascun formato.
La [API di verifica del conto](https://docs.didit.me/it/standalone-apis/bank-account-check.md) restituisce una chiave sandbox in base alle stesse terminazioni.

## I documenti di esempio

> [!WARNING]
>
> Non caricare mai documenti d'identità reali in sandbox. Usa invece i documenti di esempio integrati.

Il flusso ospitato offre tre documenti di esempio, uno per tipo di documento:

| Paese | Tipo di documento |
| - | - |
| Spagna | Carta d'identità nazionale |
| Argentina | Passaporto |
| Polonia | Patente di guida |

Tocca un campione nella barra per usarlo al posto di un'acquisizione reale. I dati estratti e l'esito della sessione provengono sempre dallo scenario o dal valore magico selezionato, quindi ogni campione funziona con qualsiasi scenario.

## Identità di esempio: test di `expected_details`

Ogni documento della sandbox è generato a partire da un'unica identità **fissa**.
I valori estratti sono gli stessi in ogni sessione e non dipendono mai dalla data corrente, quindi puoi precompilare `expected_details` con questi valori e verificare dall'inizio alla fine la gestione del confronto dei campi e degli avvisi.
Se passi i valori indicati di seguito, i controlli di confronto vanno a buon fine; se passi qualsiasi altro valore, viene generato di proposito l'avviso `*_MISMATCH_WITH_PROVIDED` corrispondente.

Le date sono condivise da tutti i documenti di esempio:

| Campo | Valore |
| - | - |
| `date_of_birth` | `1990-06-15` |
| Data di rilascio | `2025-06-15` |
| Data di scadenza | `2035-06-15` |

Il resto dell'identità dipende dal documento utilizzato:

| `sandbox_sample` | Documento | `first_name` | `last_name` | `gender` | `nationality` | `id_country` | `identification_number` |
| - | - | - | - | - | - | - | - |
| *(predefinito, nessun campione selezionato)* | ePassport brasiliano | `GUSTAVO` | `MATSUMOTO` | `M` | `BRA` | `BRA` | `YC531181` |
| `spain-id-card-2021` | Carta d'identità nazionale spagnola | `CARMEN` | `ESPAÑOLA ESPAÑOLA` | `F` | `ESP` | `ESP` | `CAA000000` |
| `argentina-passport-2009` | Passaporto argentino | `MARIA VICTORIA` | `VILLAREAL` | `F` | `ARG` | `ARG` | `AAF794880` |
| `poland-driving-license-2019` | Patente di guida polacca | `JAN` | `KOWALSKI` | non presente su questo documento | `POL` | `POL` | `SP005/89/5` |

```json theme={null}
{
  "workflow_id": "<your-workflow-uuid>",
  "expected_details": {
    "date_of_birth": "1990-06-15",
    "gender": "M",
    "nationality": "BRA",
    "identification_number": "YC531181"
  }
}
```

`first_name` e `last_name` fanno eccezione: la sandbox riporta sul documento generato i nomi che invii in `expected_details`, quindi il confronto dei nomi va sempre a buon fine, qualunque nome tu usi.
Usa il valore magico `SANDBOX_OCR_FULL_NAME_MISMATCH_WITH_PROVIDED` per testare una discordanza nel nome, e `SANDBOX_OCR_DOB_MISMATCH_WITH_PROVIDED` per una discordanza nella data di nascita.

> [!NOTE]
>
> Se il tuo workflow limita `documents_allowed` a un paese o a un tipo di documento che esclude l'ePassport brasiliano, la sandbox genera invece un documento a partire dal primo paese consentito, quindi `nationality`, `id_country` e il nome del documento seguono quel paese. Le date indicate sopra restano invariate.

### Ciò che il documento generato non riporta

Il documento generato è il modello generico per il paese e il tipo di documento consentiti, quindi i campi che fornisce solo un documento reale rilasciato da uno Stato restano vuoti. Quello che conta per l'instradamento è la **regione / stato USA** (`kyc.region`): una patente o una carta d'identità statunitense di prova non riporta alcuno stato, quindi una condizione di ramo come `Region equals IL` non può mai essere soddisfatta in sandbox. Se nemmeno gli altri rami del nodo sono soddisfatti, il flusso segue il ramo di fallback del nodo (il ramo senza condizioni). Non si tratta di una revisione né di un errore del ramo: la condizione semplicemente non ha nessun valore da leggere. Un campo mancante fa inoltre fallire `not equals` e `not in`; per la differenza tra un campo mancante e una stringa vuota, consulta [come le condizioni di ramo leggono i dati della sessione](https://docs.didit.me/it/console/workflows.md#come-leggere-le-condizioni-dei-rami-sui-dati-di-sessione).

Per testare in sandbox un flusso che dipende dallo stato, pilota la decisione da un valore della sessione che controlli tu, anziché dal documento:

* Invia lo stato in `metadata` quando crei la sessione (per esempio `"metadata": {"credential_state": "IL"}`) e crea un ramo basato su `metadata.credential_state`. I metadati vengono valutati in sandbox esattamente come nell'ambiente di produzione.
* Mantieni la condizione `kyc.region`, basata sul documento, per il traffico in produzione se ti serve anche che il documento provi lo stato; in modalità di produzione la regione viene letta dal documento reale.

Per il resto, l'instradamento è identico all'ambiente di produzione: il grafo del workflow, le condizioni dei rami, i valori di `metadata` e `expected_details`, i nodi di azione e i nodi di stato vengono tutti eseguiti davvero. La sandbox non porta mai una sessione in revisione da sola: una sessione in sandbox finisce In revisione solo quando il workflow la instrada lì (uno scenario `review_*`, un valore magico associato a un'azione di revisione o un nodo di stato nel grafo).

## Codici OTP e opt-in per le email

* **OTP telefonico:** il controllo telefonico della sandbox accetta qualsiasi codice ben formato (da 4 a 8 cifre, incluso `123456`). L'input non valido restituisce comunque `400`.
* **OTP email:** il controllo email della sandbox accetta qualsiasi codice ben formato (incluso `123456`). L'input non valido restituisce comunque `400`.

Per impostazione predefinita le sessioni sandbox **non** inviano email (avvisi di revisione, cambi di stato, OTP, reinvio, nuovo link di sessione, ecc.). Per inviare comunque un'email, usa uno di questi schemi di opt-in sull'indirizzo del destinatario:

| Schema di opt-in | Esempio |
| - | - |
| `<local>+sandbox@<domain>` | `alice+sandbox@example.com` |
| `*@didit.test` | `alice@didit.test` |

## Pilotare gli esiti: scenari, valori magici, attivazione e l'endpoint di simulazione

Esistono cinque modi per controllare l'esito di una sandbox.

### 1. `sandbox_scenario` alla creazione della sessione

Imposta lo slug dello scenario quando crei la sessione (`POST /v3/session/`). Il flusso di creazione espande i valori magici inclusi nello scenario nei campi di input della sessione, così i provider simulati producono l'esito previsto attraverso la pipeline reale del workflow.

```json theme={null}
{
  "workflow_id": "<your-workflow-uuid>",
  "sandbox_scenario": "decline_document_expired"
}
```

### 2. Valori magici inseriti manualmente

Imposta tu stesso i singoli campi di input (ad esempio `expected_details.first_name = "SANDBOX_OCR_DOCUMENT_EXPIRED"`, oppure `user_email = "sandbox+aml_hit@didit.test"`). Consulta la tabella dei valori magici sopra per il registro completo.

### 3. Armare (o riarmare) la sessione prima dell'avvio del flusso

Imposta o sostituisci lo scenario armato su una sessione già esistente, purché non sia passata oltre `Not Started`. Questo è l'endpoint che il [selettore dello scenario prima del flusso](#sandbox-nel-flusso-di-verifica-ospitato) richiama, e puoi chiamarlo tu stesso per costruire un selettore personalizzato o un ambiente di test:

```
POST /v3/session/{session_id}/sandbox/arm/
Session-Token: <session_token>
```

```json theme={null}
{
  "scenario": "decline_document_expired"
}
```

Risposta 200:

```json theme={null}
{
  "session_id": "<session_id>",
  "scenario": "decline_document_expired",
  "status": "Not Started"
}
```

* Autenticati con il `Session-Token` della sessione (restituito come `session_token` alla creazione della sessione), non con la tua chiave API dell'applicazione: è un endpoint rivolto al client.
* Restituisce `400` per uno slug di scenario sconosciuto, e `400` quando la sessione è passata oltre `Not Started` (`"Scenario can only be armed before the verification starts."`).
* Restituisce `404` quando il `Session-Token` appartiene a un'applicazione live (non sandbox), oppure non corrisponde al `session_id` nel percorso.
* **Riarmare sostituisce lo scenario precedente.** Cancella solo i valori magici scritti dallo scenario precedente e lascia intatto tutto ciò che l'utente ha già inserito manualmente (email, nome, ecc.). Ad esempio: armi `decline_phone_high_risk`, poi armi `approve`. Il numero di telefono torna non impostato, ma l'email inserita dal cliente sopravvive a entrambe le chiamate.

### 4. L'endpoint di simulazione

Forza uno stato finale a posteriori:

* Console / chiave API (richiede il privilegio `write:sessions`; una chiave API con ambito limitato deve avere accesso in scrittura alle sessioni): `POST /v3/session/{session_id}/simulate/`
* Flusso ospitato (intestazione `Session-Token`): `POST /v3/session/{session_id}/sandbox/simulate/`

Entrambi funzionano sulle sessioni sandbox KYC e KYB.
Una sessione live (non sandbox) restituisce `404`, così come un `Session-Token` che non corrisponde al `session_id` nel percorso.

Ogni campo del payload è facoltativo, ma è obbligatorio almeno uno tra `new_status`, `scenario` o `risk`:

| Campo | Tipo | Funzione |
| - | - | - |
| `new_status` | stringa | `Approved`, `Declined`, `In Review`, `Expired` o `Abandoned`. Se lo ometti, assume lo stato predefinito del caso di rischio (`risk`, oppure il primo rischio che i valori magici dello scenario contengono), altrimenti lo stato predefinito dello scenario. |
| `scenario` | stringa, fino a 100 caratteri | Uno slug di scenario. Senza `risk`, viene applicato il primo rischio contenuto nei suoi valori magici. |
| `risk` | stringa, fino a 128 caratteri | Un caso di rischio. Il suo avviso viene aggiunto alla sessione. |
| `node_id` | stringa, fino a 128 caratteri | Il nodo del workflow a cui è associato l'avviso. Il valore predefinito è il nodo corrente della sessione. |
| `comment` | stringa, fino a 500 caratteri | Nota aggiunta alla voce di attività che registra il cambio di stato. |
| `send_webhooks` | booleano, predefinito `true` | Indica se il cambio di stato invia webhook. |

`send_webhooks: true` invia esattamente i webhook che invia un cambio di stato reale: `status.updated`, più gli eventi `user.status.updated` e `user.data.updated` (oppure `business.status.updated` e `business.data.updated` per una sessione aziendale) che il cambio provoca, verso le destinazioni iscritte a tali eventi.
Con `send_webhooks: false` lo stato cambia comunque, ma non viene registrato né inviato alcun webhook.
Il recupero dei webhook mancanti non reinvia mai quella decisione, e la console si aggiorna comunque in tempo reale.
Il successivo cambio di stato della sessione invia i webhook come di consueto.

```json theme={null}
{
  "scenario": "decline_aml_hit",
  "send_webhooks": false
}
```

Risposta 200:

```json theme={null}
{
  "session_id": "<session_id>",
  "previous_status": "In Progress",
  "status": "Declined",
  "scenario": "decline_aml_hit",
  "risk": "POSSIBLE_MATCH_FOUND",
  "send_webhooks": false
}
```

* `status` è lo stato impostato dalla simulazione, e `previous_status` quello che la sessione aveva prima.
* `scenario` riporta lo slug che hai inviato e `risk` è il caso di rischio applicato; ciascuno è `null` quando non c'è.
* `send_webhooks` riporta il valore applicato.
* Restituisce `400` per uno scenario o un rischio sconosciuti, quando non è possibile ricavare un `new_status`, per qualsiasi altro `new_status`, e quando la sessione ha già lo stato richiesto (`["The new status is the same as the current status."]`).

### 5. `sandbox_scenario` nell'API AML autonoma

Lo screening AML lato back-end non ha un utente finale né una sessione da armare, quindi lo slug va direttamente nella richiesta di screening (`POST /v3/aml/`):

```json theme={null}
{
  "full_name": "Ada Lovelace",
  "save_api_request": true,
  "sandbox_scenario": "decline_aml_hit"
}
```

* `decline_aml_hit` restituisce un riscontro con la struttura di produzione e chiude lo screening come `Declined`. `review_aml_possible_match` lo chiude come `In Review`. Uno scenario che non arma alcun esito AML lascia lo screening pulito.
* Con `save_api_request: true` (predefinito) lo screening viene salvato esattamente come con una chiave live, quindi il `request_id` restituito è risolvibile tramite `GET /v3/session/{request_id}/decision/` e `GET /v3/session/{request_id}/generate-pdf/`.
* Restituisce `400` per uno slug di scenario sconosciuto, e `400` quando la chiave API appartiene a un'applicazione live.

## Dove compare `sandbox_scenario`

Lo slug dello scenario armato (`null` se non ne è armato nessuno) viene riportato su alcune superfici e volutamente omesso da altre:

| Superficie | Esposto? |
| - | - |
| Payload del passaggio corrente (KYC e KYB) | Sì, come `sandbox_scenario` |
| `GET /v1/session/{id}/decision/` | Sì, come `sandbox_scenario` |
| `GET /v3/session/{id}/decision/` (vedi [Retrieve Session](https://docs.didit.me/it/sessions-api/retrieve-session.md)) | Sì, `sandbox_scenario` al primo livello (null se non armato) |
| Webhook di sessione (`status.updated`, `data.updated`) | Sì, come `sandbox_scenario`, `null` sulle sessioni live o sulle sessioni sandbox senza scenario armato |

Se la tua integrazione deve basarsi sullo scenario armato lato server, leggilo dall'involucro del webhook o da uno dei due endpoint di decisione (`v1` o `v3`).

## Uso e fatturazione

L'uso della sandbox viene registrato, ma non viene mai addebitato:

* Ogni chiamata simulata registra comunque un evento di utilizzo (`is_sandbox: true`, con prezzo `0.0000`), così il volume della sandbox è visibile per il debug, ma non viene mai aggiunto ai totali di utilizzo, non viene mai detratto dal saldo e non compare mai in una fattura.
* Il saldo, la ricarica e le sezioni della Business Console relative all'utilizzo in produzione filtrano per impostazione predefinita l'uso della sandbox. Gli endpoint di utilizzo della ricarica accettano un parametro `environment` (`live`, il valore predefinito, oppure `sandbox`) per poter esaminare separatamente il volume della sandbox, sempre a costo zero e senza consumare il piano gratuito.
* La verifica di email e telefono viene fatturata per richiesta e non per esito della sessione, e la sandbox non può rispecchiare completamente questo comportamento a livello di webhook. Le verifiche di email e telefono in sandbox registrano comunque un evento di utilizzo per richiesta, con prezzo `0.0000`, come ogni altra funzionalità simulata: si tratta di una divergenza accettata e nota rispetto al comportamento di fatturazione in produzione, non di un bug.
* La struttura della risposta della validazione su database in sandbox differisce volutamente da quella specifica di ciascun provider in produzione, poiché non esiste un provider reale da replicare. Considera i payload della validazione su database in sandbox come un sostituto dell'esito (stato e codice di avviso), non come un'anteprima byte per byte della risposta di un provider reale.


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