Vai al contenuto principale
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.
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; 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”.
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, 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 passa a UNCONFIRMED_OWNERSHIP senza alcun invio, e puoi completarlo in sandbox tramite il widget di verifica della proprietà del wallet, oppure tramite confermare la proprietà 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 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 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. 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 elenca il wallet di ciascuno scenario e il suo esito esatto. Il trigger inbound del Test VASP accetta solo accept e name_mismatch nel suo campo scenario.
Come esercitare una regola prima che vada in produzione. Usa Backtest: 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 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. 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.

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: 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 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; 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 per ogni terminazione e un conto valido per ciascun formato. La API di verifica del conto restituisce una chiave sandbox in base alle stesse terminazioni.

I documenti di esempio

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: 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: Il resto dell’identità dipende dal documento utilizzato:
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.
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. 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:

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.

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 richiama, e puoi chiamarlo tu stesso per costruire un selettore personalizzato o un ambiente di test:
Risposta 200:
  • 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: 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.
Risposta 200:
  • 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/):
  • 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: 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.
Ultima modifica il 7 novembre 2026